Collections and generics only hold objects, so you meet wrapper types the moment you store numbers in a List or Map.
Each primitive has a wrapper class in java.lang: Integer, Long, Double, Boolean, Character and so on. Wrappers are objects, so they can be stored in collections (List<Integer>), be null, and offer useful static methods.
The compiler converts automatically between the two forms. Autoboxing turns int into Integer when needed, and unboxing does the reverse:
List<Integer> ids = new ArrayList<>();
ids.add(42); // boxing
int first = ids.get(0); // unboxingThe convenient conversions hide two traps:
- Unboxing
nullthrowsNullPointerException. If aMap<String, Integer>has no entry,int n = map.get("x");crashes. ==on wrappers compares references. Small values (−128 to 127) are cached, soInteger a = 100, b = 100; a == bis true, but with 1000 it is usually false. Useequals, or unbox first.
Parsing text into numbers is a daily task: Integer.parseInt("42"), Double.parseDouble("3.5"), Long.parseLong(...). Invalid input throws NumberFormatException, so validate or catch it when parsing user input. The reverse is String.valueOf(n) or Integer.toString(n).
Other handy members: Integer.MAX_VALUE, Integer.compare(a, b), Character.isDigit(c), Character.isLetter(c).
In performance-critical loops, prefer primitives: boxing allocates objects, and a List<Integer> of a million numbers uses several times more memory than an int[].
Example
import java.util.HashMap;
import java.util.Map;
public class Boxing {
public static void main(String[] args) {
int port = Integer.parseInt("8080");
double ratio = Double.parseDouble("0.75");
System.out.println(port + ratio); // 8080.75
Integer a = 1000, b = 1000;
System.out.println(a == b); // false (different objects)
System.out.println(a.equals(b)); // true
Map<String, Integer> stock = new HashMap<>(Map.of("apples", 5));
Integer pears = stock.get("pears"); // null, fine as Integer
int safe = stock.getOrDefault("pears", 0); // 0
System.out.println(pears + " " + safe); // null 0
try {
Integer.parseInt("12abc");
} catch (NumberFormatException e) {
System.out.println("not a number");
}
}
}Remember
- Wrappers let primitives live in collections and be null
- Compare wrapper values with
equals, not== Integer.parseIntand friends convert text to numbers and throw on bad input
Watch out for
- Unboxing a null
Integer(e.g. frommap.get) into anintthrows NullPointerException.