Ответ 1
Я хотел бы немного расширить то, что сказали 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);
Фактически вы проверяете, установлен ли этот бит.
Второй
Есть 4 характеристики потока, которые задаются в результате создания вашего первого потока (а не двух). Либо книга немного устарела, либо вы не показали нам весь пример:
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
, но no; результат false false
: такая оптимизация не выполняется, даже если этого не мешает.