我有一个对象,Pet,其中一个功能是检索它的名字。
public class pet{
private String petName;
private int petAge;
public pet(String name, int age){
petName = name;
petAge = age;
}
public String getName(){
return petName;
}
public int getAge(){
return petAge;
}
}
然后我有一个 ArrayList,其中包含宠物的集合,如下面的代码所示:
import java.util.ArrayList;
pet Dog = new pet("Orio", 2);
pet Cat = new pet("Kathy", 4);
pet Lion = new pet("Usumba", 6);
ArrayList<pet> pets = new ArrayList<>();
pets.add(Dog);
pets.add(Cat);
pets.add(Lion;
我想知道如何检索 ArrayList 中的索引或具有我需要的名称的对象。那么,如果我想知道乌松巴的年龄,我该怎么做?
注意:这不是我的实际代码,它只是用来让我更好地解释我的问题。
到目前为止,我有以下内容,但我想知道是否有更好或更有效的方法
public int getPetAge(String petName){
int petAge= 0;
for (pet currentPet : pets) {
if (currentPet.getName() == petName){
petAge = currentPet.getAge();
break;
}
}
return petAge;
}
您不能将
indexOf()
用于此目的,除非您滥用 equals()
方法的目的。
对
for
变量使用 int
循环,从 0
迭代到列表的长度。
在循环内,比较第 i 个元素的名称,如果它等于您的搜索词,则您已找到它。
类似这样的:
int index = -1;
for (int i = 0; i < pets.length; i++) {
if (pets.get(i).getName().equals(searchName)) {
index = i;
break;
}
}
// index now holds the found index, or -1 if not found
如果你只是想找到对象,则不需要索引:
pet found = null;
for (pet p : pets) {
if (p.getName().equals(searchName)) {
found = p;
break;
}
}
// found is now something or null if not found
正如其他人已经指出的,您不能直接使用 indexOf() 来实现此目的。在某些情况下这是可能的(lambda、重写 hashCode/equals 等),但这通常是一个坏主意,因为它会滥用另一个概念。
以下是我们如何在现代 Java 中做到这一点的一些示例: (由于索引主题已经得到很好的回答,这仅处理直接对象返回)
package stackoverflow.filterstuff;
import java.util.ArrayList;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Predicate;
public class FilterStuff {
public static void main(final String[] args) {
final Pet dog = new Pet("Orio", 2); // again, naming conventions: variable names start with lowercase letters
final Pet cat = new Pet("Kathy", 4);
final Pet lion = new Pet("Usumba", 6);
final ArrayList<Pet> pets = new ArrayList<>();
pets.add(dog);
pets.add(cat);
pets.add(lion);
try {
simpleOldLoop(pets);
} catch (final Exception e) {
e.printStackTrace(System.out);
}
try {
simpleLoopWithLambda(pets);
} catch (final Exception e) {
e.printStackTrace(System.out);
}
try {
filterStreams(pets);
} catch (final Exception e) {
e.printStackTrace(System.out);
}
try {
filterStreamsWithLambda(pets);
} catch (final Exception e) {
e.printStackTrace(System.out);
}
}
private static void simpleOldLoop(final ArrayList<Pet> pPets) {
System.out.println("\nFilterStuff.simpleOldLoop()");
System.out.println("Pet named 'Kathy': " + filterPet_simpleOldLoop(pPets, "Kathy"));
System.out.println("Pet named 'Hans': " + filterPet_simpleOldLoop(pPets, "Hans"));
}
private static Pet filterPet_simpleOldLoop(final ArrayList<Pet> pPets, final String pName) {
if (pPets == null) return null;
for (final Pet pet : pPets) {
if (pet == null) continue;
if (Objects.equals(pet.getName(), pName)) return pet;
}
return null;
}
private static void simpleLoopWithLambda(final ArrayList<Pet> pPets) {
System.out.println("\nFilterStuff.simpleLoopWithLambda()");
System.out.println("Pet named 'Kathy': " + filterPet_simpleLoopWithLambda(pPets, (pet) -> Boolean.valueOf(Objects.equals(pet.getName(), "Kathy"))));
System.out.println("Pet named 'Hans': " + filterPet_simpleLoopWithLambda(pPets, (pet) -> Boolean.valueOf(Objects.equals(pet.getName(), "Hans"))));
}
private static Pet filterPet_simpleLoopWithLambda(final ArrayList<Pet> pPets, final Function<Pet, Boolean> pLambda) {
if (pPets == null) return null;
for (final Pet pet : pPets) {
if (pet == null) continue;
final Boolean result = pLambda.apply(pet);
if (result == Boolean.TRUE) return pet;
}
return null;
}
private static void filterStreams(final ArrayList<Pet> pPets) {
System.out.println("\nFilterStuff.filterStreams()");
System.out.println("Pet named 'Kathy': " + filterPet_filterStreams(pPets, "Kathy"));
System.out.println("Pet named 'Hans': " + filterPet_filterStreams(pPets, "Hans"));
}
private static Pet filterPet_filterStreams(final ArrayList<Pet> pPets, final String pName) {
return pPets.stream().filter(p -> Objects.equals(p.getName(), pName)).findAny().get();
}
private static void filterStreamsWithLambda(final ArrayList<Pet> pPets) {
System.out.println("\nFilterStuff.filterStreamsWithLambda()");
System.out.println("Pet named 'Kathy': " + filterPet_filterStreams(pPets, p -> Objects.equals(p.getName(), "Kathy")));
final Predicate<Pet> pdctHans = p -> Objects.equals(p.getName(), "Hans"); // we can also have 'lambda expressions' stored in variables
System.out.println("Pet named 'Hans': " + filterPet_filterStreams(pPets, pdctHans));
}
private static Pet filterPet_filterStreams(final ArrayList<Pet> pPets, final Predicate<Pet> pLambdaPredicate) {
return pPets.stream().filter(pLambdaPredicate).findAny().get();
}
}
与您的 Pet 类一起,通过 toString() 扩展:
package stackoverflow.filterstuff;
public class Pet { // please stick to naming conventions: classes start with uppercase letters!
private final String petName;
private final int petAge;
public Pet(final String name, final int age) {
petName = name;
petAge = age;
}
public String getName() {
return petName;
}
public int getAge() {
return petAge;
}
@Override public String toString() {
return "Pet [Name=" + petName + ", Age=" + petAge + "]";
}
}
此解决方案改编自 https://stackoverflow.com/a/33989643/1527469 和 https://stackoverflow.com/a/65387550/1527469。
如果需要一个通用的实用方法,它会很有用。
@FunctionalInterface
public static interface EqualityComparer<E> {
boolean areEqual(E e1, E e2);
}
public static <E> int indexOf(List<? extends E> list, E item, EqualityComparer<? super E> comparer) {
return IntStream.range(0, list.size())
.filter(i -> comparer.areEqual(list.get(i), item))
.findFirst().orElse(-1);
}
@Test
public void testIndexOf() {
pet Dog = new pet("Orio", 2);
pet Cat = new pet("Kathy", 4);
pet Lion = new pet("Usumba", 6);
ArrayList<pet> pets = new ArrayList<>();
pets.add(Dog);
pets.add(Cat);
pets.add(Lion);
int petIndex = indexOf(pets, new pet("Kathy", 0), (p1, p2) -> p1.getName().equals(p2.getName()));
pet foundPet = pets.get(petIndex);
assertEquals(1, petIndex);
assertEquals(4, foundPet.getAge());
}