标签: collectors

使用流转换和过滤Java Map

我有一个我想要转换和过滤的Java Map.作为一个简单的例子,假设我想将所有值转换为整数然后删除奇数条目.

Map<String, String> input = new HashMap<>();
input.put("a", "1234");
input.put("b", "2345");
input.put("c", "3456");
input.put("d", "4567");

Map<String, Integer> output = input.entrySet().stream()
        .collect(Collectors.toMap(
                Map.Entry::getKey,
                e -> Integer.parseInt(e.getValue())
        ))
        .entrySet().stream()
        .filter(e -> e.getValue() % 2 == 0)
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));


System.out.println(output.toString());
Run Code Online (Sandbox Code Playgroud)

这是正确的,并产生: {a=1234, c=3456}

但是,我不禁想知道是否有办法避免.entrySet().stream()两次打电话.

有没有办法可以执行转换和过滤操作,.collect()最后只调用 一次?

java java-8 java-stream collectors

35
推荐指数
3
解决办法
4万
查看次数

为什么Java 8'Collector'类以这种方式设计?

我们知道Java 8引入了一个新的Stream API,并且java.util.stream.Collector是定义如何聚合/收集数据流的接口.

但是,Collector接口的设计如下:

public interface Collector<T, A, R> {
    Supplier<A> supplier();
    BiConsumer<A, T> accumulator();
    BinaryOperator<A> combiner();
    Function<A, R> finisher();
}
Run Code Online (Sandbox Code Playgroud)

为什么它的设计不符合以下规定?

public interface Collector<T, A, R> {
    A supply();
    void accumulate(A accumulator, T value);
    A combine(A left, A right);
    R finish(A accumulator);
}
Run Code Online (Sandbox Code Playgroud)

后者更容易实现.将它设计为前者的考虑是什么?

java java-8 java-stream collectors

34
推荐指数
2
解决办法
2298
查看次数

使用无序终端操作的Stream.skip行为

我已经阅读过这个这个问题,但仍然怀疑Stream.skipJDK作者是否打算观察到这种行为.

让我们简单输入数字1..20:

List<Integer> input = IntStream.rangeClosed(1, 20).boxed().collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

现在让我们创建一个并行流,以不同的方式结合unordered()使用skip()并收集结果:

System.out.println("skip-skip-unordered-toList: "
        + input.parallelStream().filter(x -> x > 0)
            .skip(1)
            .skip(1)
            .unordered()
            .collect(Collectors.toList()));
System.out.println("skip-unordered-skip-toList: "
        + input.parallelStream().filter(x -> x > 0)
            .skip(1)
            .unordered()
            .skip(1)
            .collect(Collectors.toList()));
System.out.println("unordered-skip-skip-toList: "
        + input.parallelStream().filter(x -> x > 0)
            .unordered()
            .skip(1)
            .skip(1)
            .collect(Collectors.toList()));
Run Code Online (Sandbox Code Playgroud)

过滤步骤在这里基本没什么,但为流引擎增加了更多的难度:现在它不知道输出的确切大小,因此关闭了一些优化.我有以下结果:

skip-skip-unordered-toList: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
// absent values: 1, 2
skip-unordered-skip-toList: …
Run Code Online (Sandbox Code Playgroud)

java parallel-processing java-8 java-stream collectors

32
推荐指数
1
解决办法
1267
查看次数

partitioningBy的目的是什么?

例如,如果我打算对某些元素进行分区,我可以执行以下操作:

Stream.of("I", "Love", "Stack Overflow")
      .collect(Collectors.partitioningBy(s -> s.length() > 3))
      .forEach((k, v) -> System.out.println(k + " => " + v));
Run Code Online (Sandbox Code Playgroud)

哪个输出:

false => [I]
true => [Love, Stack Overflow]
Run Code Online (Sandbox Code Playgroud)

但对我partioningBy来说只是一个子问题groupingBy.虽然前者Predicate在后者a中接受as参数Function,但我只看到一个分区作为正常的分组函数.

所以相同的代码完全相同:

 Stream.of("I", "Love", "Stack Overflow")
       .collect(Collectors.groupingBy(s -> s.length() > 3))
       .forEach((k, v) -> System.out.println(k + " => " + v));
Run Code Online (Sandbox Code Playgroud)

这也导致了Map<Boolean, List<String>>.

那么有什么理由我应该用partioningBy而不是groupingBy?谢谢

java java-8 collectors

30
推荐指数
2
解决办法
9381
查看次数

收集HashMap <String,List <String >> java 8

我希望能够将转换ListHashMap其中关键是elementName和值是随机的东西(在这种情况下,它的元素名称)的列表.所以总之我想要(A->List(A), B->List(B), C-> List(C)).我尝试使用toMap()并传递它keyMapper,ValueMapper但我收到编译错误.如果有人可以帮助我,我真的很感激.

谢谢!

public static void main(String[] args) {
    // TODO Auto-generated method stub
    List<String> list = Arrays.asList("A","B","C","D");
    Map<String, List<String>> map = list.stream().map((element)->{
        Map<String, List<String>> map = new HashMap<>();
        map.put(element, Arrays.asList(element));
        return map;
    }).collect(??);
}


