Skip to content

Instantly share code, notes, and snippets.

@shoaibi
Last active August 29, 2015 14:23
Show Gist options
  • Save shoaibi/74d55cfb490360d845dd to your computer and use it in GitHub Desktop.
Save shoaibi/74d55cfb490360d845dd to your computer and use it in GitHub Desktop.
My Java7 Notes

Java Basics

General

  • For loop, set the comparison condition as variable outside the loop
  • conventions
    • ClassName
    • methodName
    • propertyName
    • CONSTANT_NAME
  • Constants should be static and final. Ideally private too.
    • Why? Java compiles the calling code with the constant values instead of references so if a constant's value is changed without recompiling the calling code it'd give unexpected behavior in the calling code.
  • Use @Override for interface methods or the overridden methods
  • Need to initialize ArrayList class but just need it for looping?
Iterator<Integer> a = new ArrayList<Integer>;

The type on left is actually an interface, which means that during init it'd force-check that the type on right complies with the contract. Of course this does have the side effort that we won't be able to use ArrayList's own methods not specified in Iterator Interface unless we type-cast it.

  • We can skip the type hint on right side and do:
Iterator<Integer> a = new ArrayList<>;

but this would only work in recent versions of java

  • import can import classes or static from classes.
import java.net.*;
import static java.lang.Integer.MIN_VALUE;
  • System.currentTimeMillis()

Data Types

  • Primitive Data Types

    • predefined, reserved word, do not share state with each other
    • byte, short, int, long (integer-like types)
    • float, double (decimal point values)
    • char
    • boolean
  • Reference Types

    • All Wrapper classes
      • Byte
      • Short
      • Integer
      • Float
      • Double
      • Character
      • Boolean
    • String
    • etc
  • long, float and double need suffix letter at the end of literal values

  • Underscores can be used anywhere in digits except before the suffix

  • Primitive are faster, also better because they don't allow nulls.

  • Object type can be created from primitive types like:

Byte b = new Byte("10");
Byte b = new Byte(10);
Byte b = Byte.valueOf(10);

Last method is preferred because it uses pool wrappers and saves memory.

  • Conversions
int parsedInt = Integer.parseInt("10");
Integer intObj = Integer.valueOf(parsedInt);
int convertedInt = intObj.intValue();
  • Strings are immutable, not array of chars, own object.
  • Operations on string return new string.
  • Init strings with literals instead of constructor to same memory unless an explicitly unique copy is needed.
  • With Java 7 strings can be used in switch statements.

StringBuffer

  • StringBuffer is like a mutable copy of String
  • StringBuffer is faster than string for concatenation
  • String concatenation is slow because it always returns a new object with concatenated string

Formatted Strings

  • String.format "% [argument number] [flags] [width] [.precision] type"
  • d = number, f = float, s = string
  • %n = newline

Atomic Classes

  • java.util.concurrent.atomic (Java > 1.7)
  • volatile keyword used to indicate that value will be modified by different threads, never cached locally
  • Mutable, provided automatic operation addition, increment and assignment
  • lock-free and wait-free algorithms

Arrays

  • Packing same types(primitive or reference) into a bag
  • Object types
  • Examples of fixed sized array of primitive and reference types:
int[] c = new int[12];
String[] b = new String[100];
  • Array initializer, skipping the length:
int[] a = { 1, 2, 3, 4, 5, 6, 6};

For loop

  • Old style
int l = array.length;
for(int counter = 0; counter < l; counter++)
System.out.printf("%5d%d\n", counter, array[counter]);
  • Enhanced for loop, good for only iteration, can't modify the current value:
for (int value: array)
System.out.printf("%13d\n", value);

Passing Data Types to Methods

  • Call/Pass by value
  • Call/Pass by reference (faster, eliminate the need to copy large data)
  • Java does not let you choose how to pass data
    • everything is pass by value
    • copies of primitive types or copies of pointer to reference types
    • when a method changes primitive value passed, no changes are reflected on actual data
    • when a method changes a reference type, changes progress because the pointer actually points to actual object
    • If the methods assigns a new object to passed pointer, no changes are reflected on the calling code because the invoked function just changes the copy of the pointer to point to the new object.

Constructors and Initializations

  • new
    • allocate memory
    • call constructor
  • Rules
    • Same name as class
    • do not return a value, not even void
  • Default constructor provided with no parameters, sets instance properties to default value
    • numeric = 0
    • characters types = null
    • reference types = null and calls parent's constructor with no arguments
  • Constructor Overloading (number of parameters, order of parameters and types of parameters)

Initializers

  • static blocks in classes are static initializers
  • instance initializer are same as static except that they don't have the static keyword. These are called before constructor.
class InitializerTest
{
  // static initializer
  static {
    System.out.println("Gets called when class is initialized/loaded.");
  }

