在Java中,尝试查找ArrayList中一个对象的所有出现次数

21

我有一个Java中的ArrayList,需要查找其中特定对象的所有出现次数。ArrayList.indexOf(Object)方法只能找到一个出现次数,因此我需要其他方法。


“具体对象”是指引用应该是 equals 还是 == - Peter Lawrey
在我的情况下,它是一个整数的ArrayList,因此两者都可以使用。 但实际上是否有只能使用其中一个的情况? - missrg
1
@missrg.. == 操作符仅比较 reference 的值,而不是对象的实际内容。因此,如果您使用 == 比较具有相同值的两个不同对象的引用,则将得到 false 结果,并且使用 equals 方法将得到 true 结果。您可以在互联网上获取关于此主题的大量资源。只需谷歌搜索 - “equals v/s =="。 - Rohit Jain
@Rohit 非常感谢,我还没有想到这个区别 :) - missrg
1
“equals” 可以查看两个对象的内容并比较这些对象的值。如果你使用 == 判断,那么它们是同一个特定对象,而不仅仅是包含相同值的两个对象。这意味着,虽然 new Integer(1234).equals(new Integer(1234)) 成立,但是 new Integer(1234) != new Integer(1234) 因为它们不是同一个对象。 - Peter Lawrey
显示剩余4条评论
6个回答

23

我认为在这方面你不需要太过花哨。以下内容应该能够正常起作用:

static <T> List<Integer> indexOfAll(T obj, List<T> list) {
    final List<Integer> indexList = new ArrayList<>();
    for (int i = 0; i < list.size(); i++) {
        if (obj.equals(list.get(i))) {
            indexList.add(i);
        }
    }
    return indexList;
}

这意味着您将获得一个值列表,这些值都相等。indexOf返回位置(而非值)。 - Peter Lawrey
1
我写的代码将会给你相等对象的索引,如变量名“indexList”所示。 - André C. Andersen

6

我想您需要获取ArrayList中所有与给定对象相同的对象所在槽位的索引。

以下方法可能实现您想要的功能:

public static <T> int[] indexOfMultiple(List<T> list, T object) {
    List<Integer> indices = new ArrayList<>();
    for (int i = 0; i < list.size(); i++) {
        if (list.get(i).equals(object)) {
            indices.add(i);
        }
    }
    // ArrayList<Integer> to int[] conversion
    int[] result = new int[indices.size()];
    for (int i = 0; i < indices.size(); i++) {
        result[i] = indices.get(i);
    }
    return result;
}

它使用equals方法搜索对象,并将当前数组索引保存到具有索引的列表中。在您的问题中,您正在引用indexOf,该方法使用equals方法测试相等性,正如Java文档中所述:

使用equals方法测试相等性,搜索给定参数的第一个出现。


更新

使用Java 8流将变得更加容易:

public static <T> int[] indexOfMultiple(List<T> list, T object) {
    return IntStream.range(0, list.size())
        .filter(i -> Objects.equals(object, list.get(i)))
        .toArray();
}

我提到了 indexOf 方法,是因为我希望有一个类似的方法适用于我的情况,就像对于字符串来说有个 indexOf(char,int) 方法一样。感谢你的答案和解释 :) - missrg

4
这类似于这个答案,只是使用了stream API。
List<String> words = Arrays.asList("lorem","ipsum","lorem","amet","lorem");
String str = "lorem";
List<Integer> allIndexes =
        IntStream.range(0, words.size()).boxed()
                .filter(i -> words.get(i).equals(str))
                .collect(Collectors.toList());
System.out.println(allIndexes); // [0,2,4]

2

遍历所有元素,不要中断循环。

ArrayList的每个元素与您的object进行比较(arrayList.get(i).equals(yourObject))。

如果匹配,则应将索引(i)存储在单独的ArrayList中(arraListMatchingIndexes)。

有时我会这样做“删除所有”,当我需要位置时。

希望这可以帮助您!


2

Do

for (int i=0; i<arrList.size(); i++){
    if (arrList.get(i).equals(obj)){
        // It's an occurance, add to another list
    }
}

希望这有所帮助。

1
@user529543 这取决于情况。有时候,您需要检查对象的某个实例在数组中是否不会出现多次,那么您将使用 ==,如果相等的对象意味着“包含相同的数据”,那么就是 .equals() 版本。 - Jiří

0

Java 8+

如果您想要预计算List中每个值的索引,可以在索引的IntStream上使用Collectors.groupingBy

import java.util.stream.Collectors;
import java.util.stream.IntStream;
//...
List<Integer> list = Arrays.asList(1, 2, 2, 1, 4, 5, 4, 3, 4, 5, 0);
final Map<Integer, List<Integer>> indexMap = IntStream.range(0, list.size()).boxed()
        .collect(Collectors.groupingBy(list::get));
//Map of item value to List of indexes at which it occurs in the original List

然后,要查找特定值的所有索引,请在常量时间内使用 Map 上的 get。
List<Integer> indexes = indexMap.get(value);

演示


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接