标签: java-stream

如何在java流中按降序排序LinkedHashMap?

要按升序对其进行排序,我可以使用:

myMap.entrySet().stream()
    .sorted(Map.Entry.comparingByValue())
    .collect(Collectors.toMap(Entry::getKey, Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

我怎么能按降序排列呢?

java sorting linkedhashmap java-8 java-stream

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

使用多个映射函数与java流中的映射中的块语句

说我有以下代码

data.stream()
    .map(x -> {
        Object a = maybeReturnsNull(x);
        return a == null ? defaultValue : a;
    })
Run Code Online (Sandbox Code Playgroud)

我有一些可能正在返回的函数,null我将它应用于流的一个元素.然后我想确保将任何null结果更改为某个默认值.与使用上一个定义辅助变量a并在lambda表达式中使用代码块的示例相比,使用两个映射(如下例)之间是否存在任何显着差异?

data.stream()
    .map(x -> maybeReturnsNull(x))
    .map(x -> x == null ? defaultValue : x)
Run Code Online (Sandbox Code Playgroud)

有没有标准在哪里或不避免使用lambda函数的块语句?

java java-8 java-stream map-function

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

选择列表的元素,直到Java 8 Lambdas满足条件

我试图改变主意思考功能方式,并且最近面临一种情况,我需要从列表中获取元素,直到满足条件,我找不到一种简单的自然方式来实现这一点.显然我还在学习.

说我有这个清单:

List<String> tokens = Arrays.asList("pick me", "Pick me", "pick Me",
    "PICK ME", "pick me and STOP", "pick me", "pick me and Stop", "pick me");

// In a non lambdas was you would do it like below
List<String> myTokens = new ArrayList<>();
for (String token : tokens) {
    myTokens.add(token);
    if (token.toUpperCase().endsWith("STOP")) {
        break;
    }
}
Run Code Online (Sandbox Code Playgroud)

提前感谢您的意见

注意:在发布之前,我读了一个谓词限制流,但我看不出如何能够根据我的问题调整答案.任何帮助将不胜感激.

java lambda java-8 java-stream

15
推荐指数
4
解决办法
1万
查看次数

将消费者转换为功能

Function接口的许多lambda都采用了这种形式

t -> {
    // do something to t
    return t;
}
Run Code Online (Sandbox Code Playgroud)

我经常这样做,所以我已经为此编写了一个方法.

static <T> Function<T, T> consumeThenReturn(Consumer<T> consumer) {
    return t -> {
        consumer.accept(t);
        return t;
    };
}
Run Code Online (Sandbox Code Playgroud)

这使我能够做到这样的非常好的事情:

IntStream.rangeClosed('A', 'Z')
         .mapToObj(a -> (char) a)
         .collect(Collectors.collectingAndThen(Collectors.toList(), consumeThenReturn(Collections::shuffle)))
         .forEach(System.out::print); 
Run Code Online (Sandbox Code Playgroud)

还有另一种方法可以在不依赖我自己的方法的情况下进行这样的转换吗?我错过的新API中有什么东西会让我的方法变得多余吗?

java java-8 java-stream

15
推荐指数
1
解决办法
1836
查看次数

小写所有HashMap键

我遇到了一个场景,我想要小写HashMap的所有键(不要问为什么,我只需要这样做).HashMap有数百万条目.

起初,我以为我只是创建一个新的Map,迭代要小写的地图条目,并添加相应的值.这个任务应该每天只运行一次或类似的东西,所以我想我可以裸露这个.

Map<String, Long> lowerCaseMap = new HashMap<>(myMap.size());
for (Map.Entry<String, Long> entry : myMap.entrySet()) {
   lowerCaseMap.put(entry.getKey().toLowerCase(), entry.getValue());
}
Run Code Online (Sandbox Code Playgroud)

但是,当我的服务器在这一次过载时,我正要复制Map时,会导致一些OutOfMemory错误.

现在我的问题是,如何以最小的内存占用来完成这项任务?

在小写后删除每个键 - 添加到新Map帮助?

我可以利用java8流来加快速度吗?(例如这样的事情)

Map<String, Long> lowerCaseMap = myMap.entrySet().parallelStream().collect(Collectors.toMap(entry -> entry.getKey().toLowerCase(), Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)

更新 似乎它是一个Collections.unmodifiableMap所以我没有选择

在小写之后移除每个键 - 添加到新地图

java hashmap java-8 java-stream

15
推荐指数
1
解决办法
8942
查看次数

从流中收集对

我有一个像这样的对象流:

"0", "1", "2", "3", "4", "5",
Run Code Online (Sandbox Code Playgroud)

如何将其转换为对的流:

{ new Pair("0", "1"), new Pair("2", "3"), new Pair("4", "5")}.
Run Code Online (Sandbox Code Playgroud)

流大小未知.我正在从一个可能很大的文件中读取数据.我只有收集器的迭代器,我使用spliterator将此迭代器转换为流.我知道这是使用StreamEx处理相邻对的答案: 从流中收集连续对 可以在java或StreamEx中完成吗?谢谢

java java-stream streamex

15
推荐指数
2
解决办法
2186
查看次数

规范是否保证顺序Java流上的操作必须保留在当前线程中?

规范是否保证顺序 Java Streams 上的所有操作都在当前线程中执行?("forEach"和"forEachOrdered"除外)

我明确要求规范,而不是当前的实现.我可以自己查看当前的实现,不需要打扰你.但实现可能会改变,还有其他实现.

我问因为ThreadLocals:我使用的是一个内部使用ThreadLocals的Framework.即使像company.getName()这样的简单调用最终也会使用ThreadLocal.我无法改变该框架的设计方式.至少不在理智的时间内.

这里的规范似乎令人困惑.包"java.util.stream"的文档说明:

如果行为参数确实有副作用,除非明确说明,否则不能保证这些副作用对其他线程的可见性,也不保证同一流管道中"相同"元素的不同操作在同一个线程中执行.

...

即使当管道被约束以产生结果,其与流源的遭遇顺序一致(例如,IntStream.range(0,5).parallel()地图(X - > X*2).toArray( )必须产生[0,2,4,6,8]),不能保证制成,以作为对于所述映射器函数被应用到各个元件,或为了在什么螺纹任何行为参数被执行对于给定的元件.

我将其解释为:流上的每个操作都可以在不同的线程中发生.但是"forEach"和"forEachOrdered"的文档明确指出:

对于任何给定元素,可以在任何时间以及库选择的任何线程中执行该动作.

如果每个流操作都可能发生在未指定的线程中,那么该语句将是多余的.因此恰恰相反:串行流上的所有操作都保证在当前线程中执行,除了"forEach"和"forEachOrdered"?

我搜索了关于"Java","Stream"和"ThreadLocal"组合的权威答案,但没有发现任何内容.该关闭的事情是由一个答案作者Brian Goetz在这里对堆栈溢出一个相关的问题,但它是有关订单,而不是线程,它只是对"的forEach",而不是其他流的方法:是否Stream.forEach尊重遇到顺序流的顺序?

java thread-local java-8 java-stream

15
推荐指数
1
解决办法
264
查看次数

并行流的行为与Stream不同

我无法理解为什么并行流和流为完全相同的语句提供不同的结果.

    List<String> list = Arrays.asList("1", "2", "3");
    String resultParallel = list.parallelStream().collect(StringBuilder::new,
            (response, element) -> response.append(" ").append(element),
            (response1, response2) -> response1.append(",").append(response2.toString()))
            .toString();
    System.out.println("ResultParallel: " + resultParallel);

    String result = list.stream().collect(StringBuilder::new,
            (response, element) -> response.append(" ").append(element),
            (response1, response2) -> response1.append(",").append(response2.toString()))
            .toString();

    System.out.println("Result: " + result);
Run Code Online (Sandbox Code Playgroud)

ResultParallel:1,2,3

结果:1 2 3

有人可以解释为什么会发生这种情况以及如何让非并行版本得到与并行版本相同的结果?

java parallel-processing java-stream

15
推荐指数
3
解决办法
244
查看次数

如何使用Java 8流式api从地图列表创建地图地图

背景

我有一个看起来像这样的地图列表:

[
  {
    "name": "A",
    "old": 0.25,
    "new": 0.3
  },
  {
    "name": "B",
    "old": 0.3,
    "new": 0.35
  },
  {
    "name": "A",
    "old": 0.75,
    "new": 0.7
  },
  {
    "name": "B",
    "old": 0.7,
    "new": 0.60
  }
]
Run Code Online (Sandbox Code Playgroud)

我希望输出看起来像这样:

{
  "A": {
    "old": 1,
    "new": 1
  },
  "B": {
    "old": 1,
    "new": 0.95
  }
}
Run Code Online (Sandbox Code Playgroud)

...其中每个相关条目的值old和new的总和.

映射列表的数据类型是List<Map<String, Object>>,因此输出应该是a Map<String, Map<String, Double>>.

我试过的

通过一些图表绘图,文档阅读和反复试验,我能够想出这个:

data.stream()
    .collect(
        Collectors.groupingBy(entry -> entry.get("name"),
            Collectors.summingDouble(entry ->
                Double.parseDouble(entry.get("old").toString())))
    );
Run Code Online (Sandbox Code Playgroud)

生成类型的对象Map<String, Double> …

java lambda java-8 java-stream

15
推荐指数
2
解决办法
549
查看次数

IntStream rangeClosed无法返回int以外的值

为什么会出错?我以为map可以回报任何价值.

var s = IntStream.rangeClosed(1, 5).map(String::valueOf).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

| 错误:| 不兼容的类型:方法引用中的错误返回类型| java.lang.String无法转换为int | var s = IntStream.rangeClosed(1,5).map(String :: valueOf).collect(Collectors.toList()); |
^ ^ -------------

java lambda java-8 java-stream

15
推荐指数
3
解决办法
523
查看次数