Questions tagged «java-stream»

将此标签用于与使用Stream API有关的问题。它是Java 8中引入的,支持对值流的功能样式操作,例如集合上的filter-map-reduce管道。

2
Java流toArray()转换为特定类型的数组
也许这很简单,但实际上我对Java 8功能并不了解,并且不知道如何实现。我有一条包含以下文本的简单行: “密钥,名称” 并且我想将该行转换为String数组,并用逗号(,)分隔每个值,但是,我还想在返回最后一个数组之前修剪每个字段,所以我做了以下工作: Arrays.stream(line.split(",")).map(String::trim).toArray(); 但是,这将返回Object []数组而不是String []数组。经过进一步检查,我可以确认内容实际上是String实例,但是数组本身是Object元素。让我说明一下,这就是调试器对返回对象的说明: Object[]: 0 = (String) "Key" 1 = (String) "Name" 据我所知,问题在于映射调用的返回类型,但是如何使它返回String []数组呢?

5
如何将Java枚举转换为流?
我有一个第三方图书馆给我一个图书馆Enumeration<String>。我想像Java 8那样懒惰地使用该枚举,并Stream调用诸如此类的东西。filtermapflatMap 有没有现成的图书馆?我已经在引用Guava和Apache Commons,所以如果它们中的任何一个都有理想的解决方案。 另外,在保留所有内容的懒惰性质的同时将Enumerationa变成最佳/最简单的方法Stream是什么?

4
反转Java 8中的比较器
我有一个ArrayList并想按降序对其进行排序。我用它的java.util.stream.Stream.sorted(Comparator)方法。这是根据Java API的描述: 返回由该流的元素组成的流,并根据提供的进行排序Comparator。 这种方法给我一种升序排序。我应该更改哪个参数,以使其具有降序顺序?


