Java 通过传递泛型参数获取ArrayList中的项索引
我需要创建一个方法,通过比较列表中某个对象的字段来返回该对象的索引。 我有两个类A和B,它们被重写了Java 通过传递泛型参数获取ArrayList中的项索引,java,generics,arraylist,Java,Generics,Arraylist,我需要创建一个方法,通过比较列表中某个对象的字段来返回该对象的索引。 我有两个类A和B,它们被重写了Equals()和HashCode()方法,如下所示: int index = getObjectIndexFromList(listOfAs, a -> a.field1.equals("foo")); A类: public class A { private String field1; private String field2; //getters and setters
Equals()
和HashCode()
方法,如下所示:
int index = getObjectIndexFromList(listOfAs, a -> a.field1.equals("foo"));
A类:
public class A {
private String field1;
private String field2;
//getters and setters
@Override
public boolean equals (Object o){
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
A that = (A) o;
return field1.equals(that.field1);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + field1.hashCode();
return result;
}
}
B类:
public class B {
private String field1;
private String field2;
//getters and setters
@Override
public boolean equals (Object o){
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
B that = (B) o;
return field2.equals(that.field2);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + field2.hashCode();
return result;
}
}
在我的主程序中,我需要实现一个通用方法,该方法返回a或B的ArrayList
中某个项的索引
private int getObjectIndexFromList(List<A or B> list, A or B param){
int index;
try{
index = list.indexOf(list.stream().filter(e -> e.equals(param)));
}catch (NoSuchElementException ex){
index = -1;
}
return index;
}
private int getObjectIndexFromList(列表,A或B参数){
整数指数;
试一试{
index=list.indexOf(list.stream().filter(e->e.equals(param));
}捕获(无接触元素例外){
指数=-1;
}
收益指数;
}
所以我的问题是如何为该方法传递泛型参数?如果您有覆盖hashcode和equals方法。。。为什么不直接调用“List.indexOf” 让他们扩展同一个抽象类(我不知道确切的问题是什么,但如果他们的结尾在同一个列表中,他们很可能会成为一个家族)并使用它
IndexOf使用“equals”查找对象的索引,因此它必须工作…我假设您想与
A.field1
、A.field2
、B.field1
或B.field1
进行比较
在这种情况下,您可以使用lambda在流中查找它。像这样:
private <T> int getObjectIndexFromList(List<T> list, Predicate<T> predicate){
int index;
try {
index = list.indexOf(list.stream()
.filter(predicate)
.findFirst()
.get());
} catch (NoSuchElementException ex){
index = -1;
}
return index;
}
不过,在这里使用流并不是最优的,因为您实际上要遍历列表两次,并检查参数和所搜索对象的相等性。使用跟踪当前索引的列表迭代器更有效:
private <T> int getObjectIndexFromList(List<T> list, Predicate<T> predicate){
ListIterator<T> it = list.listIterator();
while (it.hasNext()) {
// Get the item and it's index in the list
int index = it.nextIndex();
T item = it.next();
if (predicate.test(item)) {
// We found it, return the index
return index;
}
}
// We didn't find anything
return -1;
}
private int getObjectIndexFromList(列表列表,谓词){
ListIterator it=list.ListIterator();
while(it.hasNext()){
//获取列表中的项目及其索引
int index=it.nextIndex();
T item=it.next();
if(谓词测试(项目)){
//我们找到了,返回索引
收益指数;
}
}
//我们什么也没找到
返回-1;
}
下面是一个正在使用的示例:
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("foobar");
list.add("fubar");
list.add("Hello World!");
System.out.printf("String with length %s has index %s%n",
5, getObjectIndexFromList(list, s -> s.length() == 5));
}
publicstaticvoidmain(字符串[]args){
列表=新的ArrayList();
列表。添加(“foo”);
列表。添加(“酒吧”);
列表。添加(“foobar”);
列表。添加(“fubar”);
添加(“你好,世界!”);
System.out.printf(“长度为%s的字符串具有索引%s%n”,
5,getObjectIndexFromList(列表,s->s.length()=5);
}
以及输出:
长度为5的字符串具有索引3
A和B之间的关系是什么?如果没有,接口就是你的朋友。你为什么需要这种方法呢?只需使用
list。indexOf(element)
@Eran OP只想传递一个同时满足列表签名的列表。@Eran就像Suresh Atta告诉你的那样,我需要对A和B的列表使用该方法。@SureshAtta你能再解释一下在这种情况下如何使用接口吗?我预先设置了第二个解决方案,因为它更优化。但是我只想知道为什么a->a.equals(tmpA)
即使在重写equals()
和HashCode()
methods之后仍然返回-1,而不必在可执行示例中看到所有代码。您确定在equals
中签入的所有字段确实相等吗?我正在记录项.getFieldA(),其值为equal使用调试器运行它,查看哪一行导致equals返回false,问题不在于如何找到项目索引的算法,而是如何在每次需要调用此方法时传递不同类型的列表和项目。