2016-03-01 57 views
5
Map<String, String> map1 = new HashMap<>(); 
map1.put("k1", "v1"); 
map1.put("k2", "v2"); 
map1.put("k3", "v3"); 

Map<String, String> map2 = new HashMap<>(); 
map2.put("v1", "val1"); 
map2.put("v2", "val2"); 
map2.put("v3", "vav3"); 

我想更新MAP1使之具有条目的值的基础上:更新价值观地图等地图中的Java

  • “K1”, “VAL1”
  • “K2”, “值2”,
  • “K3”, “VAL3”

我的解决办法:

for (Map.Entry<String, String> entry : map1.entrySet()) { 
    map1.put(entry.getKey(), map2.get(entry.getValue())); 
} 

有没有更好的方法来做到这一点?

编辑:我使用的Java 7,但想知道是否有在Java中8

+0

不是真的,没有 - 虽然看起来你应该做'map3.put'而不是'map1.put'? –

+1

is this java 8?在这种情况下,流可以帮助你。 – njzk2

+0

另外,当填充'map2'时,你应该做'map2.put'而不是'map1.put'。 – Atri

回答

3

什么更好的方法与Java 8开始,你可以有

map1.replaceAll((k, v) -> map2.get(v)); 

replaceAll(function)将替换地图map1中的所有值以及应用给定函数的结果。在这种情况下,函数只需从map2中检索值。

请注意,此解决方案与初始代码具有相同的问题:如果map2没有相应的映射,则会返回null。在这种情况下,您可能需要拨打getOrDefault以获得默认值。

public static void main(String[] args) { 
    Map<String, String> map1 = new HashMap<>(); 
    map1.put("k1", "v1"); 
    map1.put("k2", "v2"); 
    map1.put("k3", "v3"); 

    Map<String, String> map2 = new HashMap<>(); 
    map2.put("v1", "val1"); 
    map2.put("v2", "val2"); 
    map2.put("v3", "val3"); 

    map1.replaceAll((k, v) -> map2.get(v)); 

    System.out.println(map1); // prints "{k1=val1, k2=val2, k3=val3}" 
} 
+0

对Java 7有任何评论? –

+0

@devツ说实话,除了我提到的情况(地图没有相应的关键字)之外,还没有真正的改进空间。没问题。 – Tunaki

0

在Java中8,你可以这样写:

map1.entrySet() 
    .stream() 
    .map(entry -> new SimpleEntry(entry.getKey(), map2.get(entry.getValue()))) 
    .collect(Collectors.toMap(entry -> entry.getKey(), entry.getValue())); 

不是最好的事情,虽然,但仍然是一个非突变的解决方案。

+0

在Java7中有更好的方法吗? –

1

对于Java 7来说,除了可以做的事之外,您已经可以以最好的方式做到这一点。

我添加了这个答案作为参考,表明对于使用Java 8中的Lambda表达式的情况,这将更糟。看到这个例子:

public static void main(String[] args) { 
    Map<String, String> map1 = new HashMap<>(); 
    final Map<String, String> map2 = new HashMap<>(); 

    for (int i=0; i<100000; i++){ 
     map1.put("k"+i, "v"+i); 
     map2.put("v"+i, "val"+i); 
    } 

    long time; 
    long prev_time = System.currentTimeMillis(); 
    for (Map.Entry<String, String> entry : map1.entrySet()) { 
     map1.put(entry.getKey(), map2.get(entry.getValue())); 
    } 
    time = System.currentTimeMillis() - prev_time; 
    System.out.println("Time after for loop " + time); 


    map1 = new HashMap<>(); 
    for (int i=0; i<100000; i++){ 
     map1.put("k"+i, "v"+i); 
    } 

    prev_time = System.currentTimeMillis(); 
    map1.replaceAll((k, v) -> map2.get(v)); 
    time = System.currentTimeMillis() - prev_time; 
    System.out.println("Time after for loop " + time); 
} 

这种情况的输出将是:

Time after for loop 40 
Time after for loop 100 

第二回路是可变的,但总是比第一个更大。

我不是拉姆达专家,但我想有更多的与它进行处理比第一个方案

一遍又一遍你运行这个测试案例的平原“的foreach”将获得拉姆达几乎总是是第一次“foreach”案件的两倍。