5
Java 8 Collectors.toMap SortedMap
我正在使用Java 8 lambda,并且想要使用Collectors toMap返回一个SortedMap。我能想到的最好的Collectors toMap方法是使用一个虚拟对象mergeFunction并mapSupplier等于来调用以下方法TreeMap::new。 public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M> toMap(Function<? super T, ? extends K> keyMapper, Function<? super T, ? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier) { BiConsumer<M, T> accumulator = (map, element) -> map.merge(keyMapper.apply(element), valueMapper.apply(element), mergeFunction); return new CollectorImpl<>(mapSupplier, accumulator, …

8
Java 8 Streams可以对集合中的项目进行操作,然后将其删除吗?
像几乎每个人一样,我仍在学习新的Java 8 Streams API的复杂性(并喜欢它们)。我对流的使用有疑问。我将提供一个简化的示例。 Java Streams允许我们采用Collection,并stream()在其上使用方法来接收其所有元素的流。在这,有许多有用的方法,比如filter(),map()和forEach(),这让我们对内容的使用拉姆达操作。 我有看起来像这样的代码(简化): set.stream().filter(item -> item.qualify()) .map(item -> (Qualifier)item).forEach(item -> item.operate()); set.removeIf(item -> item.qualify()); 想法是获取集合中与某个限定符匹配的所有项目的映射,然后对它们进行操作。手术后,它们不再具有任何用途,应从原始设备中取出。该代码运行良好,但是我无法动摇一种感觉,Stream即可以在一行中为我完成操作。 如果在Javadocs中,我可能会忽略它。 有谁更熟悉API,会看到类似的东西吗?

3
使用Java 8流将List <Double>相加是否真的需要mapToDouble()?
据我所知,List&lt;Double&gt;使用Java 8流求和的方法是: List&lt;Double&gt; vals = . . . ; double sum = vals.stream().mapToDouble(Double::doubleValue).sum(); 在我mapToDouble(Double::doubleValue)看来,这似乎很不礼貌-只是应该放弃lambda和数据流的样板“仪式”。 最佳实践告诉我们,List实例比数组更可取,但是对于这种求和,数组看起来更干净: double[] vals = . . . ; double sum = Arrays.stream(vals).sum(); 当然,可以做到这一点: List&lt;Double&gt; vals = . . . ; double sum = vals.stream().reduce(0.0, (i,j) -&gt; i+j); 但这reduce(....)比更长sum()。 我知道这与需要围绕Java的非对象原语对流进行改造的方式有关,但是,我在这里还缺少什么吗?有什么方法可以压缩自动装箱以使其更短吗?还是这只是当前的最新状态? 更新-答案摘要 以下是答案的摘要。我在这里进行总结时,我敦促读者自己仔细阅读答案。 @dasblinkenlight解释说,由于Java历史中更进一步的决策,特别是在实现泛型的方式及其与非对象原语的关系方面,总是需要某种类型的拆箱。他指出,从理论上讲,编译器可以进行拆箱操作并允许使用更简短的代码,但这尚未实现。 @Holger显示了一个非常接近我所要表达的解决方案: double sum = …

3
中级流操作未按计数进行评估
似乎我很难理解Java如何将流操作组合到流管道中。 执行以下代码时 public static void main(String[] args) { StringBuilder sb = new StringBuilder(); var count = Stream.of(new String[]{"1", "2", "3", "4"}) .map(sb::append) .count(); System.out.println(count); System.out.println(sb.toString()); } 控制台仅打印4。该StringBuilder对象仍然具有价值""。 当我添加过滤器操作时: filter(s -&gt; true) public static void main(String[] args) { StringBuilder sb = new StringBuilder(); var count = Stream.of(new String[]{"1", "2", "3", "4"}) …
33 java  java-stream 

2
当数字等于0时,如何跳过流的limit(number)调用?
我有一些Java代码可以提供来自的对象items。它基于maxNumber: items.stream() .map(this::myMapper) .filter(item -&gt; item != null) .limit(maxNumber) .collect(Collectors.toList()); 它可以正常工作,但是问题是:当maxNumber == 0?时,是否有一种跳过限制的方法? 我知道我可以这样做: if (maxNumber == 0) { items.stream() .map(this::myMapper) .filter(item -&gt; item != null) .collect(Collectors.toList()); } else { items.stream() .map(this::myMapper) .filter(item -&gt; item != null) .limit(maxNumber) .collect(Collectors.toList()); } 但是,也许有更好的方法,您想到什么了吗?


3
并行无限Java流内存不足
我试图理解为什么以下Java程序给出OutOfMemoryError,而没有的相应程序没有给出.parallel()。 System.out.println(Stream .iterate(1, i -&gt; i+1) .parallel() .flatMap(n -&gt; Stream.iterate(n, i -&gt; i+n)) .mapToInt(Integer::intValue) .limit(100_000_000) .sum() ); 我有两个问题: 该程序的预期输出是什么? 如果没有,.parallel()这似乎只是输出sum(1+2+3+...),这意味着它只是在flatMap的第一个流“卡住”了,这是有道理的。 对于并行,我不知道是否有预期的行为,但是我的猜测是它以某种方式交错了第一个n左右的流,n并行工作者的数量在哪里。根据组块/缓冲行为,它也可能略有不同。 是什么导致它的内存不足?我正在专门尝试了解这些流是如何在后台实现的。 我猜有些东西阻塞了流,因此它永远不会完成,并且能够摆脱生成的值,但是我不太清楚事物的评估顺序和缓冲发生的位置。 编辑:如果相关,我正在使用Java 11。 Editt 2:即使对于简单的程序IntStream.iterate(1,i-&gt;i+1).limit(1000_000_000).parallel().sum(),显然也会发生同样的事情,因此它可能与limit而不是的懒惰有关flatMap。

5
如何从地图生成具有不同值的地图(并使用BinaryOperator使用右键)?
我有一张地图Map&lt;K, V&gt;,我的目标是删除重复的值并Map&lt;K, V&gt;再次输出相同的结构。如果发现重复的值,则必须k从两个键(k1和k1)中选择一个保存这些值的键(),因此,假定BinaryOperator&lt;K&gt;提供k了k1并k2可用。 输入和输出示例: // Input Map&lt;Integer, String&gt; map = new HashMap&lt;&gt;(); map.put(1, "apple"); map.put(5, "apple"); map.put(4, "orange"); map.put(3, "apple"); map.put(2, "orange"); // Output: {5=apple, 4=orange} // the key is the largest possible 用我的尝试Stream::collect(Supplier, BiConsumer, BiConsumer)是位非常笨拙,包含可变操作,比如Map::put和Map::remove我想避免: // // the key is the largest integer possible (following the example above) final …

2
如何理解此Java 8 Stream collect()方法?
我试图将一个int数组转换为List,并且采取了使用Java 8 Stream的陌生路线,并提出了这个建议。 Arrays.stream(arr).boxed().collect(Collectors.toList()); 我仍然很难完全理解这条线, 为什么Collectors.toList()在这种情况下返回一个ArrayList&lt;Integer&gt;实现List接口?为什么不LinkedList&lt;Integer&gt;符合List接口的通用类呢?我找不到这事,除了简短提的ArrayList 这里,在API说明部分。 左边的 意思是什么?显然是通用返回类型(在我的代码中)。而且我认为是该方法的泛型类型参数,但是如何指定它们呢?我查看了Collector界面文档,但无法吸收它。 Stream.collect()RArrayList&lt;Integer&gt;&lt;R, A&gt;

2
您可以重新平衡大小未知的不平衡分离器吗?
我想使用a Stream来并行处理一组未知数量的远程存储的JSON文件的异类(文件数量事先未知)。文件的大小可以相差很大,从每个文件1个JSON记录到其他文件中的100,000个记录。一个JSON记录在这种情况下是指表示为文件中的一条线的自包含JSON对象。 我真的很想为此使用Streams,所以我实现了这一点Spliterator: public abstract class JsonStreamSpliterator&lt;METADATA, RECORD&gt; extends AbstractSpliterator&lt;RECORD&gt; { abstract protected JsonStreamSupport&lt;METADATA&gt; openInputStream(String path); abstract protected RECORD parse(METADATA metadata, Map&lt;String, Object&gt; json); private static final int ADDITIONAL_CHARACTERISTICS = Spliterator.IMMUTABLE | Spliterator.DISTINCT | Spliterator.NONNULL; private static final int MAX_BUFFER = 100; private final Iterator&lt;String&gt; paths; private JsonStreamSupport&lt;METADATA&gt; reader = …

3
Java并行流-调用parallel()方法的顺序
已关闭。这个问题需要更加集中。它当前不接受答案。 想改善这个问题吗?更新问题,使其仅通过编辑此帖子来关注一个问题。 3天前关闭。 AtomicInteger recordNumber = new AtomicInteger(); Files.lines(inputFile.toPath(), StandardCharsets.UTF_8) .map(record -&gt; new Record(recordNumber.incrementAndGet(), record)) .parallel() .filter(record -&gt; doSomeOperation()) .findFirst() 当我写这篇文章时,我假设线程将仅在map调用中产生,因为在map之后放置了parallel。但是文件中的某些行每次执行都会获得不同的记录号。 我阅读了Java流的正式文档和一些网站,以了解流是如何工作的。 几个问题: Java并行流基于SplitIterator进行工作,它由ArrayList,LinkedList等每个集合实现。当我们从这些集合构造并行流时,将使用相应的split迭代器对集合进行拆分和迭代。这解释了为什么并行性发生在原始输入源(文件行)级别而不是映射结果(即Record pojo)。我的理解正确吗? 就我而言,输入是文件IO流。将使用哪个拆分迭代器? 我们放置parallel()在管道中的位置无关紧要。原始输入源将始终被分割,其余的中间操作将被应用。 在这种情况下,Java不应允许用户在管道中除原始源之外的任何地方进行并行操作。因为,它为那些不知道java流内部工作方式的人提供了错误的理解。我知道parallel()操作将为Stream对象类型定义,因此,它是以这种方式工作的。但是,最好提供一些替代解决方案。 在上面的代码片段中,我试图将行号添加到输入文件中的每个记录,因此应该对它进行排序。但是,我想doSomeOperation()并行应用,因为它是繁重的逻辑。一种实现方式是编写自己的自定义拆分迭代器。还有其他办法吗?
11 java  java-stream 

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.