  // instance initializer
  {
    System.out.println("Gets Called before Constuctor");
  }
}

Inheritance

  • Object class is superclass
    • has methods like
      • clone
      • notify
      • notifyAll
      • toString
      • equals
      • copy
      • getClass
      • wait
      • hashCode
      • ...
  • Classes implicitly inherit from super class

Autoboxing and Unboxing

  • Autoboxing: Primitive to Wrapper, uses valueOf() against relevant wrapper class.
  • Unboxing: Wrapper to Primitive, uses *Value(), say intValue() for Integer

varArgs

  • Used when variable number of arguments are required type...variableName
  • These should be the last argument in function signature
  • varArgs are translated to an array

Enum

  • More than just fancy integer mapping
  • Class-like, allows member data and methods
  • Implicitly extend java.lang.Enum
  • Have special methods embedded like .values()
  • Constants should be defined at top of enum declaration and must end with ; if member data or methods follow
  • type-safe, can't assign any random value
  • constants are implicitly static and final
  • can not instantiate enum because constructor is private, enum constants can only be created inside enum itself
  • constructors can have arguments and can be overloaded
  • EnumSet.range() inclusive range of enums

Assertion

  • assert requirements
assert booleanExpr, assert booleanExpr : errorMessageExpr;
assert s != null : "S shouldn't be null";
  • Need to enable assertions on the interpreter level
    • vm arguments: -ea
    • test using: assert false
  • If assertions are disabled, AssertionError exception is thrown when encountering first assert
  • Used for:
    • Internal variance to check value is within a range, 1-5
    • Object variance to ensure object static is valid, usually inside an isValid() method
    • Control flow variance to ensure that code never reaches a block it shouldn't, say default case of a switch statement
    • Pre conditions
    • Post conditions

Regular Expresses

  • java.util.regex

String Literals

Pattern p = Pattern.compile('vtc'); // regex compiled
Matcher m - p.matcher('vtc'); // haystack
m.find(); // find the next subsequence of the input sequence
  • m.group(); search string
  • m.start(); start index
  • m.end(); last index
  • range are inclusive of start index and exclusive of last

Meta characters

  • character with special meaning for regex compiler
Pattern p = Pattern.compile('(?i)vtc'); // regex compiled
Matcher m - p.matcher('VTc'); // haystack

Character Classes

  • Set of characters in square brackets
  • [mnto]ap will match map, nap, tap, oap
  • [^n]ap will match anything that ends with ap except nap
  • [a-m]b will match whole range
  • map[^1-5] negation with range
  • [a-fo-q]ap or [a-f[o-q]] union
  • [a-z&&[def]] d, e, or f (intersection)
  • [a-z&&[^bc]] a through z, except for b and c: [ad-z] (subtraction)
  • [a-z&&[^m-p]] a through z, and not m through p: [a-lq-z] (subtraction)

Quantifier

  • [Bn+b] find B followed by any character one or more times and ending with b
  • (log)(3) any consecutive triplets of log, match set is logloglog

Capturing groups and backreferences

  • (\w+).(\w+)@(\w+)\.(\w+)
  • \b(\w+) \1\b match any word followed by a space followed by the word itself e.g. "vtc vtc"
    • \b is word boundary

Boundary Matchers

  • ^ start of line
  • $ end of line
  • \b word boundary, match whole word
  • \B non-word boundary, match anywhere in string, even partial words
  • \A start of input
  • \G end of previous match
  • \Z end of input but for final terminator, if any
  • \z end of input

Pattern and Matcher

  • compiler(regex, flags)
    • Pattern.CASE_INSENSITIVE
    • Pattern.UNICODE_CASE
    • Pattern.COMMENTS
    (Pattern.CASE_INSENSITIVE == (Pattern.CASE_INSENSITIVE & pattern.flags()))
  • Pattern.matches(regex, data) // returns boolean, short hand for compile(), matcher() and find()

Arrays Class

  • toString()
  • asList()
  • copyOfRange(source, from, to)
  • fill(array, value)
  • sort(array, from, to) // allows selective sort if 2nd and third params are provided
  • binarySearch(array, key) // must be sorted before search
    • use linear search for small array, sort is an expensive operation

Comparable and Comparator Interfaces

Comparable

  • java.lang.Comparable
  • Allows object1 of class A to be compared to object2 of class A
  • must implement java.lang.Comparable interface
  • used when sorting objects
  • override compareTo method, single argument, return -1, 0, 1

Comparator:

  • java.util.Comparator
  • Allows comparing 2 objects of any class
  • Usually implemented as a separate class, say UserSortByName, UserSortByAge
  • override compare method, takes 2 objects and returns compareTo result for relevant type
    • say UserSortByName does: return name2.compareTo(name1);
  • Could be used in Arrays.sort(array, new UserSortByName())

Lists and Sets Interfaces

