从ArrayList <customobject> </customobject>查找项目索引的更好方法

时间:2012-11-12 09:44:58

标签: java search arraylist indexof

首先,如果我错了,请纠正我。我想在不使用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循环查找索引不是一个好方法。

6 个答案:

答案 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);

但是搜索的元素是否在最后一个索引中

  • 经典循环:0,066±0,002 ms / op
  • 并行流:0,121±0,023 ms / op
  • 流:0,161±0,024 ms / op

然后,如果您有456976个元素:

  • 经典循环:2,172±0,297 ms / op
  • 并行流:3,145±0,380 ms / op
  • 流:6,081±0,097 ms / op

如您所见,击败循环真的很难!