【Java基础概述-8】Lambda表达式概述、方法引用、Stream流的使用

1、Lambda表达式概述

        什么是Lambda表达式?

        Lambda表达式是JDK1.8之后的新技术,是一种代码的新语法

        是一种特殊写法。

        作用:“核心的目的是为了简化匿名内部类的写法”。

        

        Lambda表达式的格式:

        (匿名内部类被重写的形参列表){

        被重写的代码

        }

        使用前提:

        Lambda表达式并不能简化所有匿名内部类的写法

        Lambda表达式只能简化接口中只有一个抽象方法的匿名内部类形式。

        Lambda表达式只能简化函数式接口的匿名内部类写法:

        首先是接口,其次只有一个抽象方法。

1.1、函数式接口

        @FunctionalInterface函数式接口注解:

        一旦某个接口加上这个注解,这个接口有且只有一个抽象方法。

        这个接口可以用Lambda表达式简写。

        如Runnable线程任务接口:

public class LambdaDemo02 {
    public static void main(String[] args) {
//        Thread thread = new Thread(new Runnable() {
//            @Override
//            public void run() {
//
//            }
//        });
        //Runnable
        //简写后:
        new Thread(()->{
            System.out.println(Thread.currentThread().getName()+"执行");
        }).start();
    }
}

         1.如果Lambda表达式的方法体只有一行代码,可以省略大括号不写,同时省略分号。

        此时,如果这串代码有return语句,可以省略return 和;不写。

        2.参数类型可以不写

       3.如果只有一个参数,可以省略(和)不写

    public static void main(String[] args) {
        Set<Student> t = new TreeSet<>((o1,o2)->
           o1.getAge()-o2.getAge()
        );
        t.add(new Student("查尔斯",30));
        t.add(new Student("张三",20));
        t.add(new Student("里斯",23));
        System.out.println(t);
    }
}

public class LambdaDemo {
    public static void main(String[] args) {
        List<String> names =new ArrayList<>();
        names.add("欧拉");
        names.add("理查德");
        names.add("特斯拉");
//        names.forEach(new Consumer<String>() {
//            @Override
//            public void accept(String s) {
//                System.out.print(s+" ");
//            }
//        });
        names.forEach(s-> System.out.println(s));
        System.out.println("\n-----");
        names.forEach(s -> System.out.println(s));


    }
}

2、方法引用

        概述:方法引用是为了进一步简化Lambda表达式的写法。

        方法引用的格式,类或者对象::引用的方案

        关键语法是“”::“”。

        


        方法引用的方式:

        1.静态方法的引用

        2.实例方法的引用

        3. 特定类型的引用

        4.构造器的引用

        例子:

public class MethodDemo01 {
    public static void main(String[] args) {
        List<String> names =new ArrayList<>();
        names.add("欧拉");
        names.add("理查德");
        names.add("特斯拉");
        names.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.print(s+" ");
            }
        });
        System.out.println("\n-----");
        names.forEach(System.out::println);

    }
}

 2.1、静态方法的引用

        引用格式:

        类名::静态方法名。

        注意事项:

        1.被引用的方法参数列表要和函数式接口中的抽象方法的参数列表一致

        如果函数式接口中抽象方法有返回值,则被引用的方法也需要有返回值。

        如果函数式接口中的抽象方法没有返回值,则被引用的方法可以有返回值也可以没有

package _04方法引用方式一_静态方法的引用;

public class Student{
    private String name;
    private int age;


    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    public static int compareTo(Student o1,Student o2) {
        return o1.getAge()-o2.getAge();
    }
}

        

public class MethodDemo01 {
    public static void main(String[] args) {
        ArrayList<Student> s = new ArrayList<>();
        Student s1 = new Student("理查德", 30);
        Student s2 = new Student("查理斯", 25);
        Student s3 = new Student("张三", 20);
        Collections.addAll(s,s1,s2,s3);

//        Collections.sort(s,(o1,o2)->o1.getAge()-o2.getAge());
//        Collections.sort(s,(o3,o4)->Student.compareTo(o3,o4));
        Collections.sort(s,Student::compareTo);//类名::静态方法名
        s.forEach(System.out::println);
    }
}

2.2、实例方法的引用 

        格式:对象::实例方法。

        简化步骤:

        a.定义一个实例方法,把需要的代码放到实例方法中。

        b.被引用的方法参数必须和函数式接口中的抽象方法参数一样

        

public class MethodDemo {
    public static void main(String[] args) {
        List<String> names =new ArrayList<>();
        names.add("欧拉");
        names.add("理查德");
        names.add("特斯拉");
        names.forEach(s -> System.out.println());//对象::实例方法
        System.out.println("\n-----");
        names.forEach(System.out::println);//对象::实例方法
    }
}

2.3、特定类型的引用

        特定类型:类似String的包装类

        特定类型::方法

public class MethodDemo {
    public static void main(String[] args) {
        String[] strings =new String[]{"Jxx","sxxx","aaxx","Axxx","Bcc","bcc"};
//        Arrays.sort(strings, new Comparator<String>() {
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.compareToIgnoreCase(o2);
//            }
//        });
//        Arrays.sort(strings, (String o1, String o2)-> o1.compareToIgnoreCase(o2));
        Arrays.sort(strings, String::compareToIgnoreCase);
        System.out.println("-------");
        for (String string : strings) {
            System.out.println(string);
        }
    }
}

2.4、构造器引入

                格式:类名::new

                引入的格式需要: s -> new Student(s) =>Student::new

                小结:方法引入可遇不可求