List

  • ordered collection, may have dups
  • array like indexes, 0 based
  • child of Collection
  • Implemented by ArrayList, LinkedList and Vector, ...
  • ArrayList, Vector: resizable array of elements
  • ArrayList, Vector: Inserting in middle is slow and expensive for large data
  • LinkedList: efficient insertion/deletion
  • ArrayList: unsynchronized, not thread-safe.
  • Vectors: synchronized and thread-safe, but slow due to synchronization
  • ArrayList vs Array: ArrayList is resizeable and allows mixed data

Set

  • no dups
  • integer keys

Iterator Interface

  • hasNext()
  • next()

Map interface:

  • No dupes
  • Override equals() and hashCode()
    • do not use properties that are dynamic
    • use same properties in both methods
    • use prime numbers as seeds
    • hashCode() returns memory address by default for objects
      • used to determine key in datasets
      • do not override unless have objects as keys
      • helps find duplicate objects

Collections class

  • sort()
  • reverse()
  • shuffle()
  • copy()
  • fill()

What Collection to use?

  • dupes?
    • No? Use Set interface implementations
    • Yes? List interface implementations
  • KV Mapping with no dupes? Map implementations
  • Multiple threads? Vector, else ArrayList
  • Need insertion/deletion in mid? LinkedList

Generics

  • Help compiler keep track of types, parameters, type checks and type casts
  • Diamond operator <>
  • Without generics we can only find about the error on runtime
List l = new ArrayList();
l.add(new Integer(5));
String s = (String) l.get(0);
  • Most IDEs would error on following even before compilation:
List<Integer> lg = new ArrayList<Integer>();
lg.add(new Integer(5));
String s = (String) lg.get(0);
  • Can't assign List<Integer> to List<Number>, even though integer is subtype of number listInteger is not subtype of listNumber
  • Can parameterize multiple types

Defining simple Generics:

  • Generic type is a generic class/interface that is parameterized over generics

List l = new ArrayList(); // or: List l = new ArrayList<>(); Map<Integer, String> m = new HashMap<Integer, String>(); // integer keys, string values


### Wildcards
- Can use wildcard parameterized types in method arguments to use same method for multiple generic types e.g. ```List<?>```, ```ArrayList<?>```
  - Upper bound
    - ```List<? extends Number> list```: list variable can be anything that extends ```Number```
  - Lower bound
    - ```List<? super Integer> list```: list variable can be anything that ```Integer``` extends
- Use ```extends``` wildcard when only getting values from structure
- Use ```super``` wildcard when only pushing values to structure
- Don't use a wildcard when doing both get and push

### Generic methods:
- Method to compare a Pair objects that has Integer keys and Integer values
```java
public static boolean compare(Pair<Integer, Integer> p1, Pair<Integer, Integer> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }

awesome method. What if we have Pairs that have String values? String keys with Object values? Time to go generic methods with type parameter

public static <K, V> boolean compare(Pair<K, V> p1, Pair<K, V> p2) {
        return p1.getKey().equals(p2.getKey()) &&
               p1.getValue().equals(p2.getValue());
    }
  • type parameter must occur before return type

Generic Classes:

  • Assume we had:
class QueueOfStrings {
   private LinkedList<String> items = new LinkedList<String>();
   public void enqueue(String item) {
      items.addLast(item);
   }
   public String dequeue() {
      return items.removeFirst();
   }
   public boolean isEmpty() {
      return (items.size() == 0);
   }
}

great class but what if we also want to queue Integers, Doubles, etc? Time for a generic class with type parameter.

class Queue<T> {
   private LinkedList<T> items = new LinkedList<T>();
   public void enqueue(T item) {
      items.addLast(item);
   }
   public T dequeue() {
      return items.removeFirst();
   }
   public boolean isEmpty() {
      return (items.size() == 0);
   }
}
  • T is just a literal in place of type parameter. Most people choose to use T or E. From compiler's perspective this can be anything, say ItemType.
  • This class would allow queuing of any objects as long as type remains same.

Basic File I/O

  • java.io.File
  • File.listRoots // array of file objects
  • File.createTempFile("temp-file-name", ".tmp"); ###Writing data to file:
File file = new File("/tmp/a");
try {
  if (!file.exists()) {
    file.createNewFile();
  }
  FileWriter fw = new FileWriter(file);  // subclass of OutputStreamWriter
  BufferedWriter bw = new BufferedWriter(fw); // text written is stored in buffer, once full or flushed text is forward to FileWriter which writes it to file.
  bw.write("File Content goes here");
  bw.close(); // also flushes the buffer
} catch (IOException ioe)
{
  ioe.printStackTrace();
}

Gathering data about file:

  • file.canExecute();
  • file.canRead();
  • file.canWrite();
  • file.exists();
  • file.isDirectory();
  • file.isFile();
  • file.isHidden();
  • file.length();
  • file.lastModified();

Reading File

if (file.exists()) {
  FileReader fr = null;
  try {
    fr = new FileReader(file); // InputStreamReader subclass
    BufferedReader br = new BufferedReader(fr);
    String line = '';
    while ((line = br.readLine()) != null)
    {
      System.out.println(line);
    }
  } catch (Exception e)
  {
    throw new RuntimeException(e);
  } finally {
    try {
      fr.close();
    } catch (IOException ioe) {
      // ignoring this exception
    }
  }
}

Buffered I/O

  • java.io supports 2 types of streams
    • binary streams (InputStream, OutputStream)
    • ````character streams (Reader``` and ```Writer```)
  • Using Buffered* variants is better for performance instead of byte-by-byte operations
  • Default size is 512 bytes, can be changed default size by passing new size to constructor.
  • Best way is to read availableLength into byte array e.g. custom buffering

