需要从ArrayLists <Double>的ArrayList中删除元素

时间:2019-06-09 22:49:15

标签: java arraylist

我有处理wav文件的代码,并将双精度值(音频样本)的集合排序到ArrayList中,然后将每个ArrayLists排序到ArrayLists的ArrayList中:

ArrayList<Double> sampleEvent = new ArrayList<Double>();

ArrayList<ArrayList<Double>> EventsCollect = new ArrayList<ArrayList<Double>>();

我有一些代码尝试从集合中删除小于特定大小的ArrayList。

但是,它似乎只做列表的一半,并且没有从集合中删除正确的ArrayList。

请在下面查看我的代码:

for (int loop = 0 ;   loop <  EventsCollect.size(); loop++) {
    if ( EventsCollect.get(loop).size() <  200000) {
         EventsCollect.remove(loop);
    }
}

完成此操作后,ArrayList保留在集合中,大小仅为三位数。

任何有关如何纠正此问题的建议将不胜感激。

2 个答案:

答案 0 :(得分:2)

您的问题是,即使删除了元素,您也会增加循环计数器。这样,您可以跳过循环中的元素。只需更改您的if语句:

    int loop = 0; // loop counter
    while (loop < EventsCollect.size()) {
        if (EventsCollect.get(loop).size() < 200000) {
            EventsCollect.remove(loop);
        }
        else
            loop++;
    }

或者您可以向后遍历ArrayList:

for (int i = EventsCollect.size() - 1; i >= 0; i --){
    if (EventsCollect.get(i).size() > 200000)
        EventsCollect.remove(i);
}

之所以起作用,是因为您将始终在数组中循环一定的时间。如果您查看代码,则EventsCollect.size()会在删除元素时发生变化,因此不会循环 通过每个元素。这应该是您提示出问题的地方。

答案 1 :(得分:0)

在Java 8中,您可以尝试使用lambda表达式删除谓词

    EventsCollect = EventsCollect.stream() 
               //we want to retain only samples with more than 200_000 count
               .filter(sampleEvent -> sampleEvent.size() >=  200_000) 
               //we collect everything that we want back into our EventsCollect list
               .collect(Collectors.toList()); 

作为旁注,您可能希望将EventsCollect重命名为eventsCollect(小写字母e)。

无论如何,仅评估一半条目的原因是因为当您 删除一个条目,所有底部都向上移一位。这样的效果是,新转移的条目的第一项将不会被评估。

假设我们有4个条目,而我目前为1(指向100k)

{230k, 100k, 20k, 122k} 

循环评估并删除100k

{230, 20k, 122k}

现在所有值都上移一个,并且i递增到2(指向122k)。请注意,20k位于1的位置,现在被跳过。循环将评估并删除122k。

{230, 20k}

要用最少的更改来修复代码,您需要进行反向迭代(从最后一个条目到第一个条目)

for (int loop = EventsCollect.size()-1 ;   loop >=0; loop--) {
    if ( EventsCollect.get(loop).size() <  200000) {
         EventsCollect.remove(loop);
    }
}