Java ConcurrentModificationException; single Thread; without for each loop
<p>I am currently programming a BTree Algorithm.
I have already implemented the functionality to add Numbers to it. As I went to test it, I ran into a ConcurrentModificationException.</p>

<p>I researched the issue and found hints that it mainly is due to two things:</p>

<ol>
<li>Multiple Threads accessing the same List.</li>
<li>Modifing the List while going through it using a for each loop.</li>
</ol>

<p>Neither of these problems occur in my code, so I am completely lost...</p>

<p>I hope you guys can help me!</p>

<p>Code from the "Knoten" class:</p>

<pre><code>public List&lt;Nodes&gt; Childnodes;
public List&lt;Integer&gt; Keys;

private Baum tree;
private Nodes parent;
private boolean isRoot;


public void Add(int number)
{
    int lastSmallerPosition = -1;

    for(int i = 0; i &lt; Keys.size(); i++)
    {
        if(Keys.get(i) &lt; number)
        {
            lastSmallerPosition = i;
        }
        else
        {
            if( Keys.size() &lt; i + 1 &amp;&amp; number == Keys.get(i + 1))
            {
                return; 
            }
            break;
        }
    }

    if(isLeaf())
    {
        Keys.add(lastSmallerPosition + 1, number);

        if(Keys.size() &gt; tree.maxKeys)
        {
            if(isRoot) 
            {
                Nodes k1 = new Nodes(tree, this, false);
                Nodes k2 = new Nodes(tree, this, false);
                k1.Keys.addAll(Keys.subList(0, Keys.size()/2));
                k2.Keys.addAll(Keys.subList(Keys.size()/2 + 1, Keys.size()));
                Childnodes.add(k1);
                Childnodes.add(k2);

                int spareNumber = Keys.get(Keys.size()/2);
                Keys.clear();
                Keys.add(spareNumber);
            }
            else
            {
                if(parent.Keys.size() == tree.maxKeys)
                {
                    List&lt;Integer&gt; list = new ArrayList&lt;Integer&gt;();

                    if(parent.Childnodes.indexOf(this) == 0)
                    {

                        int index = parent.Childnodes.indexOf(this);

                        list.addAll(Keys);
                        list.add(parent.Keys.get(index));
                        list.addAll(parent.Childnodes.get(index + 1).Keys);

                        Keys.clear();
                        parent.Keys.remove(index);
                        parent.Childnodes.remove(index + 1);
                    }
                    else
                    {

                        int index = parent.Childnodes.indexOf(this) - 1; 

                        list.addAll(parent.Childnodes.get(index).Keys);
                        list.add(parent.Keys.get(index));
                        list.addAll(Keys);

                        parent.Childnodes.remove(index);
                        parent.Keys.remove(index);
                        Keys.clear();
                    }

                    int keysPerChildnode = (list.size() - tree.minKeys) / tree.minChilds;
                    int extraKeys = (list.size() - tree.minKeys) % tree.minChilds; 
                    int usedExtraKeys = 0;

                    for(int i = 0; i &lt; tree.minKeys - 1; i ++)
                    {
                        Childnodes.add(new Nodes(tree, this, false));
                        Childnodes.get(i).Keys.addAll(
                                list.subList(i * keysPerChildnode + usedExtraKeys + i, (i + 1) * keysPerChildnode + usedExtraKeys + i));
                        if(usedExtraKeys &lt; ExtraKeys)
                        {
                            Childnodes.get(i).Keys.add(list.get((i + 1) * keysPerChildnode + usedExtraKeys + i));
                            usedExtraKeys++;
                        }

                        Keys.add(list.get((i + 1) * keysPerChildnode + usedExtraKeys + i));
                    }

                    Childnodes.add(new Nodes(tree, this, false));
                    Childnodes.get(tree.minChilds - 1).Keys.addAll(list.subList(list.size() - keysPerChildnode, list.size()));
                }
                else
                {
                    Nodes k = new Nodes(tree,parent,false);
                    k.Keys = Keys.subList(Keys.size() / 2, Keys.size());
                    int NewParentKey  = Keys.get(Keys.size() / 2 - 1);

                    Keys = Keys.subList(0, Keys.size() / 2 - 1);

                    int index = parent.Childnodes.indexOf(this);

                    parent.Keys.add(index, NewParentKey);
                    parent.Childnodes.add(index + 1, k);
                }
            }
        }
    }
    else 
    {
        Childnodes.get(lastSmallerPosition + 1).Add(number);
    }
}
</code></pre>

<p>Exception:</p>

<pre><code>java.util.ConcurrentModificationException
    at java.util.ArrayList$SubList.checkForComodification(Unknown Source)
    at java.util.ArrayList$SubList.size(Unknown Source)
    at Baum.Knoten.Add(Knoten.java:39)
    at Baum.Knoten.Add(Knoten.java:175)
    at Baum.Baum.Add(Baum.java:31)
    at Test.BaumTest.AddTest(BaumTest.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
</code></pre>