首先,如果我错了,请纠正我。我想在不使用For循环的情况下从ArrayList<CustomType>
找到Item的索引(即String值)。
POJO:
id;
name;
代码:
ArrayList<POJO> list = new ArrayList<POJO>;
//Lots of data added to these list...
现在我想从arraylist中找到特定名称的id,而不使用下面的for循环。
String id = null;
// TODO Auto-generated method stub
for (int i = 0; i < list.size(); i++) {
if("ABCD".equalsIgnoreCase(list.get(i).getName())) {
id = list.get(i).getId();
break;
}
}
理想情况下,我不想实现For循环,因为在某些情况下我在List中有500多个数据并且使用For循环查找索引不是一个好方法。
答案 0 :(得分:12)
您可以使用list.indexOf()
,但为了使其有效,您需要覆盖equals
的{{1}}和hasCode
。
默认情况下,如果两个对象具有相同的引用,则它们将被视为相等。您可以覆盖POJO
以适用于您的案例:
equals
覆盖等于建议您覆盖public boolean equals(Object o) {
if (!(o instanceof POJO)) {
return false;
}
POJO other = (POJO) o;
return name.equalsIgnoreCase(other.getName());
}
。例如:
hashCode
答案 1 :(得分:4)
以这种方式查找元素,其中复杂性将为您提供BIG-O(n)。我认为如果你映射会给你更好的结果。
HashMap
会是更好的选择。 - 复杂性为O(1)。
答案 2 :(得分:2)
如果您需要搜索字符串值,则应使用HashMap
代替ArrayList
。
答案 3 :(得分:2)
您可以使用List.indexOf()
- 但您必须确保也覆盖POJO.equals()
- (并且作为约定的一部分 - 也是hashCode()
。< / p>
请注意 - 结果将是O(n)
- 另一种方法是使用排序数组(POJO[]
)并使用Arrays.binarySearch()
或{ {3}} / Set
如果您使用数组binarySearch()
- 您必须确保POJO
也实施Map
请注意,对于静态数据(您的列表不会经常更改/根本没有更改) - 尽管数组和binarySearch()
“更差”,然后{@ 1}}就大O符号而言,在实践中 - 它通常要快得多,特别是对于相对较短的列表。
就big-O表示法而言,基于哈希的解决方案提供HashSet
平均案例访问。
答案 4 :(得分:2)
感谢大家的善意和快速回复。但特别感谢Joachim Sauer。你绝对正确 500个元素不是很多,这个循环很可能对代码的性能没有实际影响(即使它是低效的)。即使我尝试了5000个元素并且仍然没有对表现产生负面影响。
再次感谢大家,感谢您的评论Joachim Sauer。
答案 5 :(得分:0)
为回答这个问题,我与JMH发起了基准测试。
经典循环是做到这一点的有效方法。
我使用的DATA_ARRAY
包含17576个元素,搜索到的元素位于索引7733。
使用经典循环-0,030±0,001 ms / op:
int i = 0;
for (String str : DATA_ARRAYLIST) {
if (str.equals("lll")) break;
i++;
}
使用indexOf并覆盖equals方法:0,030±0,002 ms / op
MY_DATA_ARRAYLIST.indexOf("lll");
使用数据范围:0,082±0,003 ms / op
OptionalInt integer = IntStream.range(0, DATA_ARRAYLIST.size())
.filter(i -> DATA_ARRAYLIST.get(i).equals("lll"))
.findFirst();
找到流后使用indexOf:0,074±0,008 ms / op
String result = DATA_ARRAYLIST.stream().filter(e -> e.equals("lll")).findFirst().get();
DATA_ARRAYLIST.indexOf(result);
在找到parallelStream后使用indexOf:0,087±0,023 ms / op
String result = DATA_ARRAYLIST.parallelStream().filter(e -> e.equals("lll")).findFirst().get();
DATA_ARRAYLIST.indexOf(result);
但是搜索的元素是否在最后一个索引中
然后,如果您有456976个元素:
如您所见,击败循环真的很难!