Diamond Operator in Java

Naveen AnamaneniUpdated · 3 min read

Before Java 7, creating a map of student marks meant writing the types twice: Map<String, List<Integer>> marks = new HashMap<String, List<Integer>>();. The second half added nothing; the compiler could see the types on the left. The diamond operator, <>, lets you leave them out: new HashMap<>(). The compiler fills them in from the context.

The Diamond in Action

Diamond.java▶ Try it
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class Diamond {
    public static void main(String[] args) {
        Map<String, List<Integer>> marks = new HashMap<>();
        marks.put("Navika", new ArrayList<>(List.of(91, 88)));
        System.out.println(marks);
 
        Comparator<String> byLength = new Comparator<>() {
            public int compare(String a, String b) {
                return a.length() - b.length();
            }
        };
        List<String> names =
            new ArrayList<>(List.of("Srihitha", "Navika", "Advitha"));
        names.sort(byLength);
        System.out.println(names);
 
        var mixed = new ArrayList<>();
        mixed.add("Advitha");
        mixed.add(7);
        System.out.println(mixed);
    }
}
Output
{Navika=[91, 88]}
[Navika, Advitha, Srihitha]
[Advitha, 7]

How it works

  1. new HashMap<>() takes its type arguments, <String, List<Integer>>, from the variable it's assigned to.
  2. new ArrayList<>(List.of(91, 88)) infers Integer from both the target and the argument.
  3. Since Java 9, the diamond also works with anonymous classes: new Comparator<>() { ... }.
  4. The trap: var mixed = new ArrayList<>(); has no type on the left to copy from, so the compiler picks ArrayList<Object>. That list accepts anything, which is exactly what generics are meant to prevent.

Where the Diamond Works

CodeInferred
List<String> a = new ArrayList<>();ArrayList<String>
Map<String, Integer> m = new HashMap<>();HashMap<String, Integer>
return new ArrayList<>(); in a method returning List<Order>ArrayList<Order>
process(new ArrayList<>()) where the parameter is List<String>ArrayList<String>
var list = new ArrayList<>();ArrayList<Object>, almost never what you want

Common Mistakes

var x = new ArrayList<>(); It silently becomes a list of Object.

Forgetting the <> entirely: new ArrayList(). That's a raw type, with no type checking at all, and the compiler warns about it.

Assuming the diamond works in Java versions before 7, or with anonymous classes before 9. It doesn't.

Practice

  1. Easy: Rewrite Map<String, Map<String, Integer>> grades = new HashMap<String, Map<String, Integer>>(); with the diamond.
  2. Harder: Write a method that returns new ArrayList<>() and is declared to return List<LocalDate>. Add two dates to the result in main, and explain how the type was inferred.

Quick check: Diamond operator

4 questions
1Where does the diamond get its types from?
2What is var list = new ArrayList<>();?

Was this tutorial helpful?

Lesson 243 of 482