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

时间:2018-12-12 19:24:45

标签: java constructor java-8 mapping java-stream

假设我有以下代码:

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

我有一个MyObject Constructor,它带有两个String类型的参数。 我希望能够做到这一点,但我不能。 我知道我可以e -> new MyObject(e.getKey(), e.getValue()),但更喜欢MyObject::new

类似的代码适用于Set<String>类的一个参数构造函数,适用于List<String>MyObject

4 个答案:

答案 0 :(得分:9)

使用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方法的类。

答案 1 :(得分:3)

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

我有一个MyObject构造函数,它带有两个String类型的参数。我希望能够做到这一点,但我不能。

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

答案 2 :(得分:2)

添加Map.Entry构造函数

import suds.bindings
from robot.libraries.BuiltIn import BuiltIn, RobotNotRunningError

class SudsLibraryExtension(object):
    """
    Extension on the SudsLibrary

    """
    ROBOT_LIBRARY_SCOPE = 'GLOBAL'    
    ROBOT_LIBRARY_VERSION = 1.0

    def __init__(self, LibraryName='SudsLibrary'):
        """SudsLibraryExtension can be imported with an optional argument.
        - ``LibraryName``:
          Default value for `LibraryName` is SudsLibrary if not given.
          The name can by any Library Name that implements or extends the
          SudsLibraryExtension.
        """        
        try:
            self.SudsLibrary = BuiltIn().get_library_instance(LibraryName)

        # This is useful for when you run Robot in Validation mode or load
        # the library in an IDE that automatically retrieves the documen-
        # tation from the library. 
        except RobotNotRunningError:
            pass

    def set_binding(self, binding, url):
        """Set Binding can be used to add a binding to the message.

        Example    Set Binding     SOAP-ENV    http://www.w3.org/2003/05/soap-envelope
        """
        suds.bindings.binding.envns = (binding, url)

您将可以致电

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;
        }
    }

答案 3 :(得分:1)

构造函数的问题是它定义了两个参数,而Function#apply要求的Stream#map只接受一个。

您可以为MyObject编写静态工厂方法

class MyObject {
    public static MyObject of(Map.Entry<String, String> e) {
        return new MyObject(e.getKey(), e.getValue());
    }
}

并像

一样引用它
map(MyObject::of)

在执行此操作之前,请问自己是否值得在普通处理链中某个漂亮的行中使用新的构造函数或实用程序方法。