2

What's the tersest way to declare a list/array literal in Java, both at point of declaration and point of use?

As a secondary concern, I'd prefer a method that doesn't cause a compile-time warnings or require warnings to be suppressed.

Note: Personally this is for Java 8ish on Android, incase that changes the answers.

I've tried:

    // error: generic array creation
    Pair<Integer, String>[] data4 = new Pair<Integer, String>[] {
            new Pair<Integer, String>(0, "00000000"),
            new Pair<Integer, String>(1, "00000001"),
            new Pair<Integer, String>(127, "11111111"),
            new Pair<Integer, String>(128, "10000000")
    };
    // warning: unchecked assignment
    Pair<Integer, String>[] data4 = new Pair[] {
            new Pair<Integer, String>(0, "00000000"),
            new Pair<Integer, String>(1, "00000001"),
            new Pair<Integer, String>(127, "11111111"),
            new Pair<Integer, String>(128, "10000000")
    };
    for (Pair<Integer, String> x : data4) {
    }
    Pair[] data5 = new Pair[] {
            new Pair<Integer, String>(0, "00000000"),
            new Pair<Integer, String>(1, "00000001"),
            new Pair<Integer, String>(127, "11111111"),
            new Pair<Integer, String>(128, "10000000")
    };
    // warning: unchecked assignment
    for (Pair<Integer, String> x : data5) {
    }
    for (Pair x : data5) {
        //warning: unchecked assignment
        Pair<Integer, String> y = x;
    }
    // warning: unchecked generics array creation for vargs parameter
    List<Pair<Integer, String>> data = Arrays.asList(
            new Pair<Integer, String>(0, "00000000"),
            new Pair<Integer, String>(1, "00000001"),
            new Pair<Integer, String>(127, "11111111"),
            new Pair<Integer, String>(128, "10000000")
    );
    for (Pair<Integer, String> x : data) {
    }
    List<Pair> data2 = Arrays.asList(
            (Pair) new Pair<Integer, String>(0, "00000000"),
            (Pair) new Pair<Integer, String>(1, "00000001"),
            (Pair) new Pair<Integer, String>(127, "11111111"),
            (Pair) new Pair<Integer, String>(128, "10000000")
    );
    // warning: unchecked assignment
    for (Pair<Integer, String> x : data2) {
    }
    for (Pair x : data2) {
        // warning: unchecked assignment
        Pair<Integer, String> y = x;
    }
Pod
  • 3,938
  • 2
  • 37
  • 45

1 Answers1

2

Straight away, discount any of the choices which use raw types.

Then discount the ones which mix generics and arrays.

That basically leaves

List<Pair<Integer, String>> data = Arrays.asList(...);

There are a few ways to avoid the warning here:

  • Suppress it. (e.g. @SuppressWarnings("unchecked"))
  • Don't try to add the elements immediately:

    List<Pair<Integer, String>> data = new ArrayList<>();
    data.add(new Pair<>(1, ""));
    // ...
    
  • Use something like Guava's ImmutableList.of (works without generic arrays only up to 11 parameters):

    List<Pair<Integer, String>> data = ImmutableList.of(
        new Pair<>(1, ""),
        // ...
        );
    
  • Create an "adder" class, something like:

    class ListAdder<T, L extends List<T>> {
      L list;
    
      ListAdder(L list) { this.list = list; }
    
      L list() { return list; }
    
      ListAdder<T> add(T item) { list.add(item); return this; }
    }
    

    and use it like:

    List<Pair<Integer, String>> list =
        new ListAdder<>(new ArrayList<Pair<Integer, String>>())
            .add(new Pair<>(1, ""))
            // ...
            .list();
    
  • If you must, you can use double-brace initialization - but you must be aware of the problems with it (like it being prone to memory leaks, it creates an extra class, etc etc):

    List<Pair<Integer, String>> data = new ArrayList<Pair<Integer, String>>() {{
      add(new Pair<>(1, ""));
      // ...
    }};
    
Community
  • 1
  • 1
Andy Turner
  • 137,514
  • 11
  • 162
  • 243
  • Thanks! Even before posting the question I'd just settled on `Arrays.asList` and suppressing the warnings. I didn't like doing that and wanted a "better" solution, but it doesn't look like there is. Everything else is too spammy! It was in testing code so I didn't care much. In real code I might just go for the `.add ` variety. – Pod Mar 09 '17 at 09:46