简体   繁体   English

有效地从ArrayList获取子列表

[英]Get a sublist from an ArrayList efficiently

My Problem 我的问题


I have a fixed-size ArrayList which contains custom variables. 我有一个固定大小的ArrayList,其中包含自定义变量。 Despite of the ArrayList having a fixed size, sometimes a lot of them will actually be null. 尽管ArrayList具有固定的大小,但有时其中很多实际上都是null。 The thing is that I need to return the ArrayList without the null variables inside it. 问题是我需要返回没有null变量的ArrayList。 One important thing to note: the ArrayList will have all of its non-null items first, and then all of the nulls below them, eg, the elements are not mixed. 需要注意的一件重要事情是: ArrayList首先包含所有非空项,然后是它们下面的所有空值,例如,元素不会混合。 Example: [non-null, non-null, .... null, null, null] 示例:[非null,非null,.... null,null,null]

My workaround 我的解决方法


I though of creating a for-loop that checked (from last to first index) each of the elements inside the ArrayList to determine if it's null or not. 我创建了一个for循环,它检查(从最后到第一个索引)ArrayList中的每个元素,以确定它是否为null。 If is null, then I'd call this code: 如果为null,那么我将调用此代码:

for (i = size-1; i >=0 ; i--) {
    groupList = new ArrayList<>(groupList.subList(0, i));
}

My question 我的问题


If the ArrayList is too big, this method might me particularly slow (or not?). 如果ArrayList太大,这种方法可能会特别慢(或不是?)。 I was wondering if there exists a better, more performance-friendly solution. 我想知道是否存在更好,更友好的解决方案。 AFAIK the .subList method is expensive. AFAIK .subList方法很昂贵。

You can have a variant of binary search , where your custom comparator is: 您可以使用二进制搜索的变体,其中您的自定义比较器是:

  • Both elements are null/not null? 两个元素都为null / not null? They are equal 他们是平等的
  • Only one element is null? 只有一个元素为空? The none null is "smaller". none null是“较小”。

You are looking for the first null element. 您正在寻找第一个null元素。

This will take O(logn) time, where n is the size of the array. 这将花费O(logn)时间,其中n是数组的大小。

However, taking the sublist of the ArrayList that is none null (assuming you are going to copy it to a new list object), is going to be linear time of the elements copied, since you must "touch" each of them. 但是,将ArrayList的子列表设为非null(假设您要将其复制到新的列表对象),将是复制元素的线性时间,因为您必须“触摸”它们中的每一个。

This gives you total time complexity of O(logn + k) , where k is number of non null elements, and n is the size of the array. 这给出了总时间复杂度O(logn + k) ,其中k是非null元素的数量, n是数组的大小。

Following all of your outstanding advices, I modified the original method so that I can take the last (first) ever null item position and call the .subList method just once. 根据你所有出色的建议,我修改了原始方法,以便我可以获取最后一个(第一个)空项目位置并只调用一次.subList方法。 And here it is: 这是:

int lastNullIndex = size - 1;

for (i = lastNullIndex; i >= 0; i--) {
    if (null == groupList.get(i)) {
        lastNullIndex = i;
    } else {
        break;
    }
}

groupList = new ArrayList<>(groupList.subList(0, lastNullIndex));
return groupList;

If you think it can be further modified so as to allow for a better performance, let us know. 如果您认为可以进一步修改以便获得更好的性能,请告诉我们。

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

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