Console class:

  • java.io.Console
  • access character based console device attached to current jvm
  • Extension of command line, available through System.console() method.(doesn't work unless you have an active character-based device)
  • format()
  • reader()
  • writer()
  • readLine()
  • readPassword()

Object Serialization

  • Object state:
    • primitive properties
    • reference objects
  • For object to be serialized:
    • Implement Serializable interface
    • All properties must be Serializable
  • By default all object data is serialized
    • Use transient keyword before the data type to exclude data
    • Serializing objects through ObjectOutputStream.writeObject() along with a target stream, say FileOutputStream (why OutputStream and not Writer? Because it is binary)
    • Deserialization through ObjectInputStream.readObject() along with a target stream, say FileInputStream
      • Deserialization may throw ``ClassNotFoundException``` as the object we are deserializing might be of a type that is not available.

Compressed Files

Compressing files

public function zipFiles(File[] files) {
  String zipFileName = '/tmp/test.zip';
  FileOutputStream fos = new FileOutputStream(zipFileName);
  ZipOutputStream zos = new ZipOutputStream(fos);
  for (File file: files)
  {
    addToZipFile(file, zos);
  }
  zos.close();
  fos.close();
}

public static void addToZipFile(File file, ZipOutputStream zos) throws FileNotFoundException, IOException {
  FileInputStream fis = new FileInputStream(file);
  zos.putNextEntry(new ZipEntry(file.getName()));
  byte[] buffer   = new byte[1024];
  int length;
  while ((length = fis.read(buffer)) >= 0)
  {
    zos.write(buffer, 0, length);
  }
  zos.closeEntry();
  fis.close();
}

Extracting files

public function unzipFiles() {
  String zipFileName = '/tmp/test.zip';
  String outputDirPath = '/tmp/extracted';
  File outputDir      = new File(outputDirPath);
  if (!outputDir.exists()) {
    outputDir.mkdirs();
  }
  FileInputStream fis = new FileInputStream(zipFileName);
  ZipInputStream zis  = new ZipInputStream(fis);
  ZipEntry ze     = zis.getNextEntry();
  while (ze ! = null)
  {
    extractFiles(ze, outputDir);
    ze = zis.getNextEntry();
  }
  zos.close();
  fos.close();
}

public static void extractFiles(ZipEntry ze, File outputDir) throws FileNotFoundException, IOException {
  byte[] buffer   = new byte[1024];
  String fileName = ze.getName();
  File extractedFile = new File(outputDir + File.sperarator + fileName);
    new File(extractedFile.getParent()).mkdirs(); // get parent dirs ready
  FileOutputStream fos = new FileOutputStream(extractedFile);
  int length;
  while ((length = zis.read(buffer)) >= 0)
  {
    fos.write(buffer, 0, length);
  }
  fos.close();
}

Writing own I/O Classes

  • Extend from FilterInputStream and FilterOutputStream
  • Override read() or write() methods
  • Provide additional methods
  • Check new I/O streams together and ensure they are compatible

Advanced I/O

  • File Change Notifiers through WatchService API
    • Create Watch Service
    • Register it against path against set actions
    • Listen for watch keys and do some action
  • Read More

Enhanced I/O

Properties Files

  • Hash table with Keys and Values, both string types
  • Can be written to a backend, say a FileOutputStream. Can also be retrieved from a backed, say FileInputStream
  • setProperty()
  • getProperty()
  • store()
  • load()

Preferences Class

  • Prefer using preferences
  • Storing small amount of data.
  • Automatically saved with the put calls
    • Preferences.userRoot()
    • Preferences.systemRoot()
  • Can store numbers, strings, booleans, simple byte arrays, ...
  • Preferences can be accessed by a different program given it runs on same jvm
    • could use userNodeForPackage() but different programs in same jvm might have same package
    • chain calls to userRoot() and systemRoot() with .node(customScopeName) to set a custom scope
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment