Я хотел бы немного расширить то, что сказал assylias (что абсолютно правильно).
Во-первых, эти характеристики реализованы как простое int
, это двоичное представление. Сначала это все нули, но когда вы добавляете определенную характеристику, ее бит устанавливается в one
с помощью операции OR
, удаляется с помощью операции AND
.
Вы можете увидеть, где определенное свойство Spliterator устанавливает свой one
, просто выполнив это, например:
System.out.println(Integer.toBinaryString(Spliterator.SIZED)); // 1000000
Это установка 7-го бита в один справа. Итак, когда вы проверяете:
Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator();
System.out.println((spliterator.characteristics() & Spliterator.SIZED) == Spliterator.SIZED);
На самом деле вы проверяете, установлен ли этот особый бит.
Второй
Существует четыре характеристики потока, которые устанавливаются в результате создания первого потока (а не двух). Либо книга немного устарела, либо вы не показали нам весь пример:
Spliterator<Integer> spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator();
System.out.println(Integer.bitCount(spliterator.characteristics())); // 4
System.out.println(Integer.toBinaryString(spliterator.characteristics()));// 100010001010000
Эти установленные биты (равные one
) соответствуют SIZED
, ORDERED
, IMMUTABLE
, SUBSIZED
.
Другие, которые вы показали, тоже, очевидно, немного неверны - вы можете проверить их сами.
Третий
Эти характеристики чрезвычайно важны при потоковой обработке. Несколько примеров:
long howMany = Stream.of(1, 2, 3).map(x -> {
System.out.println("mapping");
return x * 2;
}).count();
System.out.println(howMany); // 3
В java-9 вы не увидите напечатанного mapping
, потому что вы не изменили поток (вы не очистили характеристику SIZED
); таким образом, нет необходимости даже оценивать сопоставление.
Stream<Integer> unlimited = Stream.iterate(0, x -> x + 1);
System.out.println(unlimited.spliterator().hasCharacteristics(Spliterator.SIZED));
Stream<Integer> limited = unlimited.limit(3);
System.out.println(limited.spliterator().hasCharacteristics(Spliterator.SIZED));
Вы могли бы подумать, что на выходе должно быть false true
— в конце концов, мы добавляем limit
, но нет; результат false false
: такая оптимизация не выполняется, даже если ей мало что мешает.
11.06.2017