天道酬勤,学无止境

java-stream

在 Java 8 中递归展平嵌套映射的值(Recursively Flatten values of nested maps in Java 8)

问题 给定一个Map<String, Object> ,其中值是String或另一个Map<String, Object> ,如何使用 Java 8 将映射展平为单个值列表? 例子: Map - "key1" -> "value1" - "key2" -> "value2" - "key3" -> Map - "key3.1" -> "value3.1" - "key3.2" -> "value3.2" - "key3.3" -> Map - "key3.3.1" -> "value3.3.1" - "key3.3.2" -> "value3.3.2" 对于上面的例子,我想要以下列表: value1 value2 value3.1 value3.2 value3.3.1 value3.3.2 我知道可以这样做: public static void main(String args[]) throws Exception { //Map with nested maps with nested maps with nested maps with nested...... Map<String, Object> map = getSomeMapWithNestedMaps(); List<Object> values = new ArrayList<>(); addToList

2021-06-24 09:02:55    分类:技术分享    java   java-8   java-stream   flatten

Arrays.stream(array) vs Arrays.asList(array).stream()(Arrays.stream(array) vs Arrays.asList(array).stream())

问题 在这个问题中已经回答了两个表达式是相等的,但在这种情况下它们产生不同的结果。 对于给定的int[] scores ,为什么这样做: Arrays.stream(scores) .forEach(System.out::println); ...但这不会: Arrays.asList(scores).stream() .forEach(System.out::println); 据我所知.stream()可以在任何集合上调用,列表肯定是。 第二个代码片段只返回一个包含整个数组而不是元素的流。 回答1 您看到的行为并非特定于Stream 。 Arrays.asList(scores)当你传递一个int[]时返回一个List<int[]> ,因为泛型类型参数不能被原始类型替换。 因此,当您调用asList(T... a) ,编译器使用int[]代替T 。 如果您将scores更改为Integer[] ,您将获得您期望的输出(即Arrays.asList(scores)将返回一个List<Integer> )。 回答2 第二个代码片段不起作用的原因是 Java 中没有List<int>这样的东西。 这就是为什么Arrays.asList(scores)不会产生您期望的结果。 从int[]切换到Integer[]可以解决这个问题,因为这两段代码会产生相同的结果。 但是

2021-06-24 07:21:42    分类:技术分享    java   arrays   foreach   java-8   java-stream

Java 8 Stream 将元素添加到列表和求和(Java 8 Stream add elements to list and sum)

问题 我相信我可以在 listOfPricedObjects 上使用一个流操作来做下一步: List<BigDecimal> myList = new ArrayList(); myList = listOfPricedObjects.stream().map(PricedObject::getPrice).collect(Collectors.toList()); BigDecimal sum = listOfPricedObjects.stream().map(PricedObject::getPrice).reduce(BigDecimal.ZERO, BigDecimal::add) 我如何用价格填充 myList 并一次使用流计算价格总和? 谢谢 UPD:结果我需要 myList 填充价格和 sum 变量和 sum。 但不是使用 stream() 两次。 回答1 您可以在应用缩减时使用peek并添加到新list List<BigDecimal> newList = new ArrayList<>(); BigDecimal sum = list.stream() .map(PricedObject::getPrice) .peek(newList::add) .reduce(BigDecimal.ZERO, BigDecimal::add)

2021-06-24 06:53:34    分类:技术分享    java   collections   java-8   sum   java-stream

如果可能,在收集器中使用 Characteristic.UNORDERED 是否重要?(Is it important to use Characteristics.UNORDERED in Collectors when possible?)

问题 由于我大量使用流,其中一些处理大量数据,我认为最好预先分配一个近似大小的基于集合的收集器,以防止随着集合的增长而进行昂贵的重新分配。 所以我想出了这个,以及其他集合类型的类似方法: public static <T> Collector<T, ?, Set<T>> toSetSized(int initialCapacity) { return Collectors.toCollection(()-> new HashSet<>(initialCapacity)); } 像这样使用 Set<Foo> fooSet = myFooStream.collect(toSetSized(100000)); 我担心的是Collectors.toSet()的实现设置了一个Characteristics枚举,而Collectors.toCollection()没有: Characteristics.UNORDERED 。 Collectors.toCollection()没有方便的变体来设置超出默认值的所需特征,并且由于可见性问题,我无法复制Collectors.toSet()的实现。 因此,要设置UNORDERED特性,我不得不执行以下操作: static<T> Collector<T,?,Set<T>> toSetSized(int initialCapacity){ return

2021-06-24 06:01:49    分类:技术分享    java   java-8   java-stream

Why does this parallel stream run 15x SLOWER? [duplicate]

This question already has answers here: Java 8's streams: why parallel stream is slower? (4 answers) How do I write a correct micro-benchmark in Java? (11 answers) Why is parallel stream slower? (3 answers) Closed 4 years ago. I was attempting to demonstrate to a Java novice streams and such. He said he had read that streams can be slower than for loops for primitive types. So, I set immediately to prove that wrong! What I got was a shock! The for-loop and the serial stream run roughly the same, but the parallel stream is consistently and dramatically slower. Can someone explain why? @Test

2021-06-24 05:51:22    分类:问答    java   java-8   java-stream

如何使用java 8流将列表中的值相乘(How to multiply values in a list using java 8 streams)

问题 流中是否有 sum() 等效方法可以执行流中给定值的乘法? 我有一个像这样的整数列表: List<Integer> listOfIntegers = new ArrayList<>(); listOfIntegers.addAll(Arrays.asList(1,4,2,7,5)); 我能够获得所有整数的总和,但无法找到可以将值相乘并给出输出的 API。 listOfIntegers.stream().mapToInt(a -> a).sum(); 如果我尝试使用 forEach 来做到这一点,那么我无法存储结果,因为只允许在其中使用最终变量。 有什么替代方法吗? 回答1 尝试减少流,它应该会有所帮助。 喜欢: listOfIntegers.stream().reduce(1, (a, b) -> a * b) 此链接提供了有关如何使用 reduce 的更多信息。 回答2 在乘以未知数量的ints时要记住的一件事是溢出的可能性。 而不是(a,b) -> a*b ,使用Math::multiplyExact更安全,它会在溢出时抛出异常: listOfIntegers.stream().mapToInt(x->x).reduce(1, Math::multiplyExact); 或者,您可以通过减少BigInteger来容纳较大的结果: listOfIntegers.stream

2021-06-24 04:25:25    分类:技术分享    java   java-8   java-stream

Stream.map(…) 和 Collectors.mapping(…) 有什么区别?(What's the difference between Stream.map(…) and Collectors.mapping(…)?)

问题 我注意到 Stream 中公开的许多功能在收集器中显然是重复的,例如Stream.map(Foo::bar)与Collectors.mapping(Foo::bar, ...)或Stream.count()与Collectors.counting() 。 这些方法有什么区别? 有性能差异吗? 它们是否以某种方式以不同的方式实现,从而影响它们的并行化程度? 回答1 Stream中似乎存在重复功能的收集器,因此它们可以用作groupingBy()等收集器组合器的下游收集器。 作为一个具体的例子,假设您要计算“卖方的交易计数”。 你可以这样做: Map<Seller, Long> salesBySeller = txns.stream() .collect(groupingBy(Txn::getSeller, counting())); 如果没有像counting()或mapping()这样的收集器,这些类型的查询会困难得多。 回答2 有很大的不同。 流操作可以分为两组: 中间操作 - Stream.map 、 Stream.flatMap 、 Stream.filter 。 那些产生 Stream 的实例并且总是惰性的,例如没有实际遍历 Stream 元素发生。 这些操作用于创建转换链。 终端操作 - Stream.collect 、 Stream.findFirst 、

2021-06-24 03:50:28    分类:技术分享    java   java-8   java-stream

Including elements from unmodified lists in modified lists in a 2D list with Streams

I asked this question about doing the same thing with 1D lists, figuring that it would be easy to apply the answers to 2D lists, but it was not. Basing my code off of Holger's answer, I came up with this solution: //list is of type ArrayList<List<Integer>> list.stream() .map(l -> Stream.concat( l.subList(0, l.size() - 1).stream().map(i -> i - 2), Stream.of(l.get(l.size() - 1)).collect(Collectors.toList()) )) .collect(Collectors.toList()); I get the compile-time error Cannot infer type argument(s) for <R> map(Function<? super T,? extends R>), however, when I try this. How is can I perform this

2021-06-24 02:41:21    分类:问答    java   list   java-8   java-stream

如何使用 Java 8 Stream 将 csv 转换为地图(How to convert csv to a map using Java 8 Stream)

问题 我正在尝试创建一个简单的解析实用程序,它可以转换一个两列的 CSV 文件并将其放入地图中。 public Map<String, String> getMapFromCSV(final String filePath) throws IOException { return Files.lines(Paths.get(filePath)) .map(line -> line.split(",")) .collect(Collectors.toMap(line -> line[0], line -> line[1])); } 如您所见,我正在创建一个字符串流,用逗号分隔每一行并将其转换为字符串数组,最后将键映射到索引 0,将值映射到索引 1。 @Test public void testGetMapFromCSV() throws IOException{ actual = util.getMapFromCSV(filePath).get("AL"); expected = "ALABAMA"; assertEquals(expected, actual); } 出于某种原因,当我运行此测试时,实际值为空。 我排除了无效的 filePath,因为它在另一个单元测试中工作正常,并且键值存在于 CSV 中。 我已经盯着它看了几个小时了,我想也许这里有人可以指出我的错误。 另外,我对

2021-06-24 01:57:02    分类:技术分享    java   csv   lambda   java-8   java-stream

分组对象java 8(grouping objects java 8)

问题 我有类似下面的内容: public class MyClass { private Long stackId private Long questionId } 说 100 的集合,其中 stackid 可以与不同的 questionIds 重复。 它是 stackId 和 questionId 之间的一对多关系 是否有一种流畅的java 8 方法可以转换为以下结构: public class MyOtherClass { private Long stackId private Collection<Long> questionIds } 这将是 25 个的集合,每个实例都有 4 个 questionId 的嵌套集合。 输入 : [{1,100},{1,101},{1,102},{1,103},{2,200},{2,201},{2,202},{1,203}] 输出 [{1, [100,101,102,103]},{2,[200,201,202,203]}] 回答1 Stream API 的直接方式涉及 2 个 Stream 管道: 第一个创建一个临时Map<Long, List<Long>>的stackId到questionIds 。 这是通过 groupingBy(classifier,下游) 收集器完成的,我们根据stackId进行分类

2021-06-24 01:39:46    分类:技术分享    java   java-8   java-stream