当前位置: 首页 > 知识库问答 >
问题:

如何正确找到Java-8中的流特征?

百里飞捷
2023-03-14

执行流操作时,在中间/流水线操作期间,将创建具有不同特性的流(例如:排序/大小/不同/排序)--掌握lambda(第6章)

Stream.of(8,3,5,6,7,4) // ORDERED, SIZED
.filter(i->i%2==0) // ORDERED
.sorted() // ORDERED, SORTED
.distinct() // DISTINCT, ORDERED, SORTED
.map(i->i+1) // ORDERED
.unordered(); // none

我们如何找出上面片段中提到的流的不同特征?

共有1个答案

屠和洽
2023-03-14

我想稍微引申一下亚瑟利亚斯所说的话(这是绝对正确的)。

首先,这些特性被实现为简单的int,它是二进制表示。首先,它全部为零,但当您添加某个特性时,它的位通过操作被设置为One,通过操作被移除。

您可以看到某个Spliterator属性设置其One的位置,只需执行以下操作即可,例如:

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

它把第7位从右边设置为1。所以当您检查:

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)对应于sizedorderedimmutablesumved

你所展示的其他部分显然也略有偏差--你可以自己检查。

第三

这些特性在流处理中极为重要。举几个例子:

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:没有进行这样的优化,即使没有太多的预防措施。

 类似资料:
  • 问题内容: 在执行流操作时,将在中间/流水线操作期间创建具有不同特征的流(例如:SORTED / SIZED / DISTINCT / ORDERED)-掌握Lambda(第6章) 我们如何找出上述片段中提到的流的不同特征? 问题答案: 我想稍微延长一下亚述(绝对正确)。 首先 ,这些特征被实现为plain ,它是二进制表示形式。首先是全零,但是当您添加某个特性时,通过操作将该位设置为,通过该操作

  • 问题内容: 以编程方式确定输入流/文件的正确字符集编码的最佳方法是什么? 我尝试使用以下方法: 但是在我知道要用ISO8859_1编码的文件上,上面的代码会产生ASCII,这是不正确的,并且不允许我将文件的内容正确地呈现回控制台。 问题答案: 无法确定任意字节流的编码。这就是编码的本质。编码是指字节值与其表示形式之间的映射。因此,每种编码“都可以”是正确的。 的getEncoding()方法将返回

  • 问题内容: 用Java产生和使用外部进程的流(IO)的正确方法是什么?据我所知,由于可能的缓冲区大小有限,因此应在与生成进程输入并行的线程中使用java结束输入流(进程输出)。 但是我不确定我是否最终需要与这些使用者线程进行同步,或者仅等待进程退出以使用方法就足够了,以确保所有进程输出实际上都被消耗了?IE是否有可能,即使进程退出(关闭其输出流),流的Java端仍存在未读数据?实际如何知道该过程何

  • 我有一连串的弦和空值 我想将它简化为另一个流,其中任何非空字符串序列连接在一起,即像 我发现的第一种方法是创建收集器,首先将完整的输入流减少到具有所有连接字符串列表的单个对象,然后从中创建新流: 但在这种情况下,在任何使用前,如果str2,甚至作为str2。findFirst(),将完全处理输入流。它需要耗费时间和内存的操作,并且在来自某个生成器的无限流上,它将根本不工作 另一种方法-创建将保持中

  • 请,任何人都可以帮助我找到正确的XPath来检索日期值“07/05/2018 04:45” 我试过但没有成功: /输入[@type=“text”]@值 //*[@id="start Date"]

  • 我已经使用java流实现了这个breadthFirstSearch算法。首先,我过滤检查顶点是否被标记,然后如果它没有被标记,我将它添加到队列中。当我使用.map时,我需要用一个类似.collect(Collectors.ToList())的终止操作结束。 我的问题是这看起来不对,因为我正在使用collect返回一个新的过滤顶点列表。在这种情况下,我应该使用什么终端操作?我不需要收集新名单。我只想