繁体   English   中英

Java Stream Map 过滤,取出并收集

[英]Java Stream Map Filter, Remove and Collect

我有一个包含 1000 个项目的Map ,我想从此Map的前 500 个项目生成一个List ,并删除从Map收集的项目。

换句话说,我想过滤、收集到List并从Map中删除项目。

我正在尝试这样的事情:

final int i = 0;
int max = 5;
Map<String, Object> map = new HashMap<>();
map.put("ads", "123");
map.put("qwe", "123");
map.put("cvb", "123");
map.put("asd", "123");
map.put("iop", "123");
map.put("jkl", "123");
map.put("yui", "123");

List list = map.entrySet().stream().filter(y -> i++ < max).collect(Collectors.toList());

预期 output:

Map 有 2 个值

包含 5 个值的列表

Stream API 旨在创建一个新集合,但不更改现有集合,从中创建一个 stream。

在这种情况下最好使用迭代器功能。 像这样:

final int MAX = 500;

Map<String, String> map = new HashMap<>();
map.put("Item1", "Item 1 value");
map.put("Item2", "Item 2 value");
// ...
map.put("Item1000", "Item 1000 value");

List<String> list = new ArrayList<>();


var iterator = map.entrySet().iterator();
for (int i = 0; i< MAX; i++) {
  if (iterator.hasNext()) {
    var item = iterator.next();
    list.add(item.getValue());
    iterator.remove();
  }
}

正如在其他答案和评论中指出的那样,您不能在流操作期间更改 map。 所以这需要两个步骤。

var list = map.keySet().stream().limit(500).toList();
map.keySet().removeAll(list);

我在这里使用了 Java 16 API 但以前的版本是微小的变化。

但是请注意,鉴于未定义地图的顺序,这是一件毫无意义的事情。 如果您使用带有某些谓词的过滤器,那将更有意义。 尽管在这种情况下,更易读的替代方案可能是:

var list = map.keySet().stream().filter(predicate).toList();
map.keySet().removeIf(predicate);

使用SINGLE STREAM实现此目的的最简单方法是使用Stream#limitCollectors#collectingAndThen并在第二个下游Collector内执行removeAll

这是可能的,因为第一个Collectors.toList将摆脱地图的迭代,然后第二个操作可以删除而不会出现异常

List<Map.Entry<String, Object>> list = map.entrySet()
        .stream()
        .limit(max)
        .collect(Collectors.collectingAndThen(
                Collectors.toList(),
                l -> {
                    map.entrySet().removeAll(l);
                    return l;
                }
        ));

System.out.println("map = " + map); // map = {qwe=123, cvb=123}
System.out.println("list = " + list); // list = [ads=123, asd=123, jkl=123, iop=123, yui=123]

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM