试图在java中的Arraylist中找到所有出现的对象

Posted

技术标签:

【中文标题】试图在java中的Arraylist中找到所有出现的对象【英文标题】:Trying to find all occurrences of an object in Arraylist, in java 【发布时间】:2012-12-03 17:56:31 【问题描述】:

我在 Java 中有一个 ArrayList,我需要在其中找到特定对象的所有出现。 方法 ArrayList.indexOf(Object) 只找到了一次,所以看来我需要别的东西。

【问题讨论】:

“特定对象”是指引用应该是equals== 在我的例子中,它是一个整数的 ArrayList,所以它们都可以使用。但实际上是否存在只能使用其中一种的情况? @mis-s-rg.. 始终使用equals 比较对象内容。无论是Integer,还是任何其他对象。 @mis-s-rg.. == 运算符只比较reference 的值,而不是对象的实际内容。因此,您比较对具有相同值的两个不同对象的引用,您将使用== 获得错误结果,使用equals 方法获得正确结果。您可以在互联网上获得有关此主题的大量资源。只是谷歌-“等于 v/s ==" 'equals' 可能会查看两个对象的内容并比较这些对象中的值。如果您==,那么它们是相同的特定对象,而不仅仅是恰好包含相同值的两个对象。这意味着虽然new Integer(1234).equals(new Integer(1234))new Integer(1234) != new Integer(1234) 的情况,因为它们不是同一个对象。 【参考方案1】:

我认为你不需要太花哨。以下应该可以正常工作:

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 返回位置(不是值) 我编写的代码将为您提供相等对象的索引,如变量名“indexList”所示。【参考方案2】:

我想您需要获取 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) 一样。感谢您的回答和解释:)【参考方案3】:

这类似于answer,只是使用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]

【讨论】:

【参考方案4】:

遍历所有元素,不要打破循环

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

如果匹配比索引 (i) 应存储到单独的 ArrayList (arraListMatchingIndexes)。

有时,当我也需要职位时,我会以这种方式“全部删除”。

希望对你有帮助!

【讨论】:

【参考方案5】:

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

希望这会有所帮助。

【讨论】:

@user529543 取决于。有时候,你需要检查一个对象的某个实例是否在一个数组中没有多次出现,那么你会使用==,如果相等的对象意味着“包含相同的数据”,那么它就是.equals()版本【参考方案6】:

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

Demo

【讨论】:

以上是关于试图在java中的Arraylist中找到所有出现的对象的主要内容,如果未能解决你的问题,请参考以下文章

在数组(或ArrayList)中搜索由扫描仪用户指定的特定人(值),如果找到,则将该数组中的所有值返回/打印到扫描仪上

如何使用arrayList排序和操作值

Java - 将 ArrayList 中的字符串与 .txt 文件中的所有文本进行比较

从 ArrayList Java 中的 HashMap 键中检索所有值

尝试将数组添加到Java中的ArrayList时出错[重复]

ArrayAdapter 从未使用过 ArrayList null 并且所有项目都出现在单行中