我在外部和内部循环中都使用了一个映射,并且我需要在内部循环中删除该映射中的一个条目,以使删除的条目不再在外部或内部循环中进行迭代。
我尝试在内部迭代器上使用remove(),但是在外部循环上进一步迭代时确实会导致异常。
Map<String, String> testMap = new HashMap<>();
testMap.put("A", "AAA");
testMap.put("B", "BBB");
testMap.put("C", "CCC");
testMap.put("D", "DDD");
for(Iterator<Map.Entry<String, String>> it = testMap.entrySet().iterator(); it.hasNext();) {
Map.Entry<String, String> outerEntry = it.next();
for(Iterator<Map.Entry<String, String>> it1 = testMap.entrySet().iterator(); it1.hasNext();) {
Map.Entry<String, String> innerEntry = it1.next();
if(!outerEntry.getKey().equals(innerEntry.getKey()) && !innerEntry.getKey().equals("D")) {
// it1.remove();
// remove entries "B" and "C" from testMap so that the next iteration in outer loop is "D"
// also I don't require the entries "B" and "C" in the inner loop once they are deleted
}
}
}
在给定的代码中,必须在外循环的第一次迭代中从testMap中删除条目“ B”和“ C”。外循环的下一个迭代器应为“ D”。
该代码的目的是收集具有相同值的Map条目。
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args)
{
Map<String, Map<String, List<String>>> resultMap = new HashMap<>();
Map<String, List<String>> testMap = new HashMap<>();
testMap.put("A", new ArrayList<>(Arrays.asList("AAA", "CCC", "BBB")));
testMap.put("B", new ArrayList<>(Arrays.asList("AAA", "BBB", "CCC")));
testMap.put("C", new ArrayList<>(Arrays.asList("CCC")));
testMap.put("D", new ArrayList<>(Arrays.asList("DDD")));
testMap.put("E", new ArrayList<>(Arrays.asList("DDD")));
testMap.put("F", new ArrayList<>(Arrays.asList("AAA", "BBB", "CCC")));
// process testMap in a way that resultMap contains
// <A, <G1, [AAA, BBB, CCC]>>
// <B, <G1, [AAA, BBB, CCC]>>
// <C, <G2, [CCC]>>
// <D, <G3, [DDD]>>
// <E, <G3, [DDD]>>
// <F, <G1, [AAA, BBB, CCC]>>
// here G1, G2, G3 are groups that are created which represents testMap entries that have same values.
// in resultMap, the order of [AAA, BBB, CCC] doesn't matter
String gName = "G";
int gId = 0;
for(Map.Entry<String, List<String>> entry : testMap.entrySet()) {
if (resultMap.containsKey(entry.getKey())) {
continue;
}
++gId;
String group = gName + String.valueOf(gId);
Set<String> entryValuesSet = new HashSet<>(entry.getValue());
Map<String, List<String>> groupEntries = new HashMap<>();
groupEntries.put(group, entry.getValue());
Set<String> groupSet = testMap.entrySet().stream().filter(e -> !resultMap.containsKey(e.getKey()) && new HashSet(e.getValue()).equals(entryValuesSet)).map(f -> f.getKey()).collect(Collectors.toSet());
// here is my problem.
// Even though in the first iteration (entry "A") itself, entries "A", "B", "F" have assigned a group
// they are still being checked on further iterations (entries "C", "D") and need a filter condition to exclude
// which are really unnecessary checks if I could just delete those entries
for (String g : groupSet) {
resultMap.put(g, groupEntries);
}
}
System.out.println(resultMap);
}
}
是否可以删除已经在组中分配的testMap中的条目,从而避免不必要的检查?
答案 0 :(得分:0)
继@Jordans评论之后:
当前代码存在的问题是,内循环的第一次迭代会删除B
和C
,然后外循环会在下一个遇到B
的情况下被删除
您可以通过使用列表来确定要删除的条目,如下所示。
Map<String, String> testMap = new HashMap<>();
testMap.put("A", "AAA");
testMap.put("B", "BBB");
testMap.put("C", "CCC");
testMap.put("D", "DDD");
System.out.println(testMap);
List<Map.Entry<String, String>> removedInnerEntries = new ArrayList<>();
for(Map.Entry<String, String> outer : testMap.entrySet()){
if(removedInnerEntries.contains(outer))
continue;
System.out.println("OuterLoop:" + outer);
for(Map.Entry<String, String> inner : testMap.entrySet()) {
System.out.println("InnerLoop:" + inner);
if (!outer.getKey().equals(inner.getKey()) &&
!inner.getKey().equals("D") &&
!removedInnerEntries.contains(inner)) {
System.out.println(" Remove :" + inner);
removedInnerEntries.add(inner);
}
}
}
removedInnerEntries.forEach(e -> testMap.remove(e.getKey(), e.getValue()));
System.out.println(testMap);
但是,如果运行此命令,您会发现这与在上一次迭代A
上删除不完全正确,因为它未能通过内部循环的第一个条件!outer.getKey().equals(inner.getKey())
,因此您也将需要解决这个问题。
或者,您可以创建自己的迭代器来执行此操作。