我需要创建一个方法,通过比较其中一个字段来返回列表中对象的索引。
我有2个A类和B类,其中包含覆盖Equals()
和HashCode()
方法:
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;
}
所以我的问题是如何为该方法传递通用参数?
答案 0 :(得分:1)
我假设您要与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;
}
然后你就这样使用它:
int index = getObjectIndexFromList(listOfAs, a -> a.field1.equals("foo"));
在这里使用流并不是最佳的,因为您有效地遍历列表两次并检查参数和搜索对象的相等性。使用跟踪当前索引的列表迭代器会更有效:
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;
}
以下是使用中的示例:
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));
}
输出:
长度为5的字符串具有索引3
答案 1 :(得分:0)
如果您有覆盖哈希码并且等于方法...为什么不打电话给&#39; List.indexOf&#39;?
让他们扩展相同的抽象类(我不知道确切的问题,但如果他们在同一个列表中结束很可能他们将结束为家庭)并使用它。
IndexOf使用&#39; equals&#39;找到对象的索引,所以它必须工作...