Lambda、Stream与新增内容

本文介绍了Java1.8及以后版本中接口的新特性,如静态方法、默认方法和私有方法,以及Lambda表达式的使用、函数式接口的应用、Stream流的概念与操作。通过实例展示了如何利用这些特性进行集合处理和数据运算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Lambda、Stream与新增内容

1.interface新增内容

JDK1.8新增 :

​ 1)静态方法 : 跟随接口名使用

​ 2)默认方法 : 显示 通过default修饰的方法

​ 可以在实现类中重写

​ 需要通过实现类对象调用

JDK9新增 :

​ 私有方法 : 被private关键字修饰
​ 不能在外部类中使用
​ 只能在接口中的默认方法中调用

public class Class001_Interface {
    public static void main(String[] args) {
        Smoke.testStatic();
        new Impl().testDefault();
    }
}
interface Smoke{
    void smoking();
    //静态方法
    public static void testStatic(){
        System.out.println("接口中的静态方法");
    }
    //默认方法
    default void testDefault(){
        System.out.println("默认方法....");
        testPrivate();
    }
    //私有方法
    private void testPrivate(){
        System.out.println("私有方法...");
    }
}
class Impl implements Smoke{
    @Override
    public void smoking() {
    }
    @Override
    public void testDefault() {
        System.out.println("重写的默认方法....");
    }
}

2.Lambda

例题一

调用Collections.sort()方法对List集合中的数据做默认升序排序,通过定值排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递
分析:

1.定制排序:指自定义比较器|定制排序

​ 自然排序:内部比较器|自然排序

2.先比较年龄,年龄相同才比较姓名

Lambda表达式 : 将行为作为参数传递–>函数式编程

如果形参|引用为函数式接口类型,实参|赋值就可以为Lambda表达式

public static void main(String[] args) {
		List<Employee> emps = Arrays.asList(
				new Employee(103,"迪丽热巴",30,8888),
				new Employee(101,"古力娜扎",28,7777),
				new Employee(102,"易烊千玺",23,8888),
				new Employee(104,"欧娜娜娜",28,7777)
		);
		//Collections.sort(emps);  检测Employee类型是否实现了内部比较器,如果是调用做升序排序,如果没有实现报错
		System.out.println(emps);
		//Collections.sort(emps,(x,y)->x.getId()-y.getId());  //根据员工编号做升序排序
		Collections.sort(emps,(x,y)->{
			if(x.getAge()==y.getAge()){
				return y.getName().compareTo(x.getName());
			}
			return Integer.compare(x.getAge(),y.getAge());
		});  //根据员工编号做升序排序
		System.out.println(emps);
	}
例题二

1)声明函数式接口,接口中声明抽象方法,public String getValue(String str)

2)声明类 TestLambda,类中编写方法使用接口作为参数,讲一个字符串转成大写,并作为方法的返回值

3)再将一个字符串的第2个和第4个索引位置进行截取子串

public class Class002_TestLambda {
	public static void main(String[] args) {
		System.out.println(strHandler("abc",s->s.toUpperCase()));;
		System.out.println(strHandler("123abc456",s->s.substring(2,5)));;
	}
	//需求 : 对任意一个字符串做某种操作,返回结果
	public static String strHandler(String str,MyFunction my){
		return my.getValue(str);
	}
}
//接口
@FunctionalInterface
interface MyFunction{
	public String getValue(String str);
}
习题三

1)声明一个带两个泛型的函数式接口,发型类型为<T,R> T为参数,R为返回值

2)接口中声明对应抽象方法

3)在TestLambda类中声明方法,参数三个,两个long类型的参数,接口作为参数,接口实现中计算两个long型参数的和

4)再计算两个long型参数的乘积

public class Class003_TestLambda {
	public static void main(String[] args) {
		pera(100L,200L,(x,y)->x+y);
		pera(100L,200L,(x,y)->x*y);
	}

	//对两个long类型数据的使用 ,输出结果
	public static void pera(long l1,long l2,MyFunction2<Long,Long> my){
		System.out.println(my.test(l1,l2));
	}
}

@FunctionalInterface
interface MyFunction2<T,R>{
	public R test(T t1,T t2);
}

3.函数式接口

java.util.function下的函数式接口

四大内置函数式接口

​ 1.消费型接口:有参无返回值

​ Consumer

​ void accept(T t)

​ 2.函数式接口:有参有反回值

​ Function<T,R>

​ R apply(T t)

​ 3.段言型接口:有参返回布尔

​ Predicate

​ boolean test(T t)

​ 4.供给型接口:无参有返回值

​ Supplier

