【发布时间】:2019-03-25 07:29:28
【问题描述】:
我需要对具有多个条件的集合进行排序。但是,在这些条件之间,我需要修改流数据。
Customer.class
import java.math.BigDecimal;
import java.util.Date;
public class Customer {
private int id;
private String name;
private long quantity;
private BigDecimal cost;
private Date lastPurchasedDate;
public Customer(int id, String name, long quantity, BigDecimal cost) {
this.id = id;
this.name = name;
this.quantity = quantity;
this.cost = cost;
}
// setters & getters are omitted for brevity.
}
Main.class
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
public class Main {
public static void main(String[] args) {
List<Customer> customers = Arrays.asList(new Customer(1, "A", 10, BigDecimal.valueOf(673.89)),new Customer(2, "B", 10, BigDecimal.valueOf(673.89)));
getCustomer(customers).ifPresent(c -> System.out.println(c.getId()));
}
private static Optional<Customer> getCustomer(List<Customer> customers) {
// @formatter:off
return customers.stream()
.max(
Comparator.comparing(Customer::getQuantity)
.thenComparing(Customer::getCost)
// here I need to check, If multiple customers are after
// comparing the cost, I have to update the lastPurchasedDate l
// attribute value & then sort it
.thenComparing(Customer::getLastPurchasedDate)
);
// @formatter:on
}
}
如果按成本排序后有多个可用客户,那么我需要填充 lastPurchasedDate 属性值,然后按 lastPurchasedDate 对其进行排序。
为什么我之前没有填充 lastPurchasedDate 数据?
要获取该信息,我需要在 db 上运行一个查询(要获取信息,我们将使用一个包含数百万条记录的表)。所以这是一个性能限制,我想避免它。需要按lastPurchasedDate 进行比较的非常罕见的场景。所以我不想为所有客户不必要地运行这个查询。
【问题讨论】:
-
我需要填充 lastPurchasedDate 属性值,然后按 lastPurchasedDate 对其进行排序。 将其作为流的中间操作也不是一个好主意。你也可以给自己写一个自定义的
Comparator。 -
“然后排序”是什么意思?您没有对流进行排序,而是从中取出了最大客户。在某些情况下,将单个客户从列表中取出的函数也会对其进行排序,这违反了方法的单一责任原则。
-
我会在两个或三个流操作中完成。首先选择成本最高的那些到一个单独的列表中。如果多于一个,则修改并使用新的流操作进行最终排序。
-
首先,决定你真正想要什么,排序或获取最大元素。
-
@ErwinBolwidt,我相信我们只需要“在某些条件下”对数据进行排序。在这里,我的函数将通过应用一些条件来获得最大客户。像首先我们将应用数量条件,如果多个客户拥有最大客户,则应用成本条件。我的问题是其中一个数据,在给定的示例中填充 lastPurchasedDate 是一项繁重的操作,除非有必要,否则我不想这样做。
标签: java lambda java-8 java-stream