比如我使用优先队列给一批数据排序(存在 map 里的 k-v 对),先比较 k 大小,如果相同再比较 v 大小,所以直接在 lambda 里
(a, b)->{
if (a.equals(b)) return map.get(a)-map.get(b);
return a.compareTo(b);
}
访问外部的 map,没有做修改所以编译器没有报错,但是不知道这么做有没有什么隐患,有更好的方法吗?
1
arjen 2020-03-30 23:37:11 +08:00 1
lambda 会隐式让调用的外面容器变成 final 的。
|
2
arjen 2020-03-30 23:39:57 +08:00
如果想达到排序的目的用 TreeMap ?
|
3
mazai 2020-03-30 23:42:29 +08:00 1
函数表达式里面涉及到的所有都应该是无状态的,所以不要存有侥幸心理。
|
4
1194129822 2020-03-31 00:08:27 +08:00 via Android 1
很明显并没有任何隐患,和 java 只有值传递一样,java 只有值捕获,lambda 还是匿名对象都一样,在 lambad 里别说使用对象,就是修改对象的值也是正常操作,只要注意 lamdba 有没有在另外线程执行如果在另外线程执行注意所捕获使用的对象是不是线程安全就好了,想想 list. forEach 里修改 bean 不是很正常操作。而你的功能是什么,选用什么方法实现,就是你自己的事了。stream api 学会了绝对让你爽翻起飞
|
5
zzl22100048 2020-03-31 00:12:33 +08:00 via iPhone 1
直接 stream 操作 hashmap
|
6
rosu 2020-03-31 08:11:55 +08:00 via iPhone 1
可以考虑匿名内部类引用外部类属性的场景。虽然 lambda 和匿名内部类不一样,lambda 是一个闭包,但这不影响引用外部属性的这个场景。
这个引用会让该属性必须使用 final 修饰,因为防止你在闭包内进行修改。同理,你对集合进行修改,需要考虑线程安全问题(也就是闭包内启用另一个线程对 map 进行修改,在 Android 上,你还要考虑闭包内持有 ctx 导致的内存泄漏的问题)。 另一个角度是函数尽量无状态。不要引用超过函数生命周期的变量,这样会使逻辑清晰很多,知道输入就知道输出。 所以 stream api 还是香的。 |
7
siweipancc 2020-03-31 08:38:16 +08:00 via iPhone 1
你可以试试 String 的 threadLocal,能做到类似无状态就行了
|
8
LudwigWS 2020-03-31 10:18:29 +08:00
我觉得没有。另外向楼上各位学习了。
|
9
aguesuka 2020-03-31 12:45:14 +08:00 via Android 2
没有隐患,如果是给 map 排序可以直接用这个 public <K extends Comparable<K>,V extends Comparable<V>> List<K> sortKey(Map<K, V> map, int maxSize){
return map.entrySet().stream() .sorted(mapComparator()) .limit(maxSize) .map(Map.Entry::getKey) .collect(Collectors.toList()); } private <K extends Comparable<K>,V extends Comparable<V>> Comparator<Map.Entry<K, V>> mapComparator(){ return Map.Entry.<K,V>comparingByKey() .thenComparing(Map.Entry.comparingByValue()); } |
10
Aresxue 2020-03-31 15:23:20 +08:00
不涉及修改就不会有问题。。。
|