See More

/* # Array JLS7 10 Arrays are built-in into the language. Therefore, there is no Javadoc which documents them: you have to read the JLS. Arrays do however have class-like syntax semantics. Arrays are not Generics nor do they implement Collection. Arrays have fixed size. Use `ArrayList` for variable size arrays. Do not confuse arrays with the Array class: http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Array.html which just contains some convenience methods to work with arrays. Java bytecode has various array-specific instructions such as `newarray`, `arraylength`, `iastore`, etc. */ import java.util.ArrayList; import java.util.Arrays; public class ArrayCheat { static int arrayParam(int[] is) { return is[0] + is[1]; } public static void main(String[] args) { // # Declare arrays { /* Putting `[]` after `is` exactly the same as before. I find after bad style since it splits type infomation appart: type is `int[]`, not `int`. Can even use both? */ { int[] is; int js[]; int[] ks[]; } } // # Create arrays { // Create and declare at once vs separately { // At once { int[] is = new int[3]; assert is[0] == 0; assert is[1] == 0; assert is[2] == 0; } // Separately { int[] is; is = new int[3]; assert is[0] == 0; assert is[1] == 0; assert is[2] == 0; } } /* # Maximum Array size MAX_INT: */ { // ERROR: Incompatible types: conversion from long to int. //byte[] bytes = new byte[0xFFFF_FFFF_1L]; } // Primitives vs objects { // Primitives { int[] is = new int[2]; is[0] = 0; is[1] = 1; assert is[0] == 0; assert is[1] == 1; } // Objects { Integer[] is = new Integer[2]; is[0] = 0; is[1] = 1; assert is[0] == 0; assert is[1] == 1; } } // Initialization values { // Default values if none given. { // Primitives { int[] is = new int[2]; assert is[0] == 0; assert is[1] == 0; } // Objects { String[] ss = new String[2]; assert ss[0] == null; assert ss[1] == null; } } // Custom values { // Long syntax { // Good { int[] is = new int[]{0, 1}; assert is[0] == 0; assert is[1] == 1; } // This is how you create arrays on the fly for functions. { assert arrayParam(new int[]{1, 2}) == 3; } // Bad: cannot have the size and be inialized at once. //int[] is = new int[2]{0, 1}; } // Shorthand syntax { // Good { int[] is = {0, 1}; assert is[0] == 0; assert is[1] == 1; } // Bad: must be used for explicit declaration / initialization. //assert {0, 1}[1] == 1; } // Array with n equal values { // Objects: Collections.nCopies().toArray(); // Primitives: don't know. } } } } /* # Arrays look like classes But they are not classes. It's just JLS magic. http://docs.oracle.com/javase/7/docs/api/java/lang/reflect/Array.html */ { // .class works on them { int[] is = new int[3]; assert is.getClass() == int[].class; assert int[].class.getSuperclass() == Object.class; } /* JLS7 5.1.6 says that arrays can be converted to Serializable and Cloneable. This means that arrays behave as if they implement those interfaces, which are therefore magic. */ /* # Iterate array Arrays don't implement iterable since they are not regular objects, but the enthanced for loop (`:`) works magically for them as well. http://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.14.2 says that the "Expression must be Iterable or an array type". */ { ArrayList a = new ArrayList<>(); ArrayList a2 = new ArrayList<>(); a.add(1); a.add(2); for (int i : a) a2.add(i); assert a.equals(a2); } } /* # length of Array Unlike C, arrays are classes and have a length field. This field is not a regular field access: it generates a special `arraylength` JVM instruction. */ { int[] is = new int[3]; assert is.length == 3; } /* # ArrayIndexOutOfBoundsException # Bound checking Unlike in C, Java checks bounds and raises nice exceptions instead of allowing arbitray code execution vulnerabilities :) */ { int[] is = new int[3]; try { assert is[3] == 0; } catch (ArrayIndexOutOfBoundsException e) { System.out.println( "ArrayIndexOutOfBoundsException.getMessage() = " + e.getMessage() ); } } /* # range No built-in equivalent of python `range()` in Java 7: http://stackoverflow.com/questions/3790142/java-equivalent-of-pythons-rangeint-int Just use a for loop instead. Possible in Guava, and with Java 8 `IntStream.range`. */ { Integer[] ints = new Integer[10]; for (int i = 0; i < 10; i++) { ints[i] = new Integer(i); } } /* # clone arrays On arrays, `.clone()`, `Arrays.copyOf` and `System.arrayCopy` are all the same, shallow, copies. Arrays are the only place where `.clone()` works well. So better avoid it and go ti `Arrays.copyOf`. The main problem with `Arrays.copyOf` is that its clumsy interface takes the length as a parameter requiring extra typing for full array copies. Arrays does not provide a multi-dimensional deep copy, only shallow: This could be expected since it does have some deep array-only methods like `deepEquals`. */ { int[] is = new int[]{0, 1}; int[] js = is.clone(); assert(is != js); assert(Arrays.equals(is, js)); } } }