How to correctly find the stream characteristics in Java-8?

后端 未结 2 668
离开以前
离开以前 2021-02-05 13:35

While doing stream operations, during the intermediate/pipeline operations the streams would be created with different characteristics(e.g: SORTED/SIZED/DISTINCT/ORDERED) - Mast

2条回答
  •  伪装坚强ぢ
    2021-02-05 13:52

    I would like to slightly extend what assylias said (which is absolutely correct).

    First, these characteristics are implemented as plain int, it's binary representation. First it's all zeroes, but when you add a certain characteristic it's bit is set to one via the OR operation, removed via the AND operation.

    You can see where a certain Spliterator property sets its one simply by doing this for example:

    System.out.println(Integer.toBinaryString(Spliterator.SIZED)); // 1000000
    

    It's setting the 7-th bit into one from the right. So when you check:

    Spliterator spliterator = Stream.of(8, 3, 5, 6, 7, 4).spliterator();
    System.out.println((spliterator.characteristics() & Spliterator.SIZED) == Spliterator.SIZED);
    

    You are actually checking if this particular bit is set.

    Second

    There are 4 stream characteristics that are set as the result of your first stream creation(and not two). Either the book is a bit outdated or you have not showed us the entire example:

    Spliterator 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
    

    These set bits (that are equal to one) correspond to SIZED, ORDERED, IMMUTABLE, SUBSIZED.

    The others that you have shown are obviously slightly off too - you can check those yourself.

    Third

    These characteristics are extremely important in stream processing. A few examples:

    long howMany = Stream.of(1, 2, 3).map(x -> {
            System.out.println("mapping");
            return x * 2;
        }).count();
        System.out.println(howMany); // 3
    

    In java-9 you will not see the mapping printed, because you have not changed the stream (you have not cleared the SIZED characteristic); thus no need to even evaluate the mapping at all.

    Stream unlimited = Stream.iterate(0, x -> x + 1); 
    System.out.println(unlimited.spliterator().hasCharacteristics(Spliterator.SIZED));
    Stream limited = unlimited.limit(3);          
    System.out.println(limited.spliterator().hasCharacteristics(Spliterator.SIZED));
    

    You would think that the output should be false true - we are adding a limit after all, but no; the result is false false: no such optimization is done, even if there is not much preventing it.

提交回复
热议问题