CoreJava学习第十六课-JDK8中Lambda表达式和Stream编程

Lambda表达式

从JDK8 Lambda表达式开始,java成为面向对象编程思想+函数式编程思想

避免冗余代码, 提高程序的可重用性
提高可重用性: 将代码的不变部分, 和可变部分 分离
继承关系
将子类共性抽取到父类
将数据作为方法的参数
将代码作为方法的参数  定义接口,通过接口回调实现
Lambda : 函数式编程
Lambda表达式  匿名内部类的简便写法  实现的接口必须只有一个抽象方法  (函数式接口)
语法: 
1.  (参数表)->{代码块}
2.  (参数表)-> 表达式(只有一句代码时)
​
参数表中形参的类型可以省略, 由编译器自动推断
如果参数表只有一个参数,()可以省略
public class TestLambda2 {
    public static void main(String[] args) {
        List<Student> list = new ArrayList<>();
        list.add(new Student("Yangdd",48,60));
        //list.add...
        
        findStu(list, new Predicates() {
            public boolean test(Student s) {
                return s.getAge()==18;//写接口,都是为这句代码服务的
            }
        });
        //简化
        findStu(list, (Student s) -> s.getAge()==18 );
        //进一步简化
        findStu(list, s->s.getAge()==30);//如果参数表只有一个参数,()可以省略
    }
    static List<Student> findStu(List<Student> list ,Predicates p){
        List<Student> result = new ArrayList<Student>();
        for(Student s:list){
            boolean b = p.test(s);
            if (b) result.add(s);
        }
        return result;
    }
}
interface Predicates{
    public boolean test(Student s);
}
//以下都是lambda表达式写法
Runnable r= new Runnable(){
    public void run(){
        System.out.println("hehe");
    }
};
Runnable r = ()->{System.out.println("hehe");};
​
Callable<Integer> c = new Callable<Integer>(){
    public Integer call(){
        return 10;
    }
}
Callable<Integer> c = ()->10;
方法引用
public class TestMethodLambda {
    public static void main(String[] args) {
        A a = new A(){
            public void act(MyClass mc) {
                mc.method();
            }
        };
        A a2 = (MyClass mc)->mc.method();
        A a3 = MyClass::method;
        
        B b = new B() {
            public void act(MyClass mc , String s) {
                mc.method(s);
            }
        };
        B b2 = (MyClass mc , String s)->mc.method(s);
        B b3 = MyClass::method;
        
        C c2 = (MyClass mc,String s1,String s2)->mc.method(s1, s2);
        C c3 = MyClass::method;
        
        D d2 = ()->MyClass.staticMethod();
        D d3 = MyClass::staticMethod;
        
        E e2 = (s)->System.out.println(s);
        E e3 = System.out::println;
    }
}
​
interface A{
    void act(MyClass mc);
}
interface B{
    void act(MyClass mc , String s);
}
interface C{
    void act(MyClass mc , String s1 , String s2);
}
interface D{
    void act();
}
interface E{
    void act(String s);
}
​
class MyClass{
    public void method() {
        System.out.println("method()");
    }
    public void method(String s) {
        System.out.println("method(String)");
    }
    public void method(String s , String s2) {
        System.out.println("method(String,String)");
    }
    
    public static void staticMethod() {
        System.out.println("Static Method");
    }
}
构造方法引用
        ()->new Teacher();
        Teacher::new
            
        (int a)->new Teacher(a);
        Teacher::new
            
        (String s)->new Teacher(s);
        Teacher::new
            
        (int a, String s)->new Teacher(a,s);
        Teacher::new
 

 

JDK8对集合的遍历

 

接口的新语法:
    接口中可以定义默认方法  default void print(){} --->since JDK8
    接口中可以定义静态方法  static void print(){}   --->since JDK8
    接口中可以定义私有方法   since JDK9



函数式接口: 函数描述符

接口名,方法名不重要;方法参数和返回值重要

  • Runnable    ()-> Void

  • Callable    ()-> T