public class ConstractorDemo01 {
    public static void main(String[] args) {
        ArrayList<String> lists = new ArrayList<>();
        lists.add("java1");
        lists.add("java2");

        //集合默认只能转换成Object数组
//        Object[] array = lists.toArray();
//        System.out.println(Arrays.toString(array));
        //我们想转成字符串应该如何做?
        //最新的写法可以结合构造器引用实现!!
        String[] str1 =lists.toArray(new IntFunction<String[]>() {
            @Override
            public String[] apply(int value) {
                return new String[value];
            }
        });
//      String[] str =   lists.toArray(s -> new String[s] );
      String[] str2 =   lists.toArray(String[]::new);
        System.out.println(Arrays.toString(str2));


    }
}

3、Stream流

        目标:了解Stream流的强大

        什么是Stream流?

        在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream流的概念,用于解决已有集合/类库既有的弊端。

        Stream流能解决什么问题?

        可以解决已有集合类库或者数组API的弊端。

        Stream认为集合和数组的API很不友好,所以采用Stream流简化集合和数组的操作!!!
        

public class StreamDemo {
    public static void main(String[] args) {
        ArrayList<String> str = new ArrayList<>();
        str.add("张三");
        str.add("里斯");
        str.add("张无忌");
        str.add("张三丰");
        str.stream().filter(s -> s.startsWith("张")).filter(s->s.length()==3).forEach(System.out::println);
    }
}

3.1、Stream流的获取

        

 Stream流式思想思想的核心:

        先得到集合或者数组的Stream流(就是传送带)

        然后用这个Stream流操作集合或者数组元素。

         

        集合获取流的API接口:

        default stream<E> stream();

        集合获取stream流:

        list/set.stream()

        数组获取stream流:

        Arrays.stream(数组)/Stream.of(数组)

public class StreamDemo {
    public static void main(String[] args) {
        /*Collection集合获取Stream流*/
        Collection<String> collection =  new ArrayList<>();
        Stream<String> stream = collection.stream();
        /*Map集合获取Stream流*/
        HashMap<String, Integer> map = new HashMap<>();
        map.put("ID",1);
        map.put("money",100);
        Stream<String> stream1 = map.keySet().stream();//获取键流
        Stream<Integer> stream2 = map.values().stream();//获取值流
        Stream<Map.Entry<String, Integer>> stream3 = map.entrySet().stream();
        stream3.forEach(System.out::println);
        /*集合获取String流*/
        String[] s = new String[]{"张三","李四","王五"};
        Stream<String> stream4 = Arrays.stream(s);
        //或者
        Stream<String> stream5 = Stream.of(s);

    }
}

3.2、Stream流的常用API

        forEach():遍历

        count():统计个数

        filtert():过滤元素

        limit():取前几个元素

        skip():跳过前几个

        map(s->xxxx):加工方法

        concat():合并流        

        看懂下面代码即可弄懂

public class StreamDemo {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        list.stream().filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length()==3;
            }
        }).filter(s->s.startsWith("张")).forEach(System.out::println);

        long count = list.stream().filter(s -> s.length() == 3).count();
        System.out.println(count);

        list.stream().filter(s->s.startsWith("张")).limit(1).forEach(System.out::println);
        list.stream().filter(s->s.startsWith("张")).skip(1).forEach(System.out::println);
    }
}

public class StreamDemo02 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");

        //把名字都加上"厉害的+xxxx"
        list.stream().map(s->"厉害的"+s).forEach(System.out::println);

//        把其创建成学生对象
        list.stream().map(s->new Student(s)).forEach(System.out::println);
    }
}
public class StreamDemo03 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("张无忌");
        list.add("周芷若");
        list.add("赵敏");
        list.add("张强");
        list.add("张三丰");
        Stream<String> stream = list.stream();
        Stream<Integer> integerStream = Stream.of(10, 20, 40, 50);
        Stream<Object> concat = Stream.concat(stream, integerStream);
        concat.forEach(System.out::println);
    }
}

 3.3、Stream流的收集

        Stream流的作用是:把集合转换成一个传送带,借用Stream流的强大功能进行操作。

        但是实际开发中数据以最终形式还应该是集合,最终Stream流操作完毕以后还是要转换成集合。这就是Stream流。

        Stream流只是手段,集合才是目的

        格式:

        stream.collect(Collectors.toSet()/toList())

        stream.toArray(String[]::new)

public class StreamDemo {
    public static void main(String[] args) {
        List<String> one = new ArrayList<>();
        one.add("张三丰");
        one.add("张无忌");
        one.add("张小凡");
        one.add("周芷若");
        one.add("吕布");
        one.add("李小川");
        Stream<String> z = one.stream().filter(s -> s.startsWith("张"));
        /*
        * 收集成Set集合
        * */
//        Set<String> collect = z.collect(Collectors.toSet());
//        collect.forEach(System.out::println);
        /*
        * 收集成List集合
        * */
//        List<String> list = z.collect(Collectors.toList());
//        Iterator<String> iterator = list.iterator();
//        while (iterator.hasNext()) System.out.println(iterator.next());
        /*
        *
        * 转换成数组
        * */
//        String[] s =z.toArray(new IntFunction<String[]>() {
//            @Override
//            public String[] apply(int value) {
//                return new String[0];
//            }
//        })
//
        String[] s =z.toArray(String[]::new);
        for (String string : s) {
            System.out.println(string);
        }
    }

}

本次小结: 

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

努力奋斗的张同学

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

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

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

打赏作者

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

抵扣说明:

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

余额充值