java avoid arrayList.addAll()

时间:2015-01-30 18:06:53

标签: java arraylist

我有一个存储ArrayList

的缓存Map<String , ArrayList<Candidates>>
ArrayList<Candidates> candidateList = Map.get(someKey);

一旦我有了这个ArrayList候选列表,我需要做一些处理才能返回一个候选者。

为此我创建一个tempList并执行addAll。

 tempList.addAll(candidateList);

然后对tempList进行处理,例如删除与我的条件不匹配的候选项。

但是当我在这个特定的API上执行性能运行和你的快照时,看起来像addAll需要花费大量的时间..

如果我避免进行后期处理,我可以避免做这个addAll。这是我可以在缓存它们之前处理List,但这不适合我的用例

所以我的问题是,如何避免使用addAll并仍然使用相同的算法?

如果我需要在任何方面更清楚,请告诉我。

2 个答案:

答案 0 :(得分:0)

不是添加所有内容然后删除不符合条件的内容,而是翻转逻辑以搜索符合条件的对象。

在类似Java的伪代码中,它看起来像这样:

这就是你现在正在做的事情

// Start by making a copy with everything
List<Candidates> temp = new ArrayList<Candidates>(map.get(myKey));
ListIterator<Candidates> iter = temp.listIterator();
// Remove things that you do not want on your list
while (iter.hasNext()) {
    Candidates item = iter.next();
    if (!fitsMyCriteria(item)) {
        iter.remove();
    }
}

这是你应该做的事情:

// Start with an empty list
List<Candidates> temp = new ArrayList<Candidates>();
for (Candidates item : map.get(myKey)) {
    // Add items that you want on your list
    if (fitsMyCriteria(item)) { // <<== Note that the condition is inverted
        temp.add(item);
        // You can stop the loop in the middle once you
        // have collected enough objects in the temp list:
        if (haveEnoughObjects(temp)) {
            break;
        }
    }
}

答案 1 :(得分:0)

我可能会考虑通过Guava做一些事情和Predicates

ArrayList<Candidates> candidateList = Map.get(someKey);
Predicate<Candidate> filterCriteria = new Predicate<Candidate>(){...}
Iterable<Candidate> filteredView = Iterables.filter(candidateList, filterCriteria);
return Iterables.getFirst(filteredView, null);
上面filter中的

创建了一个视图,因此它是O(1)。 getFirst只会根据需要进行迭代,以找到与Predicate匹配的第一个元素

Iterables.filter

Iterables.filter