我有一个存储ArrayList
的缓存Map<String , ArrayList<Candidates>>
ArrayList<Candidates> candidateList = Map.get(someKey);
一旦我有了这个ArrayList候选列表,我需要做一些处理才能返回一个候选者。
为此我创建一个tempList并执行addAll。
tempList.addAll(candidateList);
然后对tempList进行处理,例如删除与我的条件不匹配的候选项。
但是当我在这个特定的API上执行性能运行和你的快照时,看起来像addAll需要花费大量的时间..
如果我避免进行后期处理,我可以避免做这个addAll。这是我可以在缓存它们之前处理List,但这不适合我的用例
所以我的问题是,如何避免使用addAll并仍然使用相同的算法?
如果我需要在任何方面更清楚,请告诉我。
答案 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
匹配的第一个元素