使用列表获取匹配项索引的有效方法

发布于 2024-11-30 06:12:46 字数 531 浏览 1 评论 0原文

我有两个列表 A 和 B。我想找出 A 中与 listB 元素匹配的元素的索引。像这样的事情:

ArrayList listA = new ArrayList();
listA.add(1);listA.add(2);listA.add(3);listA.add(4);
ArrayList listB = new ArrayList();
listB.add(2);listB.add(4);
ArrayList listC = new ArrayList();
for(int i=0; i<listB.size();i++) {
   int element = listB.get(i);
   for(int j=0; j<listA.size(); j++) {
      if(listA.get(j) == element) listC.add(j);
   }
}

我想这是一种丑陋的做法。查找 A 中与 B 中所有元素匹配的所有索引的最佳方法是什么?我相信集合 api 中存在一个名为 containsAll 的方法 - 不认为它返回匹配的索引。

I've two lists A and B. I'd like to find out indexes of elements in A that match elements of listB. Something like this:

ArrayList listA = new ArrayList();
listA.add(1);listA.add(2);listA.add(3);listA.add(4);
ArrayList listB = new ArrayList();
listB.add(2);listB.add(4);
ArrayList listC = new ArrayList();
for(int i=0; i<listB.size();i++) {
   int element = listB.get(i);
   for(int j=0; j<listA.size(); j++) {
      if(listA.get(j) == element) listC.add(j);
   }
}

I guess that's one ugly way to doing it. What is the best way to finding all the indexes of A that match all elements in B? I believe there exists a method called containsAll in collections api - don't think it returns matching indexes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

盛夏尉蓝 2024-12-07 06:12:46

如果您必须使用ArrayList,您可以从ArrayList 创建一个HashSet。这将使对 contains 的调用 O(1)。创建 HastSet 需要 O(n) 时间。如果您可以从 HashSet 开始,那就最好了。

public static void main(String[] args) 
{
    List listA = new ArrayList();
    listA.add(1);
    listA.add(2);
    listA.add(3);
    listA.add(4);
    List listB = new ArrayList();
    listB.add(2);
    listB.add(4);
    Set hashset = new HashSet(listA);

    for(int i = 0; i < listB.size(); i++) 
    {
        if(hashset.contains(listB.get(i))) 
        {
            listC.add(i);
            System.out.println(i);
        }
    }   
}

If you had to use an ArrayList, you could create a HashSet from the ArrayList. This would make the call to contains O(1). It would take O(n) to create the HastSet. If you could start with a HashSet, that would be best.

public static void main(String[] args) 
{
    List listA = new ArrayList();
    listA.add(1);
    listA.add(2);
    listA.add(3);
    listA.add(4);
    List listB = new ArrayList();
    listB.add(2);
    listB.add(4);
    Set hashset = new HashSet(listA);

    for(int i = 0; i < listB.size(); i++) 
    {
        if(hashset.contains(listB.get(i))) 
        {
            listC.add(i);
            System.out.println(i);
        }
    }   
}
如果没有你 2024-12-07 06:12:46

Guava 库提供了一种方法

"SetView com.google.common.collect.Sets.intersection(Set a, Set b)

,可以提供两个集合中包含的元素,但不提供索引。虽然之后应该很容易获得索引。

The Guava libraries come with a method

"SetView com.google.common.collect.Sets.intersection(Set a, Set b)

that will give the elements contained in both sets, but not the indexes. Although it should be easy to get the indexes afterwards.

隐诗 2024-12-07 06:12:46

简单:

List<Integer> listA = new ArrayList<Integer>();
listA.add(1);
listA.add(2);
listA.add(3);
listA.add(4);

List<Integer> listB = new ArrayList<Integer>();
listB.add(2);
listB.add(4);

List<Integer> listC = new ArrayList<Integer>();

for ( Integer item : listA ) {
    int index = listB.indexOf( item );
    if ( index >= 0 ) {
        listC.add(index);
    }
}

但这仅在没有重复的情况下有效,如果有重复的索引,您必须按照您的方式进行操作,导航完整列表。

编辑

我以为你想要元素,而不是索引,集合不会给你索引,只会给你元素。

Simple:

List<Integer> listA = new ArrayList<Integer>();
listA.add(1);
listA.add(2);
listA.add(3);
listA.add(4);

List<Integer> listB = new ArrayList<Integer>();
listB.add(2);
listB.add(4);

