IDEA-92308 SmartList: implement List#add(int index, E element)

This commit is contained in:
Yann Cébron
2012-10-02 09:30:01 +02:00
parent 392d9896cf
commit 0ab352287d
2 changed files with 122 additions and 11 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ public class SmartList<E> extends AbstractList<E> {
myElem = e;
}
else if (mySize == 1) {
Object[] array= new Object[2];
Object[] array = new Object[2];
array[0] = myElem;
array[1] = e;
myElem = array;
@@ -61,7 +61,7 @@ public class SmartList<E> extends AbstractList<E> {
int oldCapacity = array.length;
if (mySize >= oldCapacity) {
// have to resize
int newCapacity = oldCapacity * 3 /2 + 1;
int newCapacity = oldCapacity * 3 / 2 + 1;
int minCapacity = mySize + 1;
if (newCapacity < minCapacity) {
newCapacity = minCapacity;
@@ -78,6 +78,39 @@ public class SmartList<E> extends AbstractList<E> {
return true;
}
@Override
public void add(int index, E e) {
if (index < 0 || index > mySize) {
throw new IndexOutOfBoundsException("index= " + index + ". Must be index >= 0 && index < " + mySize);
}
if (mySize == 0) {
myElem = e;
}
else if (mySize == 1 && index == 0) {
Object[] array = new Object[2];
array[0] = e;
array[1] = myElem;
myElem = array;
}
else {
Object[] array = new Object[mySize + 1];
if (mySize == 1) {
array[0] = myElem; // index == 1
}
else {
Object[] oldArray = (Object[])myElem;
System.arraycopy(oldArray, 0, array, 0, index);
System.arraycopy(oldArray, index, array, index + 1, mySize - index);
}
array[index] = e;
myElem = array;
}
mySize++;
modCount++;
}
public int size() {
return mySize;
}
@@ -116,7 +149,7 @@ public class SmartList<E> extends AbstractList<E> {
}
else {
final Object[] array = (Object[])myElem;
oldValue = (E) array[index];
oldValue = (E)array[index];
if (mySize == 2) {
myElem = array[1 - index];
@@ -126,7 +159,7 @@ public class SmartList<E> extends AbstractList<E> {
if (numMoved > 0) {
System.arraycopy(array, index + 1, array, index, numMoved);
}
array[mySize-1] = null;
array[mySize - 1] = null;
}
}
mySize--;
@@ -159,12 +192,16 @@ public class SmartList<E> extends AbstractList<E> {
public E next() {
if (myVisited) throw new NoSuchElementException();
myVisited = true;
if (modCount != myInitialModCount) throw new ConcurrentModificationException("ModCount: "+modCount+"; expected: "+myInitialModCount);
if (modCount != myInitialModCount) {
throw new ConcurrentModificationException("ModCount: " + modCount + "; expected: " + myInitialModCount);
}
return (E)myElem;
}
public void remove() {
if (modCount != myInitialModCount) throw new ConcurrentModificationException("ModCount: "+modCount+"; expected: "+myInitialModCount);
if (modCount != myInitialModCount) {
throw new ConcurrentModificationException("ModCount: " + modCount + "; expected: " + myInitialModCount);
}
clear();
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2012 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,9 +18,7 @@ package com.intellij.util;
import com.intellij.util.containers.EmptyIterator;
import junit.framework.TestCase;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.List;
import java.util.*;
/**
* @author max
@@ -133,4 +131,80 @@ public class SmartListTest extends TestCase {
}
assertTrue("ConcurrentModificationException must be thrown", thrown);
}
public void testAddIndexedNegativeIndex() {
SmartList<Integer> l = new SmartList<Integer>();
try {
l.add(-1, new Integer(1));
}
catch (Exception e) {
return;
}
fail("IndexOutOfBoundsException must be thrown");
}
public void testAddIndexedWrongIndex() {
SmartList<Integer> l = new SmartList<Integer>(new Integer(1));
try {
l.add(3, new Integer(1));
}
catch (Exception e) {
return;
}
fail("IndexOutOfBoundsException must be thrown");
}
public void testAddIndexedEmptyWrongIndex() {
SmartList<Integer> l = new SmartList<Integer>();
try {
l.add(1, new Integer(1));
}
catch (Exception e) {
return;
}
fail("IndexOutOfBoundsException must be thrown");
}
public void testAddIndexedEmpty() {
SmartList<Integer> l = new SmartList<Integer>();
int modCount = 0;
l.add(0, new Integer(1)); assertEquals(++modCount, l.getModificationCount());
assertEquals(1, l.size());
assertEquals(1, l.get(0).intValue());
}
public void testAddIndexedOneElement() {
SmartList<Integer> l = new SmartList<Integer>(new Integer(0));
assertEquals(1, l.size());
int modCount = l.getModificationCount();
l.add(0, new Integer(42)); assertEquals(++modCount, l.getModificationCount());
assertEquals(2, l.size());
assertEquals(42, l.get(0).intValue());
assertEquals(0, l.get(1).intValue());
}
public void testAddIndexedOverOneElement() {
SmartList<Integer> l = new SmartList<Integer>(new Integer(0));
assertEquals(1, l.size());
int modCount = l.getModificationCount();
l.add(1, new Integer(42)); assertEquals(++modCount, l.getModificationCount());
assertEquals(2, l.size());
assertEquals(0, l.get(0).intValue());
assertEquals(42, l.get(1).intValue());
}
public void testAddIndexedOverTwoElements() {
SmartList<Integer> l = new SmartList<Integer>(Arrays.asList(new Integer[]{new Integer(0), new Integer(1)}));
assertEquals(2, l.size());
int modCount = l.getModificationCount();
l.add(1, new Integer(42)); assertEquals(++modCount, l.getModificationCount());
assertEquals(3, l.size());
assertEquals(0, l.get(0).intValue());
assertEquals(42, l.get(1).intValue());
assertEquals(1, l.get(2).intValue());
}
}