Lambda

Lambda

一、准备

  • 接口
public interface CatChecker {
	public boolean check(Cat c);
}
  • Cat类
public class Cat {
	public int length,weight;
	public Cat(int l,int w) {
		length=l;
		weight=w;
	}
	public String toString() {
		return "length:"+length+"  weight:"+weight;
	}
}
  • Cats类,用于维护Cat列表
    • 列表lc中有10只猫
public class Cats {
	public List<Cat> lc;
	public Cats() {
		lc=new ArrayList<>();
		for(int i=1;i<11;i++) {
			lc.add(new Cat(i*5,i*2));
		}
	}
}

二、LambdaDemo

  • 筛选出身长>30,体重>15的cat
  • 原理是将 ->后的语句作为接口CatChecker类中check函数的返回值
public class LambdaDemo {
	private static void filter(List<Cat> lc, CatChecker checker) {
		// TODO Auto-generated method stub
		for(Cat c:lc) {
			if(checker.check(c))System.out.println(c.toString());
		}
	}
    
	public static void main(String[] args) {
		Cats cats=new Cats();
		// -> 后的语句实际上是接口check函数的返回值
		filter(cats.lc,c->c.length>30 && c.weight>15);	
	}
}

三、Lambda引用方法

  • 筛选出身长>30,体重>15的cat
  • lambda表达式引入方法注意方法的返回值和参数列表与接口一致
  • 引入静态方法用 类名::方法名,注意不加括号
  • 引入成员方法用 实例::方法名,注意不加括号
  • 引用容器中的方法,假设Cat类中有成员方法check,而Cat类是列表容器cats.lc中储存的对象,那么可以使用以下两种lambda表达
    • filter(cats.lc,c->c.check());
    • filter(cats.lc,Cat::check);
public class LambdaWithMethods {
	private void filter(List<Cat> lc, CatChecker checker) {
		// TODO Auto-generated method stub
		for(Cat c:lc) {
			if(checker.check(c))System.out.println(c.toString());
		}
		System.out.println("--------------------------");
	}
	public void withStaticMethods() {
		Cats cats=new Cats();
		System.out.println("使用静态方法:");
		filter(cats.lc,c->checkCat(c));
		System.out.println("直接引用静态方法");
		filter(cats.lc,LambdaWithMethods::checkCat);
		System.out.println("引用对象方法");
		LambdaWithMethods lwm=new LambdaWithMethods();
		filter(cats.lc,lwm::check);
	}
	//静态方法
	public static boolean checkCat(Cat c) {
		if(c.length>30 && c.weight>15)return true;
		else return false;
	}
	//对象方法
	public boolean check(Cat c) {
		if(c.length>30 && c.weight>15)return true;
		else return false;
	}
    
	public static void main(String[] args) {
		LambdaWithMethods lwm = new LambdaWithMethods();
		lwm.withStaticMethods();
	}
}

四、Lambda引用构造器

interface Supplier<T> {
    T get();
}
public class ReferenceConstructor {
	public static List getList(Supplier<List> s) {
		return s.get();
	}
	public void test() {
		//引用构造器
		List<Cat> lc1=getList(ArrayList<Cat>::new);
		//Lambda方式
		List<Cat> lc2=getList(()->new ArrayList<Cat>());
	}
}

五、Stream

  • demo:使用循环和使用stream遍历cats.lc
public class StreamDemo {
	Cats cats=new Cats();
	public void readCats() {
		System.out.println("传统方式:");
		for(Cat c:cats.lc) {
			if(c.length>30&&c.weight>15)System.out.println(c.toString());
		}
		System.out.println("聚合方式:");
		cats.lc
			.stream()
			.filter(c -> c.length>30&&c.weight>15)
			.forEach(c -> System.out.println(c.toString()));
	}
	public static void main(String args[]) {
		StreamDemo sd=new StreamDemo();
		sd.readCats();
	}
}
  • Stream 和Collection结构化的数据不一样,Stream是一系列的元素,就像是生产线上的罐头一样,一串串的出来。
  • 管道指的是一系列的聚合操作。
  • 管道又分3个部分
    • 管道源:在这个例子里,源是一个List
    • 中间操作: 每个中间操作,又会返回一个Stream,比如.filter()又返回一个Stream, 中间操作是“懒”操作,并不会真正进行遍历。
    • 结束操作:当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。 结束操作不会返回Stream,但是会返回int、float、String、 Collection或者像forEach,什么都不返回, 结束操作才进行真正的遍历行为,在遍历的时候,才会去进行中间操作的相关判断
public class Stream {
	Cats cats=new Cats();
	/*
	 * 流化操作
	 * 把Collection切换成管道源很简单,调用stream()就行了。
	 * 但是数组却没有stream()方法,需要使用
	 * Arrays.stream(cats)
	 * 或者Stream.of(cats)
	 * */
	
	/**
	 * 中间操作如下:
	 * filter 匹配
	 * distinct 去除重复(根据equals判断)
	 * sorted 自然排序
     * sorted(Comparator<T>) 指定排序
     * limit 保留
	 * skip 忽略
	 */
	public void streamMiddleOperator(){
		cats.lc.stream().filter(c->c.length>40)
			.forEach(c->System.out.println(c.toString()));
		
		cats.lc.stream().distinct()
			.forEach(c->System.out.println(c.toString()));
		
		cats.lc.stream().sorted((c1,c2)->c1.length>c2.length?1:-1)
			.forEach(c->System.out.println(c.toString()));
		
		cats.lc.stream().limit(3)
			.forEach(c->System.out.println(c.toString()));
		
		cats.lc.stream().skip(3)
			.forEach(c->System.out.println(c.toString()));
	}
	//中间操作属于懒操作,若没有结束操作,中间操作不会进行
	/*
	 * 结束操作
	 * forEach() 遍历每个元素,返回值为null
	 * toArray() 转换为数组,注意返回值要用Object[]接收
	 * min(Comparator<T>) 取最小的元素,最后需要get()
	 * max(Comparator<T>) 取最大的元素,最后需要get()
	 * count() 总数,注意返回值为long
	 * findFirst() 第一个元素,最后需要get()
	 */
	public void streamFinalOperator() {
		cats.lc.stream().limit(3)
            .forEach(c->System.out.println(c.toString()));
        
		Object[] cs=cats.lc.stream().limit(3).toArray();
        
		Cat cat1=cats.lc.stream().limit(3)
            .min((c1,c2)->c1.length>c2.length?1:-1).get();
        
		Cat cat2=cats.lc.stream().limit(3)
            .max((c1,c2)->c1.length>c2.length?1:-1).get();
        
		long cou=cats.lc.stream().limit(3).count();
        
		Cat cat3=cats.lc.stream().limit(3).findFirst().get();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李星且小白blog.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值