List<Integer> listC = new ArrayList<Integer>();

for ( Integer item : listA ) {
    int index = listB.indexOf( item );
    if ( index >= 0 ) {
        listC.add(index);
    }
}

But this only works if there is no repetition, if there are repeated indexes you have to do it the way you did, navigating the full list.

EDIT

I thought you wanted the elements, not indexes, sets are not going to give you indexes, only the elements.

千里故人稀 2024-12-07 06:12:46

假设没有重复值,为什么不使用 ArrayList.indexOf


public final class ArrayListDemo {
    public static void main(String[]args){
        findIndices(createListA(), createListB());      
    }

    private static final List<Integer> createListA(){
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(3);
        list.add(5);

        return list;
    }

    private static final List<Integer> createListB(){
        List<Integer> list = new ArrayList<Integer>();
        list.add(0);
        list.add(2);
        list.add(3);
        list.add(4);

        return list;
    }

    private static void findIndices(List<Integer> listA, List<Integer> listB){
        for(int i = 0; i < listA.size(); i++){  
            // Get index of object in list b
            int index = listB.indexOf(listA.get(i));

            // Check for match
            if(index != -1){
                System.out.println("Found match:");
                System.out.println("List A index = " + i);
                System.out.println("List B index = " + index);
            }
        }
    }
}

输出

Found match:
List A index = 1
List B index = 2

Assuming there's no duplicate values, why not use ArrayList.indexOf?


public final class ArrayListDemo {
    public static void main(String[]args){
        findIndices(createListA(), createListB());      
    }

    private static final List<Integer> createListA(){
        List<Integer> list = new ArrayList<Integer>();
        list.add(1);
        list.add(3);
        list.add(5);

        return list;
    }

    private static final List<Integer> createListB(){
        List<Integer> list = new ArrayList<Integer>();
        list.add(0);
        list.add(2);
        list.add(3);
        list.add(4);

        return list;
    }

    private static void findIndices(List<Integer> listA, List<Integer> listB){
        for(int i = 0; i < listA.size(); i++){  
            // Get index of object in list b
            int index = listB.indexOf(listA.get(i));

            // Check for match
            if(index != -1){
                System.out.println("Found match:");
                System.out.println("List A index = " + i);
                System.out.println("List B index = " + index);
            }
        }
    }
}

Output

Found match:
List A index = 1
List B index = 2
温柔一刀 2024-12-07 06:12:46

如果列表 A 和列表 B 按相同的顺序排序(我假设升序,但降序也有效),这个问题有一个 O(n) 解决方案。下面是一些(非正式的、未经测试的)代码。当循环退出时,indexMap 应包含列表 A 中与列表 B 中的元素匹配的每个元素的索引以及列表 B 中匹配元素的索引。

  int currentA;
  int currentB;
  int listAIndex = 0;
  int listBIndex = 0;
  Map<Integer, Integer> indexMap = new HashMap<Integer, Integer>();

  currentA = listA.get(listAIndex);
  currentB = listB.get(listBIndex);
  while ((listAIndex < listA.length) && (listBIndex < listB.length))
  {
    if (currentA == currentB)
    {
      indexMap.put(listAIndex, listBIndex);
      ++listAIndex;
    }
    else if (currentA < currentB)
    {
      ++listAIndex;
    }
    else // if (currentA > currentB)
    {
      ++listBIndex;
    }
  }

If list A and list B are sorted in the same order (I'll assume ascending, but descending works as well) this problem has an O(n) solution. Below is some (informal, and untested) code. When the loop exits, indexMap should contain the indices of every element in list A that match an element in list B and the index of the matched element in list B.

  int currentA;
  int currentB;
  int listAIndex = 0;
  int listBIndex = 0;
  Map<Integer, Integer> indexMap = new HashMap<Integer, Integer>();

  currentA = listA.get(listAIndex);
  currentB = listB.get(listBIndex);
  while ((listAIndex < listA.length) && (listBIndex < listB.length))
  {
    if (currentA == currentB)
    {
      indexMap.put(listAIndex, listBIndex);
      ++listAIndex;
    }
    else if (currentA < currentB)
    {
      ++listAIndex;
    }
    else // if (currentA > currentB)
    {
      ++listBIndex;
    }
  }

陌若浮生 2024-12-07 06:12:46

使用 Apache CollectionUtils,有很多选项

Using Apache CollectionUtils, there are plenty of options

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文