From 0ab352287d58ade3640c60d3b27de49bf4f6dbbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yann=20C=C3=A9bron?= Date: Tue, 2 Oct 2012 09:30:01 +0200 Subject: [PATCH] IDEA-92308 SmartList: implement List#add(int index, E element) --- .../util/src/com/intellij/util/SmartList.java | 51 ++++++++++-- .../com/intellij/util/SmartListTest.java | 82 ++++++++++++++++++- 2 files changed, 122 insertions(+), 11 deletions(-) diff --git a/platform/util/src/com/intellij/util/SmartList.java b/platform/util/src/com/intellij/util/SmartList.java index d3cc2af0e771..0fdc2e9adb51 100644 --- a/platform/util/src/com/intellij/util/SmartList.java +++ b/platform/util/src/com/intellij/util/SmartList.java @@ -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 extends AbstractList { 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 extends AbstractList { 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 extends AbstractList { 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 extends AbstractList { } 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 extends AbstractList { 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 extends AbstractList { 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(); } } diff --git a/platform/util/testSrc/com/intellij/util/SmartListTest.java b/platform/util/testSrc/com/intellij/util/SmartListTest.java index c474e8230931..9c30d9259697 100644 --- a/platform/util/testSrc/com/intellij/util/SmartListTest.java +++ b/platform/util/testSrc/com/intellij/util/SmartListTest.java @@ -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 l = new SmartList(); + try { + l.add(-1, new Integer(1)); + } + catch (Exception e) { + return; + } + fail("IndexOutOfBoundsException must be thrown"); + } + + public void testAddIndexedWrongIndex() { + SmartList l = new SmartList(new Integer(1)); + try { + l.add(3, new Integer(1)); + } + catch (Exception e) { + return; + } + fail("IndexOutOfBoundsException must be thrown"); + } + + public void testAddIndexedEmptyWrongIndex() { + SmartList l = new SmartList(); + try { + l.add(1, new Integer(1)); + } + catch (Exception e) { + return; + } + fail("IndexOutOfBoundsException must be thrown"); + } + + public void testAddIndexedEmpty() { + SmartList l = new SmartList(); + 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 l = new SmartList(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 l = new SmartList(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 l = new SmartList(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()); + } + }