30

I need an efficient way of removing items from list. If some condition happens, I need to remove first 'n' elements from a list. Can some one suggest the best way to do this? Please keep in mind: performance is a factor for me, so I need a faster way than itterating. Thanks.

I'm thinking of a way through which the 'n'th item can be made as the starting of the list so that the 0-n items will get garbage collected. Is it possible?

Lukas Eder
  • 211,314
  • 129
  • 689
  • 1,509
Eldhose M Babu
  • 14,382
  • 8
  • 39
  • 44
  • Nice answer here : http://stackoverflow.com/a/10798153/1579667 , with a LinkedList it is `list.subList(from, to).clear();` – Benj Jan 25 '17 at 16:43

8 Answers8

25

create subList()

Returns a view of the portion of this list between fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the returned list is empty.) The returned list is backed by this list, so changes in the returned list are reflected in this list, and vice-versa. The returned list supports all of the optional list operations supported by this list.

Check implementation of this method and make some tests to determine performance

jmj
  • 237,923
  • 42
  • 401
  • 438
  • 1
    Your answer is good, but I really doubt this runs faster than O(n). – tu_ru Sep 17 '12 at 09:46
  • 1
    @tu_ru It depends on the characteristics of the underlying list, about which you have provided zero information. – user207421 Sep 17 '12 at 10:11
  • @EJP Yes, but there are only two possibilities, aren't they? Either we have a linked list in which case deletion is fast, but to actually get to the n-th element, one has to iterate through the list which takes O(n) time, or an array-based list where we can get to the n-th element in constant time, but removing elements involves O(n) operations. That's why he should look into custom data structures that can do both things efficiently. – tu_ru Sep 17 '12 at 10:28
13

Jigar Joshi's answer is already contains the solution you need. I wanted to add some other stuff. Calling clear() on the sublist will handle your work, I guess. But it might be using iteration in the background, I'm not sure. Example script for your use:

ArrayList<Integer> list = new ArrayList<Integer>();
ArrayList<Integer> subList = (ArrayList<Integer>) list.subList(0, 9);
subList.clear();
Juvanis
  • 25,802
  • 5
  • 69
  • 87
9

A single line solution is:

 list.subList(n, m).clear();

Removes m - n elements from the list starting at index n stopping at index m - 1.

8

You can use ArrayList.removeRange(int fromIndex, int toIndex) .

Quoting the documentation:

Removes from this list all of the elements whose index is between fromIndex, inclusive, and toIndex, exclusive. Shifts any succeeding elements to the left (reduces their index). This call shortens the list by (toIndex - fromIndex) elements. (If toIndex==fromIndex, this operation has no effect.)

Santosh
  • 17,667
  • 4
  • 54
  • 79
  • 13
    `removeRange` has protected access on `ArrayList` – dcernahoschi Sep 17 '12 at 09:20
  • 1
    You can always subclass it, and override its `removeRange` method,calling the super-class method in turn. This will be faster as its indexed based and internally uses `System.arraycopy` call to carry out the operation. – Santosh Sep 17 '12 at 09:28
6

If performance is key for you, then I'm not sure using built-in functions from ArrayList is the way to go. I doubt they run faster than O(n) and sadly Java documentation says nothing about that. Maybe you should look into some custom made structures like a Rope.

tu_ru
  • 267
  • 1
  • 7
  • I'm also thinking in that way... These above methods "sublist()" and ArrayList.range every thing is doing some itterations in the backgroud. so there is no benefit I guess. I'm thinking of a way through which the 'n'th item can be made as the starting of the list so that the 0-n items will get garbage collected.] – Eldhose M Babu Sep 17 '12 at 09:33
  • I'm not sure if it can be made that way. Notice that to make use of efficient linked list deletion, you must get to the n-th element first. Deletion alone may take constant time (well, sort of), but 'getting to the n'th element' part will still take O(n) time. As I said, in this case it's best to look at different structures such as ropes. – tu_ru Sep 17 '12 at 09:44
3

If you modify the list frequently, why not use the LinkedList class?

If you use the ArrayList class, when deleting an item, the array must always move.

naugler
  • 1,060
  • 10
  • 31
Daniel
  • 79
  • 3
3

kotlin extentions

/**
 * @param length remove index [0..length)
 */
fun <E> MutableList<E>.removeFirst(length: Int): MutableList<E> {
    if (length in 1..size) {
        subList(0, length).clear()
    }
    return this
}

/**
 * @param length remove index [(size - length)..size)
 */
fun <E> MutableList<E>.removeLast(length: Int): MutableList<E> {
    if (length in 1..size) {
        subList(size - length, size).clear()
    }
    return this
}

test

package hello                      //  可选的包头

/**
 * @param length remove index [0..length)
 */
fun <E> MutableList<E>.removeFirst(length: Int): MutableList<E> {
    if (length in 1..size) {
        subList(0, length).clear()
    }
    return this
}

/**
 * @param length remove index [(size - length)..size)
 */
fun <E> MutableList<E>.removeLast(length: Int): MutableList<E> {
    if (length in 1..size) {
        subList(size - length, size).clear()
    }
    return this
}

fun main(args: Array<String>) {    // 包级可见的函数,接受一个字符串数组作为参数
   println("Hello World!")         // 分号可以省略

   val list = mutableListOf<String>("0","1","2","3","4","5","6","7")

    println(list)
    list.removeFirst(2)
    println(list)
    list.removeLast(2)
    println(list)

}

Hello World!
[0, 1, 2, 3, 4, 5, 6, 7]
[2, 3, 4, 5, 6, 7]
[2, 3, 4, 5]

refrerence

https://www.cnblogs.com/gaojing/archive/2012/06/17/java-list-sublist-caution.html

Michael Mao
  • 433
  • 5
  • 9
0

consider using Skip Lists, that will give you good performance if you will make number of dropped items aliquot to interval

it is not possible to omit iterations at all, but it is possible to reduce number of iterations or even make it "constant"

jdevelop
  • 12,176
  • 10
  • 56
  • 112