更容易进行就地更改,修改col1列表而不是创建新列表.这是Java-8解决方案:
public List > merge(List > col1, List col2){
col1.forEach(map -> map.put(TypeId.AMOUNT,
col2.stream()
.filter(e -> e.player_id == (int)map.get(TypeId.PLAYER) &&
e.platform_id == (int)map.get(TypeId.PLATFORM))
.findFirst().map(e -> e.amount).orElse(null)
));
return col1;
}
我想在这种情况下改变col1到位是令人满意的.请注意,即使将结果存储到新列表中,如果修改现有映射也无效.因此,要使结果完全独立于col1,您必须复制所有地图.
另请注意,对于遍历col2的每个col1条目,它不是非常有效,因此复杂性大致为col1.size()* col2.size().在你的情况下,最好扔掉一个Entity类并创建一个只存储platformId和playerId的新类(使用正确实现的equals和hashCode)并将其用作map键:
public static class PlatformAndPlayer {
private final int playerId, platformId;
public PlatformAndPlayer(int playerId, int platformId) {
this.playerId = playerId;
this.platformId = platformId;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + platformId;
result = prime * result + playerId;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PlatformAndPlayer other = (PlatformAndPlayer) obj;
if (platformId != other.platformId)
return false;
if (playerId != other.playerId)
return false;
return true;
}
}
这种方式而不是col2列表,你将有一个地图:
Map col2 = new HashMap<>();
col2.put(new PlatformAndPlayer(1, 1), BigDecimal.valueOf(100));
col2.put(new PlatformAndPlayer(2, 2), BigDecimal.valueOf(200));
col2.put(new PlatformAndPlayer(3, 4), BigDecimal.valueOf(300));
现在您的任务可以轻松有效地解决(即使使用Java 5):
public static List> merge(
List> col1,
Map col2) {
for (Map map : col1) {
map.put(TypeId.AMOUNT, col2.get(new PlatformAndPlayer(
(int) map.get(TypeId.PLAYER), (int) map.get(TypeId.PLATFORM))));
}
return col1;
}