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

时间:2019-04-28 12:02:03

标签: java arraylist getter

我有一个分支类,其中包含客户对象的数组列表。在分支类中,我要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对象,而是在对象内寻找值。任何建议将不胜感激。

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

6 个答案:

答案 0 :(得分: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 :(得分:1)

而不是使用Multiple for循环,而是使用single 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;
} 

以您的方式使用客户

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

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

答案 2 :(得分:0)

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

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

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

答案 3 :(得分: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);
    }
}

答案 4 :(得分: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

答案 5 :(得分:0)

同意安迪·特纳的第一个答案。在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.
    }
}

技术说明

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