public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); Scanner sc=new Scanner(br); int T=Integer.parseInt(sc.nextLine()); Map<String, List<Integer>> scores=new HashMap<>(); List<Integer> zeros= new ArrayList<>(); for (int t=0; t<T; t++) { //Begin solving here String key=sc.next(); int score = Integer.parseInt(sc.nextLine().trim()); zeros.add(0); if (scores.containsKey(key)) { int curScore = scores.get(key).get(t-1); scores.get(key).add(curScore + score); } else { scores.put(key, zeros); scores.get(key).set(t, score); }
The code above is buggy in that it produces the wrong result; the “zeros” list is aliased everywhere (I think; I’m learning Java)
if (scores.containsKey(key)) { int curScore = scores.get(key).get(t-1); //This line throws the exception; line 27 on my editor scores.get(key).add(curScore + score); } else { scores.put(key, zeros.subList(0, t+1)); //Here I fix the aliasing bug scores.get(key).set(t, score); }
Test input
2 mike 5 mike 2
Exception thrown
Exception in thread "main" java.util.ConcurrentModificationException at java.base/java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1415) at java.base/java.util.ArrayList$SubList.get(ArrayList.java:1150) at div2.A.main(A.java:27)
Advertisement
Answer
The problem is a misconception around this line:
scores.put(key, zeros.subList(0, t+1)); //Here I fix the aliasing bug
You’re not “fixing the aliasing bug”. The method subList
does not return a new list. As the documentation says, “The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa.”
It then says: “The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via the returned list.”
You’re structurally modifying the list, since you add an element (zeros.add(0)
) to the original list after creating the sublist.
You should create a new list instead:
scores.put(key, new ArrayList<>(zeros.subList(0, t+1)));