javaarraysjava-streamhashset

Java failed to convert int array to Set using Collectors.toSet()


I can't understand the basic thing I have here:

 int[] arr = {2,5,2,4,6,6,1,5,4};
        Set<Integer> orederSet  = new HashSet<Integer>(Arrays.stream(arr).collect(Collectors.toSet()));

Side note: also this not working:

Set<Integer> orederSet  = new HashSet<Integer>(Arrays.asList(arr));

which gives me compile error:

java: method collect in interface java.util.stream.IntStream cannot be applied to given types;
  required: java.util.function.Supplier<R>,java.util.function.ObjIntConsumer<R>,java.util.function.BiConsumer<R,R>
  found: java.util.stream.Collector<java.lang.Object,capture#1 of ?,java.util.Set<java.lang.Object>>
  reason: cannot infer type-variable(s) R
    (actual and formal argument lists differ in length) 

What is wrong in my code?


Solution

  • Your arr is an int[]. That means you're calling Arrays#stream(int[]), which returns an IntStream. But none of the primitive stream interfaces1 have a #collect(Collector) method. You have to convert the IntStream into a Stream<Integer>. The easiest way to do that is with the IntStream#boxed() method.

    int[] arr = {2, 5, 2, 4, 6, 6, 1, 5, 4};
    
    Set<Integer> set =
            Arrays.stream(arr)                  // IntStream
                  .boxed()                      // Stream<Integer>
                  .collect(Collectors.toSet()); // Set<Integer>
    

    As for why the following doesn't work:

    Set<Integer> set = new HashSet<>(Arrays.asList(arr));
    

    That's due to Arrays.asList(arr) returning a List<int[]> rather than a List<Integer>.

    Neither primitives nor arrays work especially well with generics. Arrays of primitives are worse. A primitive can at least be auto-boxed to the reference type (and vice versa, i.e., unboxed) when appropriate. But primitive arrays have no such special treatment.


    1. The primitive stream interfaces include IntStream, LongStream, and DoubleStream.