简体   繁体   English

从列表中删除前“n”个元素而不进行迭代

[英]Remove first 'n' elements from list without iterating

I need an efficient way of removing items from list.我需要一种从列表中删除项目的有效方法。 If some condition happens, I need to remove first 'n' elements from a list.如果发生某种情况,我需要从列表中删除前 'n' 个元素。 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.我正在考虑一种方法,通过该方法可以将第 n 个项目作为列表的开头,以便 0-n 个项目将被垃圾收集。 Is it possible?是否有可能?

create subList()创建子subList()

Returns a view of the portion of this list between fromIndex, inclusive, and toIndex, exclusive.返回此列表中 fromIndex(包含)和 toIndex(不包含)之间的部分的视图。 (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. (如果 fromIndex 和 toIndex 相等,则返回列表为空。)返回列表由此列表支持,因此返回列表中的更改会反映在此列表中,反之亦然。 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检查此方法的实现并进行一些测试以确定性能

Jigar Joshi's answer is already contains the solution you need. Jigar Joshi 的回答已经包含您需要的解决方案。 I wanted to add some other stuff.我想添加一些其他的东西。 Calling clear() on the sublist will handle your work, I guess.我想在子列表上调用clear()将处理您的工作。 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();

You can use ArrayList.removeRange(int fromIndex, int toIndex) .您可以使用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.从此列表中删除其索引介于 fromIndex(包含)和 toIndex(不包含)之间的所有元素。 Shifts any succeeding elements to the left (reduces their index).将任何后续元素向左移动(减少它们的索引)。 This call shortens the list by (toIndex - fromIndex) elements.此调用通过 (toIndex - fromIndex) 元素缩短列表。 (If toIndex==fromIndex, this operation has no effect.) (如果 toIndex==fromIndex,则此操作无效。)

If performance is key for you, then I'm not sure using built-in functions from ArrayList is the way to go.如果性能对您来说很重要,那么我不确定使用 ArrayList 中的内置函数是否可行。 I doubt they run faster than O(n) and sadly Java documentation says nothing about that.我怀疑它们的运行速度比 O(n) 快,遗憾的是 Java 文档对此一无所知。 Maybe you should look into some custom made structures like a Rope .也许你应该研究一些定制的结构,比如Rope

If you modify the list frequently, why not use the LinkedList class?如果经常修改列表,为什么不使用 LinkedList 类呢?

If you use the ArrayList class, when deleting an item, the array must always move.如果使用 ArrayList 类,则在删除项目时,数组必须始终移动。

kotlin extentions kotlin 扩展

/**
 * @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 https://www.cnblogs.com/gaojing/archive/2012/06/17/java-list-sublist-caution.html

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 .从从索引n开始到索引m - 1停止的列表中删除m - n元素。

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"根本不可能省略迭代,但可以减少迭代次数甚至使其“恒定”

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM