第五章(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()));

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值