我想有一个将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所说,我没有澄清对通用解决方案的搜索。
答案 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
功能界面和应用方法。
感谢任何人!