​ T get()

 public static void main(String[] args) {
        happy(5000,m-> System.out.println("为PDD刷火箭消费"+m));
        System.out.println(strHandler("DLGJGL",s->s.toLowerCase()));
        System.out.println(test(10,()->(int)(Math.random()*(8-5+1)+5)));
        Consumer c = a -> System.out.println("ss");
        c.accept(10);
        Function d = b-> b;
    }
    //消费
    public static void happy(double money, Consumer<Double> con){
        con.accept(money);
    }
    //对任意一个 字符串进行某种操作返回结果
    public static String strHandler(String str, Function<String,String> fun){
        return fun.apply(str);
    }
    //生成指定个数的指定规则的随机整数
    public static List<Integer> test(int num, Supplier<Integer> sup){
        List<Integer> list = new ArrayList<>();
        for(int i=1;i<=num;i++){
            list.add(sup.get());
        }
        return list;
    }
方法引用

是用来简化Lambda表达式的,是Lambda表达式的另外一种表现形式。

简化条件要求 : 必须满足一下2个条件

​ 1.当lambda体{}中的实现就是通过调用另外一个方法实现的,可以考虑是否可以通过方法引用简化

​ 2. a)当lambda参数列表,返回值与内部引用方法的参数列表与返回值保持一致的时候 ----> 对象::成员方法 | 类名::静态方法

​ b)内部所引用方法的 返回值与lambda表达式的返回值一致,lambda参数列表的第一个参数作为调用内部方法的对象,lambda参数列表的第二个参数开始匹配内部引用方法参数列表 ----> 类名::成员方法

方法引用语法 ::

​ 对象::成员方法

//分析 : 1. 满足   println()        2)  a)满足   ===>对象::成员方法
        list.forEach(i->{
            System.out.println(i);
        });
        //变化后
        list.forEach(System.out::println);

​ 类名::静态方法

//求两个double中的最大值
        //BiFunction<Double,Double,Double> fun = (x,y)->Math.max(x,y);
        //分析  : 1. 满足  max()  2.a)满足 ===>类名::静态方法
        BiFunction<Double,Double,Double> fun = Math::max;

​ 类名::成员方法

//比较两个字符串是否相等
        //BiPredicate<String,String> bi = (x,y)->x.equals(y);
        //分析  : 1. 满足  equals  2. b) 类名::成员方法
        BiPredicate<String,String> bi = String::equals;

Stream流

1.三者之间的差别

IO流 : 关注数据的传输

集合|数组 : 关注数据的存储

Stream流 : 关注数据的运算

将由数据源产生的元素序列进行流式运算

2.Stream流的使用步骤

​ 1.获取创建Stream流

​ 2.一些列流式中间操作

​ 3.终止行为

3.Stream流的特点

​ 1.Stream本身不存储数据

​ 2.Stream的运算不影响数据源

​ 3.所有中间操作都返回持有结果的新的流

​ 4.流是一次性的流,一旦已经使用就被破坏,无法重复使用多次

​ 5.延迟执行|惰性加载 : 当获取终止行为的时候所有的中间操作才会执行

4.获取Stream的方式

​ 1.Collection–>stream()

        List<Integer> ls = List.of(1,2,3,4,5);
        Stream<Integer> s1 = ls.stream();
        s1.forEach(System.out::println);

​ 2.Arrays.stream()

        String[] arr = {"aaa","bbb","ccc","ddd"};
        Stream<String> s2 = Arrays.stream(arr);
        s2.forEach(System.out::println);

​ 3.Stream.of(…)

		Stream<Integer> s3 = Stream.of(5,4,3,2,1);
        s3.forEach(System.out::println);
5.Stream中间操作 :

​ 1.过滤 filter(Predicate<? super T> predicate) 返回由与给定谓词匹配的此流的元素组成的流。

​ 2.截取 Stream limit(long maxSize) 返回由该流的元素组成的流,长度被截断为不超过maxSize 。

​ 3.跳过 Stream skip(long n) 在丢弃流的前n元素后,返回由该流的剩余元素组成的流。

​ 4.去重 Stream distinct() 返回由该流的不同元素(根据Object.equals(Object) )组成的流。

​ 根据equals与hashCode方法,需要根据内容重写

​ 5.排序

​ Stream sorted() 返回由该流的元素组成的流,按自然顺序排序。

​ Stream sorted(Comparator<? super T> comparator) 返回由该流的元素组成的流,根据提供的Comparator排序。

 emps.stream()
               .filter(e->e.getAge()<30)
               //.limit(4)
               //.skip(1)
               .distinct()
               .sorted((x,y)->Integer.compare(x.getAge(),y.getAge()))
               .forEach(System.out::println);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值