Java 使用列表获取匹配项索引的有效方法
我有两个列表A和B。我想找出A中与listB元素匹配的元素的索引。大概是这样的:Java 使用列表获取匹配项索引的有效方法,java,collections,arraylist,Java,Collections,Arraylist,我有两个列表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.
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);
}
}
ArrayList listA=new ArrayList();
增加(1);增加(2);增加(3);增加(4);
ArrayList listB=新的ArrayList();
清单b.添加(2);清单b.添加(4);
ArrayList listC=新的ArrayList();
对于(inti=0;iSimple:
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);
}
}
List listA=new ArrayList();
增加(1);
增加(2);
增加(3);
增加(4);
List listB=新的ArrayList();
清单b.添加(2);
清单b.添加(4);
List listC=new ArrayList();
对于(整数项:listA){
int index=listB.indexOf(项目);
如果(索引>=0){
添加(索引);
}
}
但这仅在没有重复的情况下才有效,如果有重复的索引,则必须像以前那样导航整个列表
编辑
我以为你想要的是元素,不是索引,集合不会给你索引,只有元素。假设没有重复的值,为什么不使用
Guava库提供了一种方法
"SetView com.google.common.collect.Sets.intersection(Set a, Set b)
这将给出两个集合中包含的元素,但不会给出索引。尽管之后应该很容易获得索引。使用,有很多选项如果必须使用数组列表
,可以从数组列表
创建哈希集
。这将调用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);
}
}
}
publicstaticvoidmain(字符串[]args)
{
List listA=new ArrayList();
增加(1);
增加(2);
增加(3);
增加(4);
List listB=新的ArrayList();
清单b.添加(2);
清单b.添加(4);
Set hashset=新hashset(listA);
对于(int i=0;i
如果列表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;
}
}
int current a;
int-currentB;
int listAIndex=0;
int listBIndex=0;
Map indexMap=newhashmap();
currentA=listA.get(listAIndex);
currentB=listB.get(listBIndex);
而((listAIndexcurrentB)
{
++listBIndex;
}
}
列表是否可以包含重复的值?是否存在集合不起作用的原因?我猜它们不能..包含重复的值。我需要元素的索引-使用集合将与使用列表相同?使用contains()的时间复杂度是多少方法?其次,我需要索引,而不是这些索引中的实际元素。contains是O(n)操作。这是线性复杂度。查找索引如何?更新答案和问题标题,以显示索引而不是匹配项。第三方库用于这样简单的事情?@Jay,是的,这是Java…我可以想象如果我在C#world进行更改,我可以编写一行非常简单的LINQ…contains()没有那么高的效率。所以..除了O(n)的最小复杂性之外,没有其他方法可以做到这一点?对于列表a中的每个元素,循环列表a中的n个元素和循环列表B中的m个元素的效率似乎低于O(n)对我来说,当你创建一个HashSet时,会循环列表A中的n个元素?@DwB-contains对于一个HashSet来说是有效的,它的O(1)get
以恒定时间运行(即O(1)),而indexOf
以线性时间运行(即O(n))for循环意味着——你将使用A中元素数的数倍进行索引——你认为SwDevMan81下面的答案更有效吗?如果列表没有排序,我猜——排序所涉及的额外复杂性将增加到总复杂性,不是吗?复杂性将成为排序与O(n)中效率最低的一个.这通常意味着这类产品的复杂性。
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);
}
}
}
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;
}
}