接口名方法名函数描述符含义
Predicate<T>test()T->boolean判断
Consumer<T>accept()T->void消费
Function<T,R>apply()T->R转换
Supplier<T>get()()->T供应商
BiConsumer<T,U>accept()(T,U)->void复杂特化
BiFunction<T,U,R>apply()(T,U)->R复杂特化
UnaryOperator<T>apply()T->T复杂特化
IntFunction<R>apply()int->R基本类型特化
ToIntFunction<T>applyAsInt()T->int基本类型特化

Stream  函数式数据处理

集合: 负责数据的存储

Stream: 处理集合中数据的运算

 

 

获得Stream<T>
   来自Collection   stream(): 获得单线程的Stream
   来自Collection   parallelStream():获得并发的Stream //底层用fork-join实现
   来自Arrays.stream(T[])    返回值Stream<T>
   来自Files.lines(Path)   Stream<String>  读取文本文件,并把每行文本放入Stream<String>
   注:Map没有stream()方法
Stream<String> s = Files.lines(Paths.get("a.txt"));   处理英文
Stream<String> s = Files.lines(Paths.get("a.txt") , Charset.forName("GBK"));  处理中文

 

中间操作

java.util.stream包下,Stream类中,方法的返回值还是stream的都是中间操作

方法名操作描述
filter(Predicate)对流中的数据做过滤
distinct()去掉流中的重复元素
limit(int n)取流中的前n个元素
skip(int n)跳过流中的前n个元素
sorted()/sorted(Comparator)自然排序/排序
map(Function<T,R>):T是流的泛型,R是结果泛型Stream<R> 对每个元素应用函数,将T对象转换为R对象存入Stream

收集操作/终端操作

java.util.stream包下,Stream类中,方法的返回值不是stream的

方法名返回值操作描述
allMatch/anyMatch/noneMatch  (Predicate<T>)boolean判断流中的元素是否能够匹配条件
count()long <br />流中可以装无限多数据返回流中的元素数量
forEach(Consumer<T>)   T->voidvoid对流中的所有元素做遍历
max/min (Comparator<T>)Optional<T>找出最大的元素/最小的元素
findAny()/findFirst()Optional<T>从流中找出任一个/第一个元素
collect(Collector<T,A,R>)R收集元素

收集器 Collector<T,A,R>

T:流中的元素类型

R:收集之后的结果类型

Collectors 直接获得Collector

Collectors的方法返回值是一个Collector, Collector的第三泛型才是collect方法的返回值

方法参数第三泛型方法描述
counting()Long统计个数
summingInt()T->intInteger对整数求和
averagingInt()T->intDouble对整数求平均数
minBy()/maxBy()(T,T)->intOptional<T>求最小/最大值
summarizingInt()T->intIntSummaryStatistics统计个数,总和,平均数,最大值,最小值
toList()/toSet()List<T>/Set<T>将Stream中的元素放入List/Set
toMap()T->K,T->UMap<K,U>将Stream中的元素放入Map
toConcurrentMap()T->K,T->UConcurrentMap<K,U>将Stream中的元素放入ConcurrentMap
joining()String将Stream中的字符串拼接成String
collectingAndThen()Collector<T,?,R>,<br>R->RRRR先收集数据,然后对数据做转换
mapping()T->U,Collector<U,?,R>R先对元素做转换,再收集数据
groupingBy()T->KMap<K,List<T>>将每个元素转换为K对象,并以K对象作为分组依据,将所有元素分组,形成Map
groupingBy()T->K,Collector<T,?,D>Map<K,D>分组后,再对分组结果做收集
partitioningBy()T->booleanMap<Boolean,List<T>>根据谓词条件,分成2组
partitioningBy()T->boolean,Collector<T,?,D>Map<Boolean,D>分区后,在对分区结果做收集

 

 

原始流特化

IntStream  LongStream  DoubleStream

获得原始特化流的方法:
Stream<T>  调用  mapToInt(T->int)
IntStream.range(a,b)    a ---> b-1
IntStream.rangeClosed(a,b)  a--->b
IntStream.generate(()->int ) 由函数生成每个元素
IntStream.iterate(a,int->int) 第一个元素是a,利用函数,通过前一个元迭代计算后一个元素
方法:
average()  OptionalDouble   求平均数
sum() int   求和
boxed() Stream<Integer>

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值