我正在通过Java 8 in Action进行练习,遇到了这个问题。交易者和交易分为2类,如下所示:
public class Trader {
private final String name;
private final String city;
public Trader(String n, String c) {
this.name = n;
this.city = c;
}
public String getName() {
return this.name;
}
public String getCity() {
return this.city;
}
public String toString() {
return "Trader:" + this.name + " in " + this.city;
}
}
public class Transaction {
private final Trader trader;
private final int year;
private final int value;
public Transaction(Trader trader, int year, int value) {
this.trader = trader;
this.year = year;
this.value = value;
}
public Trader getTrader() {
return this.trader;
}
public int getYear() {
return this.year;
}
public int getValue() {
return this.value;
}
public String toString() {
return "{" + this.trader + ", " + "year: " + this.year + ", " + "value:" + this.value + "}";
}
}
交易者和交易清单如下创建:
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
Trader raoul = new Trader("Raoul", "Cambridge");
List<Transaction> transactions = Arrays.asList(new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000), new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 700), new Transaction(alan, 2012, 950));
问题是从剑桥市找到所有商人并按名称对他们进行排序。 书中针对此问题的解决方案如下:
List<Trader> traders = transactions.stream()
.map(Transaction::getTrader)
.filter(trader -> trader.getCity().equals("Cambridge"))
.distinct()
.sorted(comparing(Trader::getName))
.collect(toList());
上面提供的答案返回了正确的结果,但是我想知道如何和为什么使用 name distinct() / em>字段以返回不同的交易者?
答案 0 :(得分:4)
distinct()
未使用名称字段来返回不同的交易者。它使用equals
方法确定两个Trader
是否相同。由于Trader
不会覆盖equals
,因此该代码似乎起作用的唯一原因是它将同一实例(由raoul
引用)传递给两个Transaction
,因此默认的equals
实现(检查==
)足以确定它们是否相同。
因此输出List
为:
[Trader:Alan in Cambridge, Trader:Brian in Cambridge, Trader:Raoul in Cambridge]
但是,如果进行以下更改:
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
Trader raoul = new Trader("Raoul", "Cambridge");
Trader raoul2 = new Trader("Raoul", "Cambridge");
List<Transaction> transactions = Arrays.asList(new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000), new Transaction(raoul2, 2011, 400),
new Transaction(mario, 2012, 710), new Transaction(mario, 2012, 700), new Transaction(alan, 2012, 950));
现在您将看到,由于raoul
和raoul2
不相等(即使它们具有相同的名称),它们都将出现在输出List
中:>
[Trader:Alan in Cambridge, Trader:Brian in Cambridge, Trader:Raoul in Cambridge, Trader:Raoul in Cambridge]
答案 1 :(得分:1)
Stream.distinct()通过Object.equals(Object)比较对象 https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#distinct--
在此示例中,您有4个Trader对象,它们通过Object.equals()的默认实现进行比较,因为Trades类不会覆盖equals方法