3

I wrote this small program to sort arrays. To my understanding it should print 0,1,2.

However, when I run this program I am getting ConcurrentModificationException

    public class Test {
    public static void main(String[] args) {
    List<Double> l1 = new ArrayList<Double>(Arrays.asList(2., 0., 1.));
    List<Double> l2 = l1.subList(0, 3);
    Collections.sort(l1);
    System.out.println(l2.get(0));
    }
}

I am really not sure about the root cause of this exception.

Can somebody help me understand where I am making mistake ?

Note: This issue is not there on JAVA 7 , It would be great if some one also tell why it is there in JAVA 8 and not in JAVA 7

T-Bag
  • 10,916
  • 3
  • 54
  • 118
  • well it works for me – Scary Wombat Jul 20 '17 at 08:38
  • 2
    @ScaryWombat Really? Try this on Java 8 and it indeed throws `ConcurrentModificationException` in `l2.get(0)`. – Jesper Jul 20 '17 at 08:42
  • I am using Java 7 – Scary Wombat Jul 20 '17 at 08:43
  • Mee too using java 8 as well... I am checking JDK code for the same , not sure whats going on internally. – T-Bag Jul 20 '17 at 08:44
  • @Jesper -- are you seeing anything suspicious in this code, to my understanding i did not try any complex it's a straight forward code...:( – T-Bag Jul 20 '17 at 08:46
  • @ScaryWombat-- If you could please let us know why it is not there in Java 7 , as i did not have JDK 7 – T-Bag Jul 20 '17 at 08:49
  • 1
    Debugging shows the modcount on l2 is updated which is the root cause of cuncurrentModificationException. When you do some change on the parent list, it seems to recognize the change in parent list not in the sublist – Anupama Boorlagadda Jul 20 '17 at 08:51
  • @eccentricCoder-- Are you using Java 7 ?? I edited my question and mention the same there as well . This exception is not there in java 7 – T-Bag Jul 20 '17 at 08:57

2 Answers2

7

The API docs of List.subList say:

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. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in progress may yield incorrect results.)

Sorting would indeed change the list in such a way that iterations in progress would lead to incorrect results. The API docs say that what happens in that case is undefined - in practice this means that a ConcurrentModificationException is thrown (at least, when using Java 8), as your code demonstrates.

Jesper
  • 202,709
  • 46
  • 318
  • 350
0

List.sublist returns a view of part of the list, thus you cannot modify the original list. If you want it to work then you need to rewrite sublist to a new list object:

        List<Double> l1 = new ArrayList<>(Arrays.asList(2.0, 0.0, 1.0));
        List<Double> l2 = new ArrayList<>(l1.subList(0, 3));
        Collections.sort(l1);
        System.out.println(l2.get(0));

Otherwise l2 vaues would change after the sort operation, which would be unwanted, and java doe not allow it.

Beri
  • 11,470
  • 4
  • 35
  • 57