如何使用indexOf()函数来查找具有特定属性的对象

问题描述 投票:0回答:3

我有一个对象,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 中的索引或具有我需要的名称的对象。那么,如果我想知道乌松巴的年龄,我该怎么做?

注意:这不是我的实际代码,它只是用来让我更好地解释我的问题。

编辑1

到目前为止,我有以下内容,但我想知道是否有更好或更有效的方法

public int getPetAge(String petName){
    int petAge= 0;

    for (pet currentPet : pets) {
        if (currentPet.getName() == petName){
            petAge = currentPet.getAge();
            break;
        }
    }

    return petAge;
}
java arraylist indexof
3个回答
1
投票

您不能将

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

0
投票

正如其他人已经指出的,您不能直接使用 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 + "]";
    }

}

0
投票

此解决方案改编自 https://stackoverflow.com/a/33989643/1527469https://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());
}
© www.soinside.com 2019 - 2024. All rights reserved.