1. 程式人生 > >第五章(4)流的規約操作reduce

第五章(4)流的規約操作reduce

我們之前見識了流的終端操作返回了boolen,List,Optional等。那麼這一章節我們介紹諸如求和,找出最大值最小值的玩法。

1.元素求和(或積等其他運算)

這個,用之前的方法,我相信大家都會得:

List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7);
int sum = 0;
for(Integer integer:nums) {
    sum+=integer;
}
System.out.println(sum);//28

下面是流操作的求和運算:

List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7);
int sum = nums.stream().reduce(0, (a,b)->a+b);
System.out.println(sum);//28

解釋一下上面程式碼的意思:

reduce接受兩個引數:

•一個初始值,這裡是0;

•一個BinaryOperator<T>來將兩個元素結合起來產生一個新值,這裡我們用的是lambda(a, b) -> a + b。

你也可以使用方法引用的方式上程式碼變得更簡潔:

int sum = nums.stream().reduce(0, Integer::sum);

此外reduce還有還有一個過載的方法,它沒有初始值,使用Optional接收結果:

List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7);
Optional<Integer> optional = nums.stream().reduce(Integer::sum);
System.out.println(optional.get());//28

2.最大值和最小值

List<Integer> nums = Arrays.asList(1,2,3,4,5,6,7);
Optional<Integer> optional = nums.stream().reduce(Integer::max);
System.out.println(optional.get());//7
Optional<Integer> optional2 = nums.stream().reduce(Integer::min);
System.out.println(optional2.get());//1

練習題:使用reduce來統計一下選單中有多少菜:

當然,你可以使用Stream中的count方法來統計:

long count = menu.stream().count();

如果使用規約reduce,需要藉助於map:

int count = menu.stream().map(d ->1).reduce(0, Integer::sum);
System.out.println(count);

把每個菜的物件對映為數值1,讓他們相加。

 

習題:

交易員類:

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

 

八道題:

1.找出2011年的交易,降序排列

2.交易員在哪些城市不同的城市工作

3.找來自劍橋的交易員,按名字排序

4.返回所有交易員的姓名字串,按字母順序排序

5.有沒有在米蘭工作的?

6.列印在劍橋工作的所有交易員的交易金額

7.所有交易額中最高交易額是多少

8.找出交易額最小的交易

答案:

System.out.println("找出2011年的交易,降序排列");
		List<Transaction> transactions2011 = transactions.parallelStream()
				.filter(t->t.getYear()==2011)
				.sorted(Comparator.comparing(Transaction::getValue).reversed())
				.collect(Collectors.toList());
		transactions2011.parallelStream().forEach(t->System.out.println(t.getYear()+":"+t.getValue()));
		
		System.out.println("----------------------------------------------------");
		System.out.println("交易員在哪些城市不同的城市工作");
		List<String> citys = transactions.parallelStream()
				.map(Transaction::getTrader)
				.map(Trader::getCity)
				.distinct()
				.collect(Collectors.toList());
		citys.parallelStream().forEach(System.out::println);
		
		System.out.println("----------------------------------------------------");
		System.out.println("找來自劍橋的交易員,按名字排序");
		List<Trader> traders = transactions.parallelStream()
				.map(Transaction::getTrader)
				.filter(t ->"Cambridge".equals(t.getCity()))
				.distinct()
				.sorted(Comparator.comparing(Trader::getName))
				.collect(Collectors.toList());
		traders.parallelStream().forEach(trader->System.out.println(trader.getName()+":"+trader.getCity()));
		
		System.out.println("-----------------------------------------------------");
		System.out.println("返回所有交易員的姓名字串,按字母順序排序");
		String names = transactions.parallelStream()
				.map(transaction -> transaction.getTrader().getName())
				.distinct()
				.sorted()
				.reduce("", (n1,n2)->n1+n2);
		System.out.println(names);
		
		System.out.println("------------------------------------------------------");
		System.out.println("有沒有在米蘭工作的?");
		boolean b = transactions.parallelStream()
				.anyMatch(t -> t.getTrader().getCity().equals("Milan"));
		System.out.println(b);
		
		System.out.println("-------------------------------------------------------");
		System.out.println("列印在劍橋工作的所有交易員的交易金額");
		List<Integer> values = transactions.parallelStream()
				.filter(transaction -> "Cambridge".equals(transaction.getTrader().getCity()))
				.map(Transaction::getValue)
				.collect(Collectors.toList());
		values.parallelStream().forEach(System.out::println);
		
		System.out.println("-------------------------------------------------------");
		System.out.println("所有交易額中最高交易額是多少");
		transactions.parallelStream().
				map(Transaction::getValue)
				.reduce(Integer::max)
				.ifPresent(System.out::println);
		
		System.out.println("---------------------------------------------------------");
		System.out.println("找出交易額最小的交易");
		Optional<Transaction> smallestTransaction = transactions.stream().reduce((t1, t2) -> t1.getValue() < t2.getValue() ? t1 : t2); 
		smallestTransaction.ifPresent(t -> System.out.println(t.getValue()));
		//或者
		Optional<Transaction> smallestTransaction2 = transactions.stream() .min(Comparator.comparing(Transaction::getValue));
		smallestTransaction2.ifPresent(t -> System.out.println(t.getValue()));