Java中Lambda表达式与反射

一、函数式编程思想和Lambda表达式定义格式

面向对象思想:是Java的核心编程思想

强调的是找对象,帮我们做事儿

比如->去北京->强调的是怎么去,火车,高铁,飞机,汽车,自行车,腿儿

jdk8开始又了个新的思想:函数式编程思想

强调的是结果,不强调过程

比如:去北京->只强调去了还是没去

Lambda表达式:

定义格式:()->{}

各部分解释:():重写方法的参数位置

->:将参数传递到方法体中

{}:重写方法的方法体

public class Demo01Lambda {
    public static void main(String[] args) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("我执行了");
            }
        }).start();
        System.out.println("=========");

        //lambda表达式

        new Thread(()-> { System.out.println("我执行了"); }).start();
    }
}

Lambda表达式使用前提

  1. 必须是函数式接口做方法传递
  2. 啥叫函数式接口:

   有且只有一个抽象方法的接口,用@FunctionInterface去检测

Lambda表达式省略规则

怎么写?

  1. 观察是否是函数式接口做方法参数传递
  2. 如果是,考虑使用Lambda表达式
  3. 调用方法,以匿名内部类的形式传递实参
  4. 从new接口开始到重写方法的方法名结束,选中,删除,别忘记在删除一个右半个大括号
  5. 在重写方法的参数后面,方法体的大括号前面加上  ->

省略规则:

重写方法的参数类型可以干掉

如果重写方法只有一个参数,所在的小括号可以干掉

如果方法体中只有一句话,那么所在的大括号以及分号部分可以干掉

如果方法体中只有一句话并且带return的,那么所在的大括号分号以及return可以干掉

/*
1.观察是否是函数式接口做方法参数传递
2.如果是,考虑使用Lambda表达式
3.调用方法,以匿名内部类的形式传递实参
4.从new接口开始到重写方法的方法名结束,选中,删除,别忘记在删除一个右半个大括号
5.在重写方法的参数后面,方法体的大括号前面加上  ->*/

public class Demo02Lambda {

    public static void main(String[] args) {


        method(new USB() {
            @Override
            public void open() {
                System.out.println("让usb打开了");
            }
        });


        System.out.println("==========lambda表达式===========");

        method(() ->{ System.out.println("让usb打开了"); });


        method(() ->System.out.println("让usb打开了"));

    }

    /*
    *
    *
    *
    * @param  usb
    * */

    private static void method(USB usb) {
        usb.open();
    }
}
@FunctionalInterface
public interface USB {
    void open();
}
public class Person {
    private String name;
    private Integer age;

    public Person() {
    }

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class Demo03Lambda {
    public static void main(String[] args) {

        ArrayList<Person> list = new ArrayList<>();
        list.add(new Person("张三",10));
        list.add(new Person("李四",9));
        list.add(new Person("王五",8));

        Collections.sort(list, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });

        System.out.println("======================Lambda==============");
        Collections.sort(list, (Person o1, Person o2) ->{ return o1.getAge()-o2.getAge(); });


        System.out.println("======================Lambda简化==============");
        Collections.sort(list, ( o1,  o2) -> o1.getAge()-o2.getAge());
        System.out.println(list);

    }
}

二、函数式接口

函数式接口:有且只有一个抽象方法的接口

检测:@FunctionalInterface

@FunctionalInterface
public interface USB {
    void open(String s);
}
public class Test01 {
    public static void main(String[] args) {

        method(new USB() {
            @Override
            public void open(String s) {
                System.out.println(s+"开启了");
            }
        });


        System.out.println("===========Lambda======");
        method((String s)-> {
                System.out.println(s+"开启了");
        });
        System.out.println("===========Lambda======");
        method(s-> System.out.println(s+"开启了"));


    }


    public static void method(USB usb){
        usb.open("鼠标");
    }
}

1.Supplier接口

java.util.function.Supplier<T>接口,它意味着“供给”->我们想要什么就给什么

方法:

T   get()->我们想要什么,get方法就可以返回什么

需求:使用Supplier接口作为方法的参数

用Lambda表达式求出int数组中的最大值

泛型:<引用数据类型>->规定了我们操作的数据是什么类型

<>最终只能写引用数据类型,不能写基本数据类型

