交易员和交易的实体类的定义如下:
Trader.class
public class Trader { private String name; private 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 void setCity(String newCity) { this.city = newCity; } public String toString() { return "Trader:" + this.name + " in " + this.city; } }
Transaction.class
public class Transaction { private Trader trader; private int year; private 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 + "}"; } }
问题:
(1) 找出2011年发生的所有交易,并按交易额排序(从低到高)。 (2) 交易员都在哪些不同的城市工作过? (3) 查找所有来自于剑桥的交易员,并按姓名排序。 (4) 返回所有交易员的姓名字符串,按字母顺序排序。 (5) 有没有交易员是在米兰工作的? (6) 打印生活在剑桥的交易员的所有交易额。 (7) 所有交易中,最高的交易额是多少? (8) 找到交易额最小的交易。
解答:
import java.util.Arrays; import java.util.List; import java.util.Optional; import static java.util.Comparator.comparing; import static java.util.stream.Collectors.joining; import static java.util.stream.Collectors.toList; public class PuttingIntoPractice { public static void main(String[] args) { Trader raoul = new Trader("Raoul", "Cambridge"); Trader mario = new Trader("Mario", "Milan"); Trader alan = new Trader("Alan", "Cambridge"); Trader brian = new Trader("Brian", "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) ); // Query 1: Find all transactions from year 2011 and sort them by value (small to high). List<Transaction> tr2011 = transactions.stream() .filter(transaction -> transaction.getYear() == 2011) .sorted(comparing(Transaction::getValue)) .collect(toList()); System.out.println(tr2011); // Query 2: What are all the unique cities where the traders work? List<String> cities = transactions.stream() .map(transaction -> transaction.getTrader().getCity()) .distinct() .collect(toList()); System.out.println(cities); // Query 3: Find all traders from Cambridge and sort them by name. List<Trader> traders = transactions.stream() .map(Transaction::getTrader) .filter(trader -> trader.getCity().equals("Cambridge")) .distinct() .sorted(comparing(Trader::getName)) .collect(toList()); System.out.println(traders); // Query 4: Return a string of all traders’ names sorted alphabetically. String traderStr = transactions.stream() .map(transaction -> transaction.getTrader().getName()) .distinct() .sorted() .reduce("", (n1, n2) -> n1 + n2); System.out.println(traderStr); // 请注意,此解决方案效率不高(所有字符串都被反复连接,每次迭代的时候都要建立一个新的String对象)。 // 这里有一个更为高效的解决方案,它像下面这样使用joining(其内部会用到StringBuilder): String traderStr_2 = transactions.stream() .map(transaction -> transaction.getTrader().getName()) .distinct() .sorted() .collect(joining()); // Query 5: Are there any trader based in Milan? boolean milanBased = transactions.stream() .anyMatch(transaction -> transaction.getTrader() .getCity() .equals("Milan") ); System.out.println(milanBased); // Query 6: Update all transactions so that the traders from Milan are set to Cambridge. transactions.stream() .map(Transaction::getTrader) .filter(trader -> trader.getCity().equals("Milan")) .forEach(trader -> trader.setCity("Cambridge")); System.out.println(transactions); // Query 7: What's the highest value in all the transactions? int highestValue = transactions.stream() .map(Transaction::getValue) .reduce(0, Integer::max); System.out.println(highestValue); // tips:流支持min和max方法,它们可以接受一个Comparator作为参数,指定计算最小或最大值时要比较哪个键值: Optional<Transaction> smallestTransaction = transactions.stream() .min(comparing(Transaction::getValue)); } }