在查找对象中的值时使用ArrayList.indexOf

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

我有一个分支类,它有一个客户对象的arraylist。在分支类中,我希望addTransaction获取给定的客户名称,但首先我要检查客户是否存在,然后添加事务。

private boolean customerExists(String customerName) {
    for (int i = 0; i < customers.size(); i++) {
        if(customers.get(i).getCustomerName().equalsIgnoreCase(customerName)) {
            return true;
        }
    }
    return false;
}


private int customerPosition(String customerName) {
    for (int i = 0; i < customers.size(); i++) {
        if(customers.get(i).getCustomerName().equalsIgnoreCase(customerName)) {
            return i;
        }
    }
    return -1;
}



public void addTransaction(String customerName, Double transactionValue) {
    if(customerExists(customerName) == false) {
        System.out.println("Customer with name " + customerName + " not found");
    } else {
        customers.get(customerPosition(customerName)).addTransaction(transactionValue);
    }
}

我知道这段代码会起作用,但我知道我必须通过arraylist做2个循环来检查它是否存在,并获得它的位置。这似乎效率低下

我知道indexOf方法在addTransaction中很有用,但是如果我在对象内部寻找特定值而不是对象本身,我不知道如何使用它,即我不是在寻找Customer对象,我在对象中寻找一个值。任何建议将不胜感激。

编辑:谢谢大家,这些答案太棒了。

java arraylist getter
6个回答
3
投票

通常,您不能只是循环遍历列表来查找值。

在代码重复方面,将customerExists的主体替换为:

return customerPosition() >= 0;

并且,在addTransaction()中,将customerPosition()的结果存储在变量中,并使用thatVariable >= 0而不是调用customerExists()

如果您使用的是Java 8+,则可以使用流:

Optional<Customer> cust = customers.stream().filter(c -> c.getCustomerName().equals(customerName)).findFirst();

然后你根本不用担心使用索引。


1
投票

而不是使用Multiple for循环,使用单个for循环并获取客户对象并使用它,

private Customer getCustomerUsingName(String customerName) {
    for (int i = 0; i < customers.size(); i++) {
        if(customers.get(i).getCustomerName().equalsIgnoreCase(customerName)) {
            return customers.get(i);
        }
    }
    return null;
} 

在您的方法中使用Customer

public void addTransaction(String customerName, Double transactionValue) {
    Customer customer = getCustomerUsingName(customerName)

    if(customer == null) {
        return;
    }
    customer.addTransaction(transactionValue);
}

0
投票

即使您可以使用'indexOf'的某些突变变体,也不会提高效率。要在未排序的数组中查找数据,您必须遍历数组以查找它。这是选择存储数据的数组所固有的。

但是你为什么要使用customerExists呢? customerPosition执行完全相同的逻辑。你只需要调用一次。

   int pos = customerPosition(...);
   if (pos >= 0) 
      customers.get(pos).addTransaction(...);
   else 
      ... does not exist ...

0
投票

使用customerPosition方法检查存在Customer

public void addTransaction(String customerName, Double transactionValue) {
    final int index = customerPosition(customerName);
    if(index == -1) {
        System.out.println("Customer with name " + customerName + " not found");
    } else {
        customers.get(index).addTransaction(transactionValue);
    }
}

0
投票

您可以改用HashMap,

通常,在某些情况下,ArrayList比HashTable更快,但是当您必须查找元素时,HashTable(使用搜索键)比ArrayList更快,您可以使用它:

HashMap<String, Customer> myCustomers = new HashMap<String, Customer>();
myCustomers.put("NameID_1", customerObject_1);
myCustomers.put("NameID_2", customerObject_2);
myCustomers.put("NameID_3", customerObject_3);
myCustomers.put("NameID_4", customerObject_4);

System.out.println(myCustomers.get("NameID_1"));
// just check if the customer exists in your Map

0
投票

同意Andy Turner的第一个答案。在findFirst()之后,你可以申请ifPresent消费者,这将增加交易。

customers.stream()
        .filter(c -> c.getCustomerName().equals(customerName))
        .findFirst()
        .ifPresent(customer -> customer.addTransaction(transactionValue));

如果将来您需要向与筛选谓词匹配的所有客户添加事务,您可以使用forEach并传递前一个示例中的使用者。

customers.stream()
        .filter(c -> c.getCustomerName().equals(customerName))
        .forEach(customer -> customer.addTransaction(transactionValue));

如果您使用Java版本8,您的循环可能会略有改进。你可以有一个循环

Iterator it = customers.iterator();
while (it.hasNext()) {
    Customer customer = it.next();
    if (customerPredicate.test(customer)) { // your if condition
        customer.addTransaction(transactionValue); // your consumer.
        break; // If you need to change only first customer.
    }
}

技术说明

Stream有forEach和peek方法。如果您需要将您的使用者应用于流的所有元素,并且仍然有一个新流(一个惰性操作) - 请使用peek。如果要为所有元素应用消费者并终止流(不再需要流) - 请使用终端操作 - forEach

© www.soinside.com 2019 - 2024. All rights reserved.