- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
JavaDocs for findFirst
说如果流有遇到顺序,那么总是返回第一个元素,但是如果流没有遇到顺序,则可以返回任何元素。
我试图演示它是如何在没有遇到顺序的流上工作的,但除了实际的第一个元素之外,我无法让它返回任何内容。
我尝试将元素添加到 Set
,它没有定义遇到顺序:
Set<String> words = new HashSet<>();
words.addAll(Arrays.asList("this", "is", "a", "stream", "of", "strings"));
Optional<String> firstString = words.stream()
.findFirst();
System.out.println(firstString);
每次我运行时,我都会得到 a
作为第一个字符串。然后我尝试在 List
上执行 Collections.shuffle
,然后将其添加到 Set
,但这并没有改变任何东西。
List<String> wordList = Arrays.asList("this", "is", "a", "stream", "of", "strings");
words = new HashSet<>();
words.addAll(wordList);
firstString = words.stream()
.findFirst();
System.out.println(firstString);
我仍然每次都回想起a
这个词。
然后我尝试使用 BaseStream
中的 unordered
方法,该方法声称返回没有遇到顺序的流,但没有区别:
firstString = Stream.of("this", "is", "a", "stream", "of", "strings")
.unordered()
.findFirst();
System.out.println(firstString);
现在我每次都会得到 this
这个词。我错过了什么吗?有什么方法可以证明无序流上的 findFirst
返回不同的值?
最佳答案
嗯,“任何”包括“第一”的可能性。当然,Stream 的实现并没有浪费时间随机化数据,所以在很多情况下,尤其是顺序执行的情况下,它仍然是第一个元素,如果我们可以这样调用它(因为没有顺序,有没有区分的第一个元素)。
为 findFirst
展示不同结果的最佳机会是使用并行流。但即便如此,也不是每一种操作组合都适合表现出无序性。
有一点是,在当前的实现中,findFirst()
操作在流无序时不会改变它的行为,即它不会主动尝试像 findAny()
那样。由于 Stream 的 source,它仍可能表现出不可预测的行为,但如果您的源是 Stream.of("this", "is", "a", "stream", "of", "strings")
,即已知大小的不可变序列,它已经具有可能的最佳并行性能,因此根本无法从链式 unordered()
,因此,当前的实现不会改变它的行为。
这可能令人惊讶,但这在某种程度上甚至适用于 HashSet
。虽然它有一个未指定的顺序,但在某个时间点,它的后备数组中会有一个实际的顺序,只要你不修改 Set
,就没有理由打乱这些条目因此,对于特定的 HashSet
实例,您可能会重复获得相同的“第一个”元素,尽管没有指定哪个元素,甚至在单个运行时,另一个 HashSet
实例表示相同的内容,但具有不同的历史,可能有不同的顺序。
distinct
是已知从无序特征中获益的一个操作示例。虽然它必须对重复项进行排序,但它必须保持 first 遇到的相等元素,如果它产生显着差异的话。这会显着降低性能,因此,如果流是无序的,实现将立即尝试获得好处。例如
List<String> equal=IntStream.range(0, 100)
.mapToObj(i->new String("test")) // don't do this in normal code
.collect(Collectors.toList());
Map<String, Integer> map = IntStream.range(0, equal.size())
.collect(IdentityHashMap::new, (m,i)->m.put(equal.get(i),i), Map::putAll);
equal.parallelStream().distinct().map(map::get)
.findFirst().ifPresent(System.out::println);
这会创建一堆 equal
但可区分的 String
实例(您通常不应该这样做),并在 IdentityHashMap< 中使用它们的位置编号注册它们
,因此我们可以找出 distinct
保留了哪个实例。由于上面的代码使用了由 List
创建的有序流,因此无论您多久执行一次,它都会始终打印 0
。
相比之下,
equal.parallelStream().unordered().distinct().map(map::get)
.findFirst().ifPresent(System.out::println);
将打印范围的任意数字,因为我们已经发布了 ordered 合约并允许选择任何相等的字符串。
如前所述,这都是特定于实现的。你永远不应该假设一个操作是否真的能带来好处,从而改变它对无序流的行为。上面的解释只是为了说明为什么有时特定实现的行为对于无序流可能不会改变。不过,它仍然可能在下一个版本或不同的 JRE 实现中。
关于Java 8 findFirst 和遇到顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41894173/
我曾以为 FindFirst 会按字母顺序查找文件,但最近我发现虽然大多数情况都是如此,但有一些文件并不是按字母顺序排列的。 if FindFirst( AProgramPath, faAnyFile
在管道中使用findFirst()和map()是否有效。findFirst是短路方法而map是中间操作。 this.list.stream().filter(t -> t.name.equals("p
Stream 的 findFirst 方法在此流中找到第一个元素为 Optional。如果流没有元素,则 findFirst 返回空 Optional。如果流没有遇到顺序,则 findFirst 可以
早上好...我正在列出目录中的所有文件...但我面临以下问题...当文件夹全部都是英文...但操作系统是葡萄牙国防部...如何根据操作系统语言列出: 例如:Program Files (EN) ->
在我的应用程序中,我使用以下过程递归扫描任何文件夹和子文件夹,如果该文件夹包含文本文件 (*.txt),我会将文件名添加到我的过程中定义的 TStringList: procedure FileSea
我将参数值'*1.dat'传递给FindFirst,FindFirst()例程返回的第一个文件仍然是46checks5.dat,非常一致。 这是一个已知问题吗? vpath:=trim(vpath);
以下方法是用于选择歌曲的加权随机选择算法的一部分。 我想将下面的方法转换为使用流,以确定它是否更清晰/更可取。我不确定这是否可能,因为计算是有状态的操作,取决于列表中的位置。 public Song
我有以下代码(TrResponse 和 TrNode 的代码无关): public TrResponse from(final TrNode b1, final TrNode b2, final Tr
我有两个表: AuctionPackage $this->belongsTo('id', 'AuctionPackageTranslation', 'auction_package_id', NULL
我正在使用 Realm 为我的应用程序提供数据库。但是…… 登录后,服务器返回数据,我创建(AccountManager 的)帐户并将这些数据保存在应用程序的数据库中,就像这样(当然是在 AsyncT
我想知道当我知道 100 时,是否有办法在不使用 .orElse() 的情况下消除 findFirst().get() 处的警告% 每次都有结果,所以我从来没有得到 NoSuchElementExce
JavaDocs for findFirst说如果流有遇到顺序,那么总是返回第一个元素,但是如果流没有遇到顺序,则可以返回任何元素。 我试图演示它是如何在没有遇到顺序的流上工作的,但除了实际的第一个元
SortedSet 的 java 8 API 文档仅声明 stream() 继承自 java.util.Collection(参见 https://docs.oracle.com/javase/8/d
我正在从 Core Data (Magical Record) 切换到 Realm,我想知道是否有相当于 MR_findFirst 的东西? 现在,我正在做: if ([myRlmObject all
当使用 FindFirst() 搜索文件时,我在 TSearchRec.Attr 字段中得到一个属性值 2080。帮助中没有指定它,因为只有这些值可用,并且它们的组合不会产生 2080: 1 fa只读
我在 Windows 7 上使用 Delphi 2010,在递归搜索目录时遇到单引号加倍的问题。 这是我搜索目录的代码。 if FindFirst(aPath + '*', faDirectory
我想找到满足某些条件的矩阵每行中第一个值的索引。我想弄清楚如何在不使用数组理解的情况下做到这一点。 这就是我使用数组理解的方式: # let's say we want to find the fir
我想找到满足某些条件的矩阵每行中第一个值的索引。我想弄清楚如何在不使用数组理解的情况下做到这一点。 这就是我使用数组理解的方式: # let's say we want to find the fir
我有一个核心数据模型,该模型由具有多个位置的 Trail 组成。我也在使用 RestKit。我获取线索的代码如下所示: Trail *trail = [Trail findFirst]; 我的问题是每
我搜索并找到了FindFirst returns null问题,但没有人回答。当我认为我做错了什么时,让我用更多的细节来解释我的问题。 我正在开发一款应用,它要求用户先登录,然后让用户使用该应用。 我
我是一名优秀的程序员,十分优秀!