Java 8 in Action Streams的明确说明

时间:2019-07-03 11:27:34

标签: java java-8 java-stream

我正在通过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>字段以返回不同的交易者?

2 个答案:

答案 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));

现在您将看到,由于raoulraoul2不相等(即使它们具有相同的名称),它们都将出现在输出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方法