在Java 8流中将键值映射到对象

5

假设我有以下代码:

Map<String, String> map;
// later on
map.entrySet().stream().map(MyObject::new).collect(Collectors.toList());

我有一个名为MyObject的构造函数,它接受两个String类型的参数。 我想要做到这一点,但我不能。 我知道我可以使用e -> new MyObject(e.getKey(), e.getValue()),但更喜欢MyObject::new
对于MyObject类的一个参数构造函数,类似的代码适用于Set<String>List<String>

2
“map” 函数并不知道这两个必要的 “String” 在哪个 “Map.Entry” 实例内。你需要手动提取键和值,因此需要使用 e.getKey()e.getValue() 方法。 - f1sh
1
你为什么喜欢使用方法引用?当它符合要求时,它很优雅,但在这里并不适用。 - RealSkeptic
1
请参见此链接:https://dev59.com/Dl0a5IYBdhLWcg3w48JP - Hadi J
2
你可以使用来自这个回答PairStream; PairStream.from(map).map(MyObject::new).collect(Collectors.toList()); - Holger
4个回答

10

使用 Lambda:

map.entrySet()
   .stream()
   .map(e -> new MyObject(e.getKey(), e.getValue()))
   .collect(Collectors.toList());
否则,使用方法引用的唯一方法是创建一个函数,如下所示:
private static MyObject apply(Map.Entry<String, String> e) {
      return new MyObject(e.getKey(), e.getValue());
}

然后做这样的事情:

map.entrySet()
   .stream()
   .map(Main::apply)
   .collect(Collectors.toList());

Main 是包含 apply 方法的类。


3
map.entrySet().stream().map(MyObject::new).collect(Collectors.toList()));

And I have a MyObject Constructor which takes two arguments of type String. I want to be able to do this but I cannot.

map.entrySet().stream().map(...)中,Java期望一个Function将一个值映射到另一个值。 一个值。 从流中,该函数接收到一个类型为Map.Entry<String, String>的值, 但您的构造函数需要两个String参数。 Java不会自动将Map.Entry<String, String>扩展为一对String以传递给您的构造函数。 您必须手动进行解包。

2
构造函数的问题在于它定义了两个参数,而由 Stream#map 要求的 Function#apply 只接受一个参数。
你可以为 MyObject 编写一个静态工厂方法。
class MyObject {
    public static MyObject of(Map.Entry<String, String> e) {
        return new MyObject(e.getKey(), e.getValue());
    }
}

并且可以像这样引用它

map(MyObject::of)

在进行操作之前,请问一下自己,是否值得为一个简单的处理链中的一个漂亮的代码行编写新的构造函数或实用方法。

2

添加Map.Entry构造函数

class MyObject {
        private final String k;
        private final String v;

        MyObject(String s1, String s2) {
            k = s1;
            v = s2;
        }

        MyObject(Map.Entry<String, String> e) {
            this(e.getKey(), e.getValue());
        }

        public String toString() {
            return "key: " + k + ' ' + "value: " + v;
        }
    }

您将能够调用。
List<MyObject> myObjectList = map.entrySet().stream().map(MyObject::new).collect(Collectors.toList());

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接