Tag: java stream

为什么这个流没有返回元素?

我尝试将以下代码编写为流: AbstractDevice myDevice = null; for (AbstractDevice device : session.getWorkplace().getDevices()) { if (device.getPluginconfig().getPluginType().getId() == 1) { myDevice = device; } } 这段代码工作正常。 但是当我像这样重写它时它不再起作用了: myDevice = session.getWorkplace().getDevices().stream() .filter(s -> s.getPluginconfig().getPluginType().getId() == 1) .findFirst().get(); 我从流中返回的Optional没有值。 为什么? 编辑 当我尝试这个时(我仍然从getDevices()获得两个设备): List testList = session.getWorkplace().getDevices() .stream().collect(Collectors.toList()); testList为空。 所以我的设备List流似乎出了问题? 它是一个JavaEE应用程序,我从相应的实体获取我的设备: @ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH}) @JoinTable(name = “Workplace_AbstractDevice”, joinColumns = { […]

为什么Files.list()并行流的执行速度比使用Collection.parallelStream()慢得多?

以下代码片段是获取目录列表的方法的一部分,在每个文件上调用extract方法并将生成的药物对象序列化为xml。 try(Stream paths = Files.list(infoDir)) { paths .parallel() .map(this::extract) .forEachOrdered(drug -> { try { marshaller.write(drug); } catch (JAXBException ex) { ex.printStackTrace(); } }); } 这是完全相同的完全相同的代码,但使用普通的.list()调用来获取目录列表并在结果列表中调用.parallelStream() 。 Arrays.asList(infoDir.toFile().list()) .parallelStream() .map(f -> infoDir.resolve(f)) .map(this::extract) .forEachOrdered(drug -> { try { marshaller.write(drug); } catch (JAXBException ex) { ex.printStackTrace(); } }); 我的机器是四核MacBook Pro,Java v 1.8.0_60(内置1.8.0_60-b27)。 我正在处理~7000个文件。 平均3次运行: 第一个版本:使用.parallel() :20秒。 没有.parallel() […]

java 8 – 流,地图和计数不同

我第一次尝试java 8流… 我有一个对象Bid,它代表用户对拍卖中商品的出价。 我有一个出价列表,我想制作一张地图,其中包含用户出价的拍卖数量(不同)。 这是我的看法: bids.stream() .collect( Collectors.groupingBy( bid -> Bid::getBidderUserId, mapping(Bid::getAuctionId, Collectors.toSet()) ) ).entrySet().stream().collect(Collectors.toMap( e-> e.getKey(),e -> e.getValue().size()) ); 它工作,但我觉得我在作弊,因为我流式传输地图的入口集,而不是在初始流上做一个操作…必须是一个更正确的方式这样做,但我无法想象出来… 谢谢

嵌套的Java 8并行forEach循环表现不佳。 这种行为有望吗?

注意:我已经在另一个SOpost中解决了这个问题 – 在嵌套的Java 8并行流动作中使用信号量可能是DEADLOCK。 这是一个错误吗? – 但是这篇文章的标题表明问题与使用信号量有关 – 这有点分散了讨论的注意力。 我正在创建这个,以强调嵌套循环可能有性能问题 – 虽然这两个问题可能是一个共同的原因(也许是因为我花了很多时间来弄清楚这个问题)。 (我不认为它是重复的,因为它强调另一种症状 – 但如果你只是删除它)。 问题:如果你嵌套两个Java 8 stream.parallel()。forEach循环并且所有任务都是独立的,无状态的等等 – 除了被提交到公共FJ池 – 然后在并行循环内嵌套并行循环执行得更差而不是在并行循环内嵌套顺序循环。 更糟糕的是:如果同步包含内循环的操作,您将获得DEADLOCK。 演示性能问题 如果没有“同步”,您仍然可以观察到性能问题。 您可以在以下url找到演示代码: http : //svn.finmath.net/finmath%20experiments/trunk/src/net/finmath/experiments/concurrency/NestedParallelForEachTest.java (有关更详细的说明,请参阅JavaDoc)。 我们的设置如下:我们有一个嵌套的stream.parallel()。forEach()。 内环是独立的(无状态,无干扰等 – 除了使用公共池之外)并且在最坏的情况下总共消耗1秒,即如果是顺序处理的话。 外循环的一半任务在该循环之前消耗10秒。 在该循环之后,一半消耗10秒。 因此,每个线程总共消耗11秒(最坏情况)。 *我们有一个布尔值,允许将内部循环从parallel()切换到sequential()。 现在:将24个外循环任务提交到具有并行性的池8我们预计24/8 * 11 =最多33秒(在8核或更好的机器上)。 结果是: 内部顺序循环:33秒。 内部并行循环:> 80秒(我有92秒)。 问题:你能证实这种行为吗? 这是人们对框架的期望吗? (我现在更加小心,声称这是一个错误,但我个人认为这是由于ForkJoinTask的实现中的一个错误。备注:我已将此发布到并发兴趣(请参阅http:// cs.oswego.edu/pipermail/concurrency-interest/2014-May/012652.html ),但到目前为止我没有得到确认)。 certificate了僵局 以下代码将为DEADLOCK // Outer […]

使用自定义收集器进行Java 8分组?

我有以下课程。 class Person { String name; LocalDate birthday; Sex gender; String emailAddress; public int getAge() { return birthday.until(IsoChronology.INSTANCE.dateNow()).getYears(); } public String getName() { return name; } } 我希望能够按年龄分组,然后收集人名列表而不是Person对象本身; 所有这些都在一个很好的lamba表达式中。 为了简化所有这些,我将链接我当前的解决方案,该解决方案按年龄存储分组结果,然后迭代它以收集名称。 ArrayList members = new ArrayList(); members.add(new OtherPerson(“Fred”, IsoChronology.INSTANCE.date(1980, 6, 20), OtherPerson.Sex.MALE, “fred@example.com”)); members.add(new OtherPerson(“Jane”, IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.FEMALE, “jane@example.com”)); members.add(new OtherPerson(“Mark”, IsoChronology.INSTANCE.date(1990, 7, 15), OtherPerson.Sex.MALE, […]

Java 8 lambdas组列表进入映射

我想获取List并return Map<String, List> ,其中Map的键是Pojo的String值,我们称之为String key 。 澄清一下,给出以下内容: Pojo 1:Key:值:1 Pojo 2:Key:值:2 Pojo 3:键:b值:3 Pojo 4:键:b值:4 我想要一个Map<String, List> with keySet() size 2,其中键“a”具有Pojos 1和2,键“b”具有pojos 3和4。 我怎么能用Java 8 lambdas最好地实现这个目标?

流状态计算:累积总和

假设我有一个Java IntStream,是否可以将它转换为具有累积总和的IntStream? 例如,以[4,2,6,…]开头的流应转换为[4,6,12,…]。 更一般地说,应该如何实现有状态流操作? 感觉这应该是可能的: myIntStream.map(new Function { int sum = 0; Integer apply(Integer value){ return sum += value; } ); 有明显的限制,这只适用于顺序流。 但是,Stream.map明确需要无状态映射函数。 我是否正确错过了Stream.statefulMap或Stream.cumulative操作,还是缺少Java流的重点? 比较一下Haskell,其中scanl1函数正好解决了这个例子: scanl1 (+) [1 2 3 4] = [1 3 6 10]

在Java 8中反转比较器

我有一个ArrayList,并希望按降序排序。 我用它来java.util.stream.Stream.sorted(Comparator)方法。 这是根据Java API的描述: 返回由此流的元素组成的流,根据提供的Comparator进行排序。 这个方法按升序返回给我。 我应该更改哪个参数,只是为了降序?

在Stream reduce方法中,对于sum,标识总是0,对于乘法,1是1吗?

我进行java 8学习。 我发现了有趣的行为: 让我们看看代码示例: // identity value and accumulator and combiner Integer summaryAge = Person.getPersons().stream() //.parallel() //will return surprising result .reduce(1, (intermediateResult, p) -> intermediateResult + p.age, (ir1, ir2) -> ir1 + ir2); System.out.println(summaryAge); 和模型类: public class Person { String name; Integer age; ///… public static Collection getPersons() { List persons = new ArrayList(); persons.add(new […]

Java 8中流的笛卡尔积作为流(仅使用流)

我想创建一个方法来创建一个元素流,这些元素是多个给定流的笛卡尔积(由二元运算符聚合到同一类型)。 请注意,参数和结果都是流, 而不是集合。 例如,对于{A,B}和{X,Y}的两个流,我希望它产生值{AX,AY,BX,BY}的流 (简单串联用于聚合字符串)。 到目前为止,我已经提出了这个代码: private static Stream cartesian(BinaryOperator aggregator, Stream… streams) { Stream result = null; for (Stream stream : streams) { if (result == null) { result = stream; } else { result = result.flatMap(m -> stream.map(n -> aggregator.apply(m, n))); } } return result; } 这是我想要的用例: Stream result = cartesian( (a, b) […]