访问 ArrayList 中对象的元素

Accessing elements of object in ArrayList

我想知道是否可以得到一些建议。我有以下代码:

 private static int getIndex(String regneeded) {

        System.out.println("The reg passed to getIndex method is:" + regneeded);
         if (arraylist.contains(regneeded)) {
             int pos = arraylist.indexOf(regneeded);
             System.out.println("The position of the vehicle in the array list is:" + pos);
         }else {return -1;}
         return 0;
  }

我想做的是搜索一个 DeliveryVehicles 数组,寻找特定的注册号(我传递给方法),然后说出包含此注册的对象在 ArrayList 中的什么位置。

我知道我遇到了一个问题,因为我在 ArrayList 中搜索字符串,而我的 ArrayList 中的是对象。所以,在我继续研究的同时寻求任何建议。

提前谢谢你。抱歉,如果这是基本的,我对 Java 很陌生。

编辑:包含有关 ArrayList 中包含的对象的更多信息。

DeliveryVehicle 对象包含在 ArrayList 中。每个都包含注册号(它们还有其他属性,但我首先关注注册号以了解此问题)。在基础 class DeliveryVehicle 中有 setters (setRegNum()) 和 getters (getRegNum()) 用于注册号,我在创建车辆对象时将注册号传递给构造函数,如下所示:

 DeliveryBike myVehicle = new DeliveryBike("21D789");
        arraylist.add(myVehicle);

我扩展了基础 class 以包括 DeliveryBike class(如图所示)。我最初发布的代码是我的控制器 class 中的一个方法。所以,我想我对如何访问 DeliveryBike 对象中的注册号感到困惑。

谢谢。

您使用了错误的数据结构来解决问题。使用字符串等键识别对象是 Map 的完美用例。因为可以对字符串进行哈希处理,所以可以使用 java.util.HashMap:

import java.util.HashMap;
import java.util.Map;

public class Main
{
    static class DeliveryBike {public String s; public DeliveryBike(String s) {this.s=s;}} 

    public static void main(String[] args)
    {
        Map<String,DeliveryBike> vehicles = new HashMap<>();
        vehicles.put("21D789",new DeliveryBike("21D789"));
        System.out.println(vehicles.get("21D789").s);
    }
}

如果你不能把它从ArrayList改成ArrayList,因为它是从外面传入的,先把它放在一个map中,然后你可以多次搜索那个map。

如果您坚持使用 ArrayList,因为它是从外部传递的,并且您总是只使用一次,您也可以使用流和过滤器:

import java.util.ArrayList;
import java.util.List;

public class Main
{
    static class DeliveryBike {public String s; public DeliveryBike(String s) {this.s=s;}} 

    public static void main(String[] args)
    {
        List<DeliveryBike> vehicles = new ArrayList<>();
        vehicles.add(new DeliveryBike("21D789"));
        System.out.println(vehicles.stream().filter(x->x.s=="21D789").findFirst().get().s);
    }

}

警告

在现实世界的代码中,您需要防止密钥在这两种情况下都不存在。使用地图,vehicles.get() 可以 return 为空,使用过滤器,findFirst() 可以 return 空可选。

您可以像这样定义通用 indexOf 方法:

private static <T,E> int indexOf(List<? extends T> list, BiPredicate<T,E> pred, E e) {
    int i = list.size();
    while (--i >= 0 && !pred.test(list.get(i), e)) {
        // nothing
    }
    return i;
}

您可以为注册号定义谓词:

private static BiPredicate<DeliveryVehicle,String> BY_REGNUMBER
        = (dv,e)->dv.getRegNumber().equals(e);

您将按如下方式使用它:

    list.add(new DeliveryBike("1"));
    list.add(new DeliveryBike("2"));
    list.add(new DeliveryBike("3"));
    list.add(new DeliveryBike("4"));
    list.add(new DeliveryBike("5"));
    System.out.println(indexOf(list, BY_REGNUMBER, "1"));
    System.out.println(indexOf(list, BY_REGNUMBER, "2"));
    System.out.println(indexOf(list, BY_REGNUMBER, "3"));
    System.out.println(indexOf(list, BY_REGNUMBER, "4"));
    System.out.println(indexOf(list, BY_REGNUMBER, "5"));
    System.out.println(indexOf(list, BY_REGNUMBER, "6"));

更新:

使用函数而不是谓词来提取属性的替代方法:

private static <T,E> int indexOf(List<? extends T> list, Function<T,E> attr, E e) {
    int i = list.size();
    while (--i >= 0 && !attr.apply(list.get(i)).equals(e)) {
        // nothing
    }
    return i;
}

你会喜欢这样吗:

    System.out.println(indexOf(list, DeliveryVehicle::getRegNumber, "1"));
    System.out.println(indexOf(list, DeliveryVehicle::getRegNumber, "2"));
    System.out.println(indexOf(list, DeliveryVehicle::getRegNumber, "3"));
    System.out.println(indexOf(list, DeliveryVehicle::getRegNumber, "4"));
    System.out.println(indexOf(list, DeliveryVehicle::getRegNumber, "5"));
    System.out.println(indexOf(list, DeliveryVehicle::getRegNumber, "6"));

好吧,你必须走遍 DeliveryVehicles 并检查对象的注册号是否等于你正在搜索的注册号:

int getIndex(String search) {
    for (int i = 0; i < arraylist.size(); i++) {
        if (Objects.equals(arraylist.get(i).getRegNum(), search)) {
            System.out.println("The position of the vehicle in the arraylist is: " + i);
            return i;
        }
    }
    return -1;
}

请注意,containsindexOf 在列表中搜索 整个对象 ,但它们不适合搜索具有 特定属性.

对于 arraylist 中的每个对象,属性 registrationNumber 与您正在 search 的字符串进行比较,如果它们匹配,则向控制台打印一些内容并立即return i,也就是找到元素的位置

否则,return -1,这是一个标记值,表示没有具有该注册号的对象。


请注意,对于这种情况,有些数据结构是更好的选择,例如使用 Map 或 Streams,但我认为这不在问题范围内。

有不同的方法。

1- 您可以遍历所有元素并比较值

private static int getIndex(String regneeded) {
    for (DeliveryBike vehicle: arrayList) {
        if (vehicle.getRegNumber().equalsIgnoreCase(regneeded)) {
            return arrayList.indexOf(vehicle);
        }
    }

    return -1;
}

2- 您可以在 DeliveryBike class

中覆盖 hashCodeequals 方法
// inside your DeliveryBike class add
@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    DeliveryBike that = (DeliveryBike) o;
    return Objects.equals(regNumber, that.regNumber);
}

@Override
public int hashCode() {
    return Objects.hash(regNumber);
}
private static int getIndex(String regneeded) {
    DeliveryBike searchItem = new DeliveryBike(regneeded);
    return arrayList.indexOf(searchItem);
}

如果我没记错的话,equals 方法用于 List、Set 和 Map 等集合中,以了解元素是否已包含并且 Map 集合使用 hashCode 方法来查找与键关联的对象。

在这种情况下,您只需要 equals 方法,但通常同时覆盖这两个方法。


此外,我会为您的目的创建两个函数,一个是 return 元素的索引,另一个是使用该索引显示文本。这样你就可以在项目变大时重用你的代码!

private static int getIndex(String regneeded) {
    DeliveryBike searchItem = new DeliveryBike(regneeded);
    return arrayList.indexOf(searchItem);
}

private static void showMessage(int index, String regneeded) {
    System.out.println("The position of the vehicle with reg " + regneeded + " in the array list is:" + pos);
}

希望对您有所帮助!