如何使用objects属性作为方法参数来设置映射键?

时间:2016-11-16 06:53:51

标签: java generics lambda

我想有一个将List映射到NavigableMap的方法。方法调用需要一个用作映射键的参数。此参数是列表对象的属性。

这样的话,所以两个电话都没问题:

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

NavigableMap<String, MyObject> stringKeyMap = asNavMap(list, MyObject:.getString());
NavigableMap<Date, MyObject>   dateKeyMap   = asNavMap(list, MyObject::getDate());

我不知道如何定义第二个参数(MyObject::getDate())。我是否必须使用lambda表达式(p -> p.getDate())或谓词或函数?

我试图从http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html的方法8(或类似)推导出一个解决方案,但我不知道该怎么做。

这是我到目前为止所做的:

具体实施:

public class ConcreteConverter {

    public static NavigableMap<Integer, Pair<Integer, String>> asNavMap(List<Pair<Integer, String>> pairs) {
        NavigableMap<Integer, Pair<Integer, String>> navMap = new TreeMap<>();
        for (Pair<Integer, String> pair : pairs) {
            navMap.put(pair.getKey(), pair);
        }
        return navMap;
    }

    public static void main(String[] args) {
        List<Pair<Integer, String>> pairs = new ArrayList<>();
        pairs.add(new Pair<Integer, String>(1, "one"));

        NavigableMap<Integer, Pair<Integer, String>> map = ConcreteConverter.asNavMap(pairs);
    }
}

class Pair<K, V> {
    K   key;
    V   val;
    // constructor, getter, setter
}

这里我卡住了(???是Pair对象的一个​​属性):

public static <K, V> NavigableMap<K, V> asNavMap(List<V> items, ???) {
    NavigableMap<K, V> navMap = new TreeMap<>();
        for (V item : items) {
            navMap.put(???, item);
        }
        return navMap;
}

请注意,我几乎没有经验编写泛型方法或使用lambda函数/接口。

感谢任何帮助。

修改1

正如Nick Vanderhofen所说,我没有澄清对通用解决方案的搜索。

2 个答案:

答案 0 :(得分:1)

您可以使用功能执行此操作。你保留了你想要的代码:

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

NavigableMap<String, MyObject> stringKeyMap = asNavMap(list, MyObject::getKey);

asNavMap方法然后可以使用Function:

private NavigableMap<String,MyObject> asNavMap(List<MyObject> list, Function<MyObject, String> getKey) {
   //the actual mapping goes here
}

您指定的getKey方法可以是MyObject上的简单getter:

public String getKey(){
    return key;
}

或者你可以创建一个静态方法来获得相同的结果:

public static String getKey(MyObject myObject){
    return myObject.getKey();
}

要应用此功能,您只需使用apply方法:

String key = getKey.apply(someObject);

对于实际的映射实现,您可以保留for循环,或者可以使用java 8重写它并重新使用您在收集器中作为参数获得的函数。但是,由于您需要TreeMap,因此语法非常详细:

items.stream().collect(Collectors.toMap(mapper, Function.identity(), (a,b) -> a, TreeMap::new));

答案 1 :(得分:0)

刚刚想出了一个有效的解决方案!

仍在阅读http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html#approach7我尝试使用Function,现在这是我的解决方案:

public static <K, V> NavigableMap<K, V> asNavigableMap(List<V> items, Function<V, K> mapper) {
  NavigableMap<K, V> navMap = new TreeMap<>();
  for (V item : items)
    navMap.put(mapper.apply(item), item);
  return navMap;
}

这些电话有效:

List<Pair<Integer, String>> pairs = new ArrayList<>();
pairs.add(new Pair<Integer, String>(1, "one"));

NavigableMap<Integer, Pair<Integer, String>> navI2P1 = GenericConverter.asNavigableMap(pairs, Pair::getKey);
NavigableMap<String, Pair<Integer, String>> navI2P2 = GenericConverter.asNavigableMap(pairs, Pair::getVal);

我很难理解Function功能界面和应用方法。

感谢任何人!