import java.util.Arrays;
import java.util.function.Supplier;

public class Demo01Supplier {
    public static void main(String[] args) {

        method(new Supplier<Integer>() {
            @Override
            public Integer get() {
                int[] arr={4,3,4,6,7};
                Arrays.sort(arr);
                return arr[arr.length-1];
            }
        });

        System.out.println("====================");

        method(() ->{
                int[] arr={4,3,4,6,7};
                Arrays.sort(arr);
                return arr[arr.length-1];
        });


    }



    public static void method(Supplier<Integer> supplier){
        Integer max=supplier.get();//让get方法返回一个数组最大值
        System.out.println("max="+max);



    }
}

2.Consumer

java.util.function.Consumer<T>->消费型接口->操作

方法:void  accept(T  t)意为消费一个指定泛型的数据

“消费”就是“操作”,至于怎么操作,就看重写accept方法之后,方法体怎么写了

import java.util.function.Consumer;

public class Demo02Consumer {
    public static void main(String[] args) {

method(new Consumer<String>() {
        @Override
        public void accept(String s) {
        System.out.println(s.length());
    }
},"abcdefg");


        System.out.println("================");
        method(s-> System.out.println(s.length()),"abcdefg");

    }


    public static void method(Consumer<String> consumer,String s){
        consumer.accept(s);
    }
}

3.Function

java.util.function.Function<T,R>接口用来根据一个类型的数据得到另一个类型的数据

方法:

R  apply(T  t)根据类型T参数获取类型R的结果

import java.util.function.Function;

public class Demo03Function {
    public static void main(String[] args) {


        method(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) {
                return integer+"";
            }
        },100);

        System.out.println("=============");
        method(integer-> integer+"",100);
    }
    
    public static void method(Function<Integer,String> function,Integer number){
        String s=function.apply(number);
        System.out.println("s="+(s+1));
    }
}

4.Predicate

java.util.function.Predicate<T>接口->判断型接口

   boolean  test(T t)->用于判断的方法,返回值为boolean型

import java.util.function.Predicate;

public class Demo04Predicate {
    public static void main(String[] args) {

        method(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length()==7;
            }
        },"abcdefg");
        System.out.println("============");

        method(s->s.length()==7,"abcdefg");
    }

    public static void method(Predicate<String> predicate,String s){
        boolean test=predicate.test(s);
        System.out.println("test="+test);
    }
}

三、Stream流

Stream流中的“流”不是特指“IO流”它是一种“流式编程”(编程方式),可以看做是“流水线”

1.Stream的获取

针对集合:Collection中的方法

Stream<E> stream()

针对数组:Stream接口中的静态方法

static<T>  Stream<T>  of(T.....values)

import java.util.ArrayList;
import java.util.stream.Stream;

public class Demo01Stream {
    public static void main(String[] args) {
        //针对集合:collection中的方法

        ArrayList<String> list = new ArrayList<>();
        list.add("张三");
        list.add("李四");
        list.add("王五");
        Stream<String> stream = list.stream();
        System.out.println(stream);

        //针对数组String接口中的静态方法

        Stream<String> stream1=Stream.of("武松","李青","李逵");
        System.out.println(stream1);

    }
}

2.Stream的方法

(1)Stream中的forEach方法:void  forEach(Consumer<? super T>action)

forEach:逐一处理->遍历

void  ForEach(Consumer<? super  T>action)

注意:forEach方法是一个终结2方法,使用完之后,Stream流不能使用了

(2)Stream中的long  count()方法

作用:统计元素个数

注意:count也是一个终结方法

(3)Stream中的long  count()方法

作用:统计元素个数

注意:count也是一个终结方法

(4)Stream中的Stream<T> filter(Predicate<? super T>predicate)方法

方法:Stream中的Stream<T> filter(Predicate<? super T>predicate)方法,返回一个新的Stream流对象

作用:根据某个条件进行元素过滤

(5)Stream<T> limit(long  maxSize):获取Stream流对象按那个中的前n个元素返回一个新的Stream流对象

Stream<T> limit(long  maxSize):获取Stream流对象按那个中的前n个元素返回一个新的Stream流对象

(6)Stream<T> slip(long n):跳过Stream流对象中的前n个元素,返回一个新的Stream流对象