Function<Map<String, String>, String> key = (map) -> {
    return map.keySet().stream().findFirst().get();
};

Function<Map<String, String>, String> value = (map) -> {
    return map.values().stream().findFirst().get();
};
Run Code Online (Sandbox Code Playgroud)

=== 这对我有用

谢谢你所有的帮助!@izstas"他们应该对元素进行操作"帮了很多:).实际上这正是我想要的确切

public static void …
Run Code Online (Sandbox Code Playgroud)

java list hashmap java-8 collectors

27
推荐指数
3
解决办法
5万
查看次数

Java 8 Streams:为什么Collectors.toMap对于带有通配符的泛型有不同的行为?

假设你有一个List数字.在该值List可以是类型的Integer,Double等等.当你声明这样的List有可能使用一个通配符(声明它?)或不用一个通配符.

final List<Number> numberList = Arrays.asList(1, 2, 3D);
final List<? extends Number> wildcardList = Arrays.asList(1, 2, 3D);
Run Code Online (Sandbox Code Playgroud)

所以,现在我想streamListcollect它所有的Map使用Collectors.toMap(显然下面的代码只是为了说明问题的例子).让我们开始流式传输numberList:

final List<Number> numberList = Arrays.asList(1, 2, 3D, 4D);

numberList.stream().collect(Collectors.toMap(
        // Here I can invoke "number.intValue()" - the object ("number") is treated as a Number
        number -> Integer.valueOf(number.intValue()),
        number -> number));
Run Code Online (Sandbox Code Playgroud)

但是,我不能对以下内容做同样的操作wildcardList:

final List<? extends Number> wildCardList …
Run Code Online (Sandbox Code Playgroud)

java generics lambda java-8 collectors

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

Java 8 Streams:根据不同的属性多次映射同一个对象

我的一位同事向我提出了一个有趣的问题,我无法找到一个整洁而漂亮的Java 8解决方案.问题是流过POJO列表,然后根据多个属性在地图中收集它们 - 映射导致POJO多次出现

想象一下以下POJO:

private static class Customer {
    public String first;
    public String last;

    public Customer(String first, String last) {
        this.first = first;
        this.last = last;
    }

    public String toString() {
        return "Customer(" + first + " " + last + ")";
    }
}
Run Code Online (Sandbox Code Playgroud)

将其设置为List<Customer>:

// The list of customers
List<Customer> customers = Arrays.asList(
        new Customer("Johnny", "Puma"),
        new Customer("Super", "Mac"));
Run Code Online (Sandbox Code Playgroud)

备选方案1:使用Map"流"外部(或更确切地说是外部forEach).

// Alt 1: not pretty since the resulting map is …
Run Code Online (Sandbox Code Playgroud)

java lambda functional-programming java-8 collectors

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

流分组:减少到列表的第一个元素

我有一个List<Valuta>可以表示(简化)JSON风格:

[{codice = EUR,description = Euro,ratio = 1},{codice = USD,description = Dollars,ratio = 1.1}]

我想用这样的方式改变它Map<String, Valuta>:

{EUR = {codice = EUR,description = Euro,ratio = 1},USD = {codice = USD,description = Dollars,ratio = 1.1}}

我写了这个单行:

getValute().stream().collect(Collectors.groupingBy(Valuta::getCodice));
Run Code Online (Sandbox Code Playgroud)

但这会返回一个Map<String, List<Valuta>>而不是我需要的东西.

我认为mapping()功能对我有用,但不知道如何.

java grouping java-8 java-stream collectors

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

如何使用Java 8流和自定义列表和地图供应商将List <V>转换为Map <K,List <V >>?

它很容易转换List<V>Map<K, List<V>>.例如:

public Map<Integer, List<String>> getMap(List<String> strings) {
   return
      strings.stream()
             .collect(Collectors.groupingBy(String::length));
}
Run Code Online (Sandbox Code Playgroud)

但我想与自己ListMap 供应商合作.

我想出了这个:

public Map<Integer, List<String>> getMap(List<String> strings) {
   return strings.stream()
       .collect(Collectors.toMap(
             String::length,
             item -> {List<String> list = new ArrayList<>(); list.add(item); return list;},
             (list1, list2) -> {list1.addAll(list2); return list1;},
             HashMap::new));
}
Run Code Online (Sandbox Code Playgroud)

问题:是否有更简单,更简洁,更有效的方法?例如,像这样的东西(不起作用):

return strings.stream()
      .collect(Collectors.toMap(
            String::length,
            ArrayList::new,                    
            HashMap::new));
Run Code Online (Sandbox Code Playgroud)

如果我只需要定义List供应商而不是Map供应商,该怎么办?

java java-stream collectors

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

如何从HashMap <String,List <E >>获取List <E>

我想List<E>从一个Map<String,List<E>>(E是一个随机类)中提取一个stream().

我想要一个使用java 8流的简单单行方法.

我到现在为止尝试过的事情:

HashMap<String,List<E>> map = new HashMap<>();
List<E> list = map.values(); // does not compile
list = map.values().stream().collect(Collectors.toList()); // does not compile
Run Code Online (Sandbox Code Playgroud)

java collections java-8 java-stream collectors

24
推荐指数
3
解决办法
801
查看次数