标签: java-stream

Java 8流串行和并行性能

在我的机器上,下面的程序打印:

OptionalLong[134043]
 PARALLEL took 127869 ms
OptionalLong[134043]
 SERIAL took 60594 ms
Run Code Online (Sandbox Code Playgroud)

我不清楚为什么串行执行程序比并行执行程序要快.我把两个程序-Xms2g -Xmx2g放在一个8gb相对安静的盒子上.有人可以澄清最新情况吗?

import java.util.stream.LongStream;
import java.util.stream.LongStream.Builder;

public class Problem47 {

    public static void main(String[] args) {

        final long startTime = System.currentTimeMillis();
        System.out.println(LongStream.iterate(1, n -> n + 1).parallel().limit(1000000).filter(n -> fourConsecutives(n)).findFirst());
        final long endTime = System.currentTimeMillis();
        System.out.println(" PARALLEL took " +(endTime - startTime) + " ms");

        final long startTime2 = System.currentTimeMillis();
        System.out.println(LongStream.iterate(1, n -> n + 1).limit(1000000).filter(n -> fourConsecutives(n)).findFirst());
        final long endTime2 = System.currentTimeMillis();
        System.out.println(" SERIAL took …
Run Code Online (Sandbox Code Playgroud)

java performance java-8 java-stream

10
推荐指数
2
解决办法
3310
查看次数

Java 8流:迭代列表地图

我有以下对象和地图:

MyObject
    String name;
    Long priority;
    foo bar;

Map<String, List<MyObject>> anotherHashMap;
Run Code Online (Sandbox Code Playgroud)

我想在另一个地图中转换地图.结果映射的键是输入映射的键.结果映射的值是My对象的Property"name",按优先级排序.

该排序和提取的名字是没有问题的,但我不能把它放到结果地图.我是用旧的Java 7方式做的,但是可以使用流式API是很好的.

Map<String, List<String>> result = new HashMap<>();
for (String identifier : anotherHashMap.keySet()) {
    List<String> generatedList = anotherHashMap.get(identifier).stream()...;

    teaserPerPage.put(identifier, generatedList);
}
Run Code Online (Sandbox Code Playgroud)

有人有想法吗?我试过这个,但卡住了:

anotherHashMap.entrySet().stream().collect(Collectors.asMap(..., ...));
Run Code Online (Sandbox Code Playgroud)

java hashmap java-8 java-stream

10
推荐指数
1
解决办法
2万
查看次数

使用分组,计数和过滤操作收集流

我正在尝试收集丢弃很少使用的项目的流,如下例所示:

import java.util.*;
import java.util.function.Function;
import static java.util.stream.Collectors.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.containsInAnyOrder;
import org.junit.Test;

@Test
public void shouldFilterCommonlyUsedWords() {
    // given
    List<String> allWords = Arrays.asList(
       "call", "feel", "call", "very", "call", "very", "feel", "very", "any");

    // when
    Set<String> commonlyUsed = allWords.stream()
            .collect(groupingBy(Function.identity(), counting()))
            .entrySet().stream().filter(e -> e.getValue() > 2)
            .map(Map.Entry::getKey).collect(toSet());

    // then
    assertThat(commonlyUsed, containsInAnyOrder("call", "very"));
}
Run Code Online (Sandbox Code Playgroud)

我觉得有可能做得更简单 - 我是对的吗?

java java-8 java-stream

10
推荐指数
2
解决办法
5397
查看次数

使用Java 8流计算加权平均值

如何计算加权平均值,Map<Double, Integer>其中整数值是要平均的Double值的权重.例如:Map有以下元素:

  1. (0.7,100)//值为0.7,权重为100
  2. (0.5,200)
  3. (0.3,300)
  4. (0.0,400)

我希望使用Java 8流应用以下公式,但不确定如何一起计算分子和分母并同时保留它.如何在这里使用减少?

在此输入图像描述

java java-8 java-stream

10
推荐指数
1
解决办法
5684
查看次数

Java 8 - 类型不匹配:无法从List <Serializable>转换为List <String>

我有一个字符串列表:

List<String> list = Arrays.asList("a1,a2", "b1,b2");
Run Code Online (Sandbox Code Playgroud)

然后转换列表中的所有内容,如:"a1","a2","b1","b2"写道:

List<String> ss1 = list.stream()
                       .flatMap(s -> Stream.of(s.split(",")))
                       .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但我有一个错误:"类型不匹配:无法转换List<Serializable>为List<String>".我把问题改成了这个:

List<String> ss2 = list.stream()
                       .flatMap(s -> Arrays.stream(s.split(",")))
                       .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

Eclipse Neon表明不同之处在于flatMap返回类型.首先flatMap返回List<Serializable>第二个返回a List<String>.

但两者Stream.of()并Arrays.stream()返回<T> Stream<T>(Eclipse的建议,他们都回报Stream<String>).

再次,Stream.of()内部使用(并返回输出)Arrays.stream().那么,第一种情况又是怎么回事呢?

java eclipse arrays java-8 java-stream

10
推荐指数
1
解决办法
2059
查看次数

如何匹配流元素但如果不存在则返回false?

我有一个流,想检查是否所有匹配过滤器.如果全部匹配,则返回true.

但是,如果流是空的,我想回来false.

我怎样才能做到这一点?

示例代码:

public boolean validate(Stream<Whatever> stream) {
  // Problem: returns **true** if stream empty.
  // How can **false** be returned if stream is empty?
  return stream.allMatch(Whatever::someCheck);
}
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

10
推荐指数
1
解决办法
3280
查看次数

Java并行流:如何等待并行流的线程完成?

所以我有一个列表,我从中获得一个并行流来填写地图,如下所示:

Map<Integer, TreeNode> map = new HashMap<>();
List<NodeData> list = some_filled_list;

//Putting data from the list into the map
list.parallelStream().forEach(d -> {
                TreeNode node = new TreeNode(d);
                map.put(node.getId(), node);
            });

//print out map
map.entrySet().stream().forEach(entry -> {
     System.out.println("Processing node with ID = " + entry.getValue().getId());
                });
Run Code Online (Sandbox Code Playgroud)

这段代码的问题在于,当"放置数据"过程仍在进行时(因为它是并行的),地图正在被打印出来,因此,地图尚未从列表中接收到所有元素.当然,在我的真实代码中,不仅仅是打印出地图; 我使用地图来利用O(1)查找时间.

我的问题是:

  1. 如何使主线程等待,以便在打印出地图之前完成"放置数据"?我试图把"把数据"线程T内,做t.start()和t.join(),但是这并没有帮助.

  2. 也许在这种情况下我不应该使用并行流?列表很长,我只想利用并行性来提高效率.

java collections parallel-processing multithreading java-stream

10
推荐指数
2
解决办法
6679
查看次数

使用Java 8 Streams基于常见条件从两个不同的列表创建映射

我有两个这样的列表实例:

List<NameAndAge> nameAndAgeList = new ArrayList<>();
nameAndAgeList.add(new NameAndAge("John", "28"));
nameAndAgeList.add(new NameAndAge("Paul", "30"));
nameAndAgeList.add(new NameAndAge("Adam", "31"));

List<NameAndSalary> nameAndSalaryList = new ArrayList<>();
nameAndSalaryList.add(new NameAndSalary("John", 1000));
nameAndSalaryList.add(new NameAndSalary("Paul", 1100));
nameAndSalaryList.add(new NameAndSalary("Adam", 1200));
Run Code Online (Sandbox Code Playgroud)

这里NameAndAge是

class NameAndAge {
    public String name;
    public String age;

    public NameAndAge(String name, String age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return name + ": " + age;
    }
}
Run Code Online (Sandbox Code Playgroud)

并且NameAndSalary是

private class NameAndSalary {
    private String name;
    private double …
Run Code Online (Sandbox Code Playgroud)

java java-8 java-stream

10
推荐指数
2
解决办法
309
查看次数

Java流组和多个字段相加

我有一个List fooList

class Foo {
    private String category;
    private int amount;
    private int price;

    ... constructor, getters & setters
}
Run Code Online (Sandbox Code Playgroud)

我想按类别分组,然后总和金额以及价格.

结果将存储在地图中:

Map<Foo, List<Foo>> map = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)

关键是Foo持有汇总的金额和价格,列表作为具有相同类别的所有对象的值.

到目前为止,我已经尝试了以下内容:

Map<String, List<Foo>> map = fooList.stream().collect(groupingBy(Foo::getCategory()));
Run Code Online (Sandbox Code Playgroud)

现在我只需要用保存汇总数量和价格的Foo对象替换String键.这是我被困的地方.我似乎无法找到任何办法.

java grouping java-8 java-stream

10
推荐指数
2
解决办法
7436
查看次数

使用流处理异常

我有一个,Map<String,List<String>>并希望将其变成,Map<String,List<Long>>因为String列表中的每个代表一个Long:

Map<String,List<String>> input = ...;
Map<String,List<Long>> output= 
input.entrySet()
       .stream()
       .collect(toMap(Entry::getKey, e -> e.getValue().stream()
                                                      .map(Long::valueOf)
                                                      .collect(toList()))
               );
Run Code Online (Sandbox Code Playgroud)

我主要的问题是每个人String可能不能正确代表一个Long; 可能有一些问题。Long::valueOf可能会引发例外。如果是这种情况,我想返回一个null或空Map<String,List<Long>>

因为我想遍历这张output地图。但是我不能接受任何错误转换。甚至没有一个。关于如何在不正确的String-> Long转换的情况下如何返回空输出的任何想法?

java java-8 java-stream

10
推荐指数
2
解决办法
187
查看次数