2016-04-21 6 views
3

Может кто-нибудь объяснить мне, почему следующее не работает:Java 8 потоков и простые типы

long la[] = new long[] {1,2,3}; 
Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet()); 

Когда это делает:

String la[] = new String[] {"1","2","3"}; 
Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet()); 

Первое дает ошибку компиляции, в то время как последний не , Ошибка компиляции настолько загадочна (Eclipse), что я не могу ее понять.

ответ

2

Arrays.stream(la) выполняет метод public static LongStream stream(long[] array), который производит LongStream. LongStreammap метод возвращает LongStream (т.е. каждый элемент long источника LongStream отображается в long в целевом LongStream). LongStream не имеет метода collect, который принимает один аргумент, поэтому collect(Collectors.toSet()) не передает компиляцию.

Он должен работать, если вы используете mapToObj:

Set<Long> set = Arrays.stream(la).mapToObj(Long::valueOf).collect(Collectors.toSet()); 

Ваш второй фрагмент кода работает так как здесь Arrays.stream производит Stream ссылочного типа (Stream<String>), чей map метод дает другой Stream эталонного типа (Stream<Long> в вашей дело). Здесь Stream имеет метод collect, который принимает единственный аргумент - collect(Collector<? super T, A, R> collector) - так работает collect(Collectors.toSet()).

+0

Это решит проблему, но не объясняет, почему первый фрагмент не компилирует tho тьфу. – Tunaki

+1

Короче: 'Arrays.stream (la) .boxed(). Collect (Collectors.toSet());' –

+0

'LongUnaryOperator o = Long :: valueOf' компилируется отлично. Это не проблема. – Tunaki

2

Код выглядит так же. Метод Arrays.stream, который вызывается на самом деле отличается в обоих случаях:

  • Первый фрагмент: stream(long[]) который возвращает LongStream. Это примитивная специализация потока для элементов long.
  • Второй фрагмент: stream(T[]) (где T = String здесь) которым возвращает Stream<String>

На Stream<String>, вы можете вызвать map и вернуть Stream<R> на основе типа возвращаемого картографа. Но на LongStream, map всегда будет возвращать LongStream, то есть первобытную специализацию. Случается, что Long::valueOf превратит ваш элемент long в объект Long, а затем он будет автоматически распакован в long; эффективно, вызов ничего не делает, кроме box/unbox.

Тогда проблема возникает на вызове collect.

  • LongStream.collect ожидает 3 аргумента
  • Stream.collect имеет метод 3 аргумента, но и метод 1 аргумент, который является тот, который вы звоните с .collect(Collectors.toSet());.

Таким образом, вы не можете позвонить .collect(Collectors.toSet()); по телефону LongStream. Это не скомпилируется: он ожидает 3 аргумента.

Что вы можете сделать, это вызов mapToObj вместо map на LongStream: этот метод объявляет возвращать Stream<R> (вместо LongStream) от типа возвращаемого картографа. В этом случае mapper равен Long::valueOf, который возвращает объект Long, поэтому он вернет Stream<Long>.

Резюмируя:

long la[] = new long[] {1,2,3}; 
    Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet()); 
//^--LongStream----^^---LongStream----^^  error 

    String la[] = new String[] {"1","2","3"}; 
    Arrays.stream(la).map(Long::valueOf).collect(Collectors.toSet()); 
//^-Stream<String>-^^--Stream<Long>--^^---- successful call -----^ 

    long la[] = new long[] {1,2,3}; 
    Arrays.stream(la).mapToObj(Long::valueOf).collect(Collectors.toSet()); 
//^--LongStream----^^-----Stream<Long>-----^^---- successful call -----^ 
+1

Почему это сокращается? Возьми мой верх. –

+0

Спасибо за ваш ответ! – user1283068

0

Чтобы ответить, почему первый один не компилируется, это создает LongStream:

Arrays.stream(la) 

Это происходит каждый long, создает Long оболочку, затем unboxes его назад к long. Поток по-прежнему LongStream:

.map(Long::valueOf) 

Это проходит один параметр LongStream.collect, который терпит неудачу, потому LongStream.collect необходимые 3 параметра:

.collect(Collectors.toSet()) 

Вы должны изменить map к mapToObj, если вы хотите изменить LongStream в Stream<Long> (или позвоните по телефону)

Смежные вопросы