Tag: java stream

如何从迭代器创建Java 8流?

是否可以从迭代器创建一个Stream,其中对象序列与通过重复调用迭代器的next()方法生成的对象序列相同? 我正在考虑的具体情况涉及使用TreeSet.descendingIterator()返回的迭代器,但我可以想象其他情况下迭代器,而不是它引用的集合是可用的。 例如,对于TreeSet tset我们可以编写tset.stream()…并以集合的排序顺序获取该集合中的对象流,但是如果我们希望它们以不同的顺序,例如可以通过使用descendingIterator()吗? 我想像tset.descendingIterator().stream()…或stream( tset.descendingIterator() )… ,虽然这些forms都不是有效的。

Java 8嵌套循环,包含流和性能

为了练习Java 8流,我尝试将以下嵌套循环转换为Java 8流API。 它计算a ^ b(a,b <100)的最大数字总和,并在我的Core i5 760上占用~0.135s。 public static int digitSum(BigInteger x) { int sum = 0; for(char c: x.toString().toCharArray()) {sum+=Integer.valueOf(c+””);} return sum; } @Test public void solve() { int max = 0; for(int i=1;i<100;i++) for(int j=1;j<100;j++) max = Math.max(max,digitSum(BigInteger.valueOf(i).pow(j))); System.out.println(max); } 我的解决方案,我希望由于并行性而更快,实际上需要0.25秒(没有parallel() 0.19s): int max = IntStream.range(1,100).parallel() .map(i -> IntStream.range(1, 100) .map(j->digitSum(BigInteger.valueOf(i).pow(j))) […]

在嵌套的Java 8并行流动作中使用信号量可能是DEADLOCK。 这是一个错误吗?

考虑以下情况:我们使用Java 8并行流来执行并行forEach循环,例如, IntStream.range(0,20).parallel().forEach(i -> { /* work done here */}) 并行线程的数量由系统属性“java.util.concurrent.ForkJoinPool.common.parallelism”控制,通常等于处理器的数量。 现在假设我们想限制特定工作的并行执行次数 – 例如,因为该部分是内存密集型的,而内存约束意味着并行执行的限制。 限制并行执行的一种明显而优雅的方法是使用信号量( 此处建议),例如,以下代码片段将并行执行的数量限制为5: final Semaphore concurrentExecutions = new Semaphore(5); IntStream.range(0,20).parallel().forEach(i -> { concurrentExecutions.acquireUninterruptibly(); try { /* WORK DONE HERE */ } finally { concurrentExecutions.release(); } }); 这很好用! 但是:在worker中使用任何其他并行流(在/* WORK DONE HERE */ )可能会导致死锁 。 对我来说,这是一个意外的行为。 说明:由于Java流使用ForkJoin池,因此内部forEach正在分叉,并且连接似乎正在等待。 但是,这种行为仍然出乎意料。 请注意,如果将”java.util.concurrent.ForkJoinPool.common.parallelism”设置为1,并行流甚至可以工作。 另请注意,如果存在内部并行forEach,则它可能不透明。 问题: 这种行为是否符合Java 8规范(在这种情况下,它意味着禁止在并行流工作者中使用信号量)或者这是一个错误? […]

获取数字流的范围

给定DoubleStream s ,我可以执行s.min()或s.max()但不能同时执行两者,因为其中任何一个都将使用流。 现在假设我有 class Range /* can add code here */ { private final double min; private final double max; Range(double min, double max){ this.min = min; this.max = max; } // can add code here } 我怎样才能获得流的范围? (除了通过s.collect(Collectors.toList()); new Range(s.stream().min(),s.stream().max()); )

Java8流:将值转换为列表的转置映射

我有键映射为String,值为List。 列表可以有10个唯一值。 我需要将此映射转换为键为Integer,将值转换为List。 示例如下: 输入: “关键1”:1,2,3,4 “Key-2”:2,3,4,5 “Key-3”:3,4,5,1 预期产量: 1:“Key-1”,“Key-3” 2:“Key-1”,“Key-2” 3:“Key-1”,“Key-2”,“Key-3” 4:“Key-1”,“Key-2”,“Key-3” 5:“Key-2”,“Key-3” 我知道使用for循环我可以实现这一点,但我需要知道这可以通过java8中的streams / lamda完成。 -谢谢。

为什么没有IntStream.flatMapToObj()?

我正在尝试做这样的事情: Stream stream = IntStream.of(…) .flatMapToObj(i -> getStreamOfObjects(i)); 不幸的是,即使在Java 9中, IntStream.flatMapToObj()也不存在。 为什么遗漏了? 什么是推荐的解决方法?

当我使用Java 8 Stream.of原始类型时,结果很混乱

byte[] a = {1,2,3}; System.out.println(Stream.of(a).count()); Byte[] b = {1,2,3}; System.out.println(Stream.of(b).count()); 结果是1和3,为什么?

拆分流并从文本文件中放入列表

如何使用流将我从文本文件中读取的所有元素放入ArrayList 中,其中monitoredData类具有以下3个私有变量: private Date startingTime, Date finishTime, String activityLabel ; File Activities.txt文本如下所示: 2011-11-28 02:27:59 2011-11-28 10:18:11 Sleeping 2011-11-28 10:21:24 2011-11-28 10:23:36 Toileting 2011-11-28 10:25:44 2011-11-28 10:33:00 Showering 2011-11-28 10:34:23 2011-11-28 10:43:00 Breakfast 等等…. 前两个字符串由一个空格分隔,然后是2个标签,再一个空格,2个标签。 String fileName = “D:/Tema 5/Activities.txt”; try (Stream stream = Files.lines(Paths.get(fileName))) { list = (ArrayList) stream .map(w -> w.split(“\t\t”)).flatMap(Arrays::stream) // \\s+ .collect(Collectors.toList()); […]

带有3个参数的Java8 stream.reduce() – 获得透明度

我编写了这段代码,将一个单词列表缩减为多少单词以’A’开头。 我只是为了学习Java 8而写它,所以我想更好地理解它[免责声明:我意识到这可能不是编写这段代码的最好方法; 这只是为了练习!] 。 Long countOfAWords = results.stream().reduce( 0L, (a, b) -> b.charAt(0) == ‘A’ ? a + 1 : a, Long::sum); 中间参数/ lambda(称为累加器)似乎能够在没有最终’Combiner’参数的情况下减少完整列表。 事实上,Javadoc实际上说: {@code accumulator}函数充当融合映射器和累加器*,它有时比单独的映射和缩减更有效,*例如当知道先前减少的值允许您避免*某些计算时。 [编辑来自作者] –以下陈述是错误的,所以不要让它混淆你; 我只是把它放在这里,所以我不会破坏答案的原始背景。 无论如何,我可以推断累加器必须输出组合器组合的1和0。 我没有从文档中发现这一点特别明显。 我的问题 有没有办法在组合器执行之前查看输出是什么,所以我可以看到组合器组合的1和0的列表? 这将有助于调试更复杂的情况,我相信我最终会遇到这种情况。

从一个长流创建流的流

我想根据Streams的内容将单个Stream拆分为Streams Streams 。 生成的Stream应包含部分原始流的数据。 我的实际应用程序更复杂(它将日志行分组在时间间隔列表中),但我的问题是如何处理流,所以在这里我要问一个简化的例子。 示例问题 我希望能够根据重复的相同数字将Stream拆分为Stream<Stream> ,只留下奇数的流。 例如,以下流包含: {1,1,1,2,2,2,3,6,7,7,1,1} 需要产生包含以下内容的流的流: {{1,1,1},{3},{7,7},{1,1}} 通过使用filter开始(或结束),我可以做出偶数数字: Stream input = …; Straem<Stream> output = input.filter(this::isOdd).someOtherOperation(); 这是不希望的,因为它意味着两次评估每个输入值,这是可以接受的,但我宁愿避免这种情况。 解决方案的想法 我当前的解决方案是迭代流的内容并创建List<List>并将其转换为Stream<Stream> 。 但是这意味着完整的结果保存在内存中(这对我的应用程序来说是不受欢迎的)。 我也认为我可以通过编写从流中读取的自己的Iterator这一点,但我不确定这是如何工作的。 题 如何根据原始Stream的内容将Stream转换为Stream of Stream ,而不是首先将完整结果存储为List of Lists 。