Stream<T> slip(long n):跳过Stream流对象中的前n个元素,返回一个新的Stream流对象

(7)static<T> Stream<T>  concat(Stream<?  extends  T>a,Stream<? extend T>b):两个流合成一个流

static<T> Stream<T>  concat(Stream<?  extends  T>a,Stream<? extend T>b):两个流合成一个流

import java.util.function.Consumer;

import java.util.stream.Stream;

public class Demo02Stream {
    public static void main(String[] args) {
        //foreach();

    //    count();

   //     filter();

      //  limit();

      //  slip();

        concat();
    }

    private static void concat(){
        Stream<String> stream1=Stream.of("武松","李青","李逵","诸葛");
        Stream<String> stream2=Stream.of("武","李","李","诸");

        Stream.concat(stream1,stream2).forEach(s -> System.out.println(s));


    }

    private static void slip() {
        Stream<String> stream1=Stream.of("武松","李青","李逵","诸葛");
        stream1.skip(2).forEach(s -> System.out.println(s));


    }

    private static void limit() {
        Stream<String> stream1=Stream.of("武松","李青","李逵","诸葛");
        stream1.limit(3).forEach(s -> System.out.println(s));


    }


    private static void filter() {
        Stream<String> stream1=Stream.of("武松","李青","李逵","诸葛");
     /*stream1.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length()==2;
            }
        }).forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });*/
        System.out.println("==============");
stream1.filter(s -> s.length()==2).forEach(s -> System.out.println(s));





        /*newStream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
*/
    }

    /*
*
*
* 统计元素个数
*
* */
    private static void count() {

        Stream<String> stream1=Stream.of("武松","李青","李逵");
        long count=stream1.count();
        System.out.println("count="+count);

    }

    /*
    * 逐一处理,可以用来遍历
    *
    * */
    private static void foreach() {

        Stream<String> stream1=Stream.of("武松","李青","李逵");
        stream1.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });

        System.out.println("=================");
        stream1.forEach( s-> System.out.println(s));

    }
}

四、方法引用

1.方法引用介绍

概述:引用方法

啥时候使用:

  被引用的方法要写在重写方法里面

  被引用的方法从参数上,返回值上要和所在的重写方法一致,而且引用的方法最好是操作重写方法的参数值的

  干掉重写方法的参数;干掉->;干掉被引用方法的参数->将被饮用方法的.改成::

import java.util.function.Consumer;
import java.util.stream.Stream;

public class Demo01Method {
    public static void main(String[] args) {

        Stream<String> stream = Stream.of("今天", "明天", "后天");

            /*
            * accept是重写方法:参数类型string  无返回值
            *
            * accept方法里面有println方法:println参数类型位String被引用的方法操作重写方参数值println没有返回值
            *
            * */
        /*stream.forEach(new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        });
*/
        System.out.println("==================");

      //  stream.forEach( s-> System.out.println(s));
        System.out.println("==================");

        stream.forEach( System.out::println);

    }
}

2.对象名-引用成员方法

使用对象名引用成员方法

格式:

对象::成员方法名

需求:

函数式接口:Supplier

  java.util.function.Supplier<T>接口

抽象方法:

 T get()用来获取一个泛型参数指定类型的对象数据

Supplier接口使用什么泛型,就可以使用get方法获取一个什么类型的数据

import java.util.function.Supplier;

public class Demo02Method {
    public static void main(String[] args) {


        /*
        *
        * get为重写方法无参的返回值位string
        * trim方法在get中无参的返回值为string
        * 考虑使用方法引用
        *
        * */
        method(new Supplier<String>() {
            @Override
            public String get() {
                return " abc ".trim();
            }
        });

        System.out.println("=============");

        method(()->" abc ".trim());

        System.out.println("====================");

        method(" abc "::trim);



    }

    public static void method(Supplier<String> supplier){
        String s=supplier.get();
        System.out.println("s="+s);
    }
}

3.类名-引用静态方法

类名-引用静态方法

格式:

类名::静态成员方法

4.类-构造引用

类-构造方法引用

格式:

构造方法名称::new

5.数组-数组引用

数组-数组引用

格式:

数组中的数据类型[]::new

int[]::new  创建一个int型的数组

double[]::new  创建于一个double型的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值