下面两种从列表中获取最新更新记录的方法有什么区别,哪种更好?为什么?
示例- 假定消息列表包含按顺序记录的记录,其中消息对象将是:
Message
{
Integer id ;
String name ;
}
列表中名为“邮件”的值包含
[1 , "a"],[2, "b"],[1 , "b"],[1, "c"]
结果应仅包含这两个记录-
[2, "b"] ,[1, "c"]
解决方案1-
Map<Integer,String> latestMessage = new HashMap<>();
for (Message m : messages) {
latestMessage.put(m.getId(), m.getName());
}
解决方案2-
Map<Integer,String> latestMessage = new HashMap<>();
for (Message m : messages) {
if(!latestMessage.containsKey(m.getId())) {
latestMessage.put(m.getId(), m.getName());
}
else {
latestMessage.replace(m.getId(), m.getName()) ;
}
}
答案 0 :(得分:0)
我会选择前一个(put
),因为您没有使用该消息,甚至没有尝试合并 (由于Java 8和{{3} }方法):
您也不做类似的事情:
Map<String, List<String>> map = ...;
for (Message m : messages)
map.computeIfAbsent(m.getId(), k -> new ArrayList<>()).add(m.getName());
如果是的话,您应该使用Stream
和groupingBy
,如下所示:
messages.stream()
.collect(groupingBy(Message::getId, Message::getName));
回到您的两个用例:
put
也更短,更容易理解:后者(containsKey
+ put
/ replace
)会更难理解(不是 ,虽然如此,但您仍然必须阅读代码才能理解它。)put
的速度应比检查映射是否存在的速度快一点,因为您需要进行更多的操作。我不会为此付出很大的努力,但是您将不得不编写一个基准测试(使用JMH)以比较哪个更好。 TL; DR::除非可以证明containsKey
+ put
/ replace
更好,否则使用看跌期权。
答案 1 :(得分:0)
我尝试了以下代码来查看您所提供的方法之间的性能差异:
public class MapPerformanceTest {
public static void main(String[] args) {
Map<Integer, Integer> map = new HashMap();
// fill the map with 50000 entities
int count = 50000;
for (int i = 0; i < count; i++) {
// value doesn't matter
map.put(i, getRandom(0, count));
}
// fill a set with one million entities
Set<Integer> set = new HashSet();
int setSize = 1000000;
for (int i = 0; i < setSize; i++) {
set.add(getRandom(0, count));
}
// use the set to test performance
long startTime = System.nanoTime(), endTime = 0;
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()) {
int next = iterator.next();
map.put(next, getRandom(0, count));
}
endTime = System.nanoTime();
System.out.println(String.format("PUT: %d", endTime - startTime));
startTime = System.nanoTime();
iterator = set.iterator();
while (iterator.hasNext()) {
int next = iterator.next();
if(!map.containsKey(next)) {
map.put(next, getRandom(0, count));
}
else {
map.replace(next, getRandom(0, count)) ;
}
}
endTime = System.nanoTime();
System.out.println(String.format("REPLACE: %d", endTime - startTime));
}
private static int getRandom(int min, int max) {
return ThreadLocalRandom.current().nextInt(min, max + 1);
}
}
运行上述代码时,它将在控制台上打印以下内容:
PUT: 17171025
REPLACE: 18274190
这意味着第一种方法的性能稍好。