栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java基础(二十二)——反射(获取属性)、jdk8 与 jdk9 接口的特性概念、Lambda表达式、四个函数式接口(Supplier、Consumer、Predicate、Function)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java基础(二十二)——反射(获取属性)、jdk8 与 jdk9 接口的特性概念、Lambda表达式、四个函数式接口(Supplier、Consumer、Predicate、Function)

Java基础(二十二)——反射(获取属性) 一、反射 1、获取属性

反射前面讲了这么多,就只剩下获取属性没讲。
先看下反射获取属性的方法:

学生类的属性:

2、getFields()——获得所有公开的属性


然后效果:

3、getDeclaredFields()——获得所有属性(包括私有的)

效果:

4、getField()——获得单个公有的属性

私有同理,就不再作演示了。

二、jdk8 与 jdk9 接口的特性概念 1、概念

概念:在jdk8与jdk9之后,接口不仅可以存在抽象方法,还可以有普通的成员方法。

2、增加内容

jdk8:增加的静态方法与默认方法。
jdk9:增加了私有的方法

3、影响

接口中可以存在抽象方法,也可以存在普通的成员方法。

所以接口与抽象类的差距缩小,接口可以多继承,所以在实际的开发中大部分使用接口来定义。

4、接口中的默认方法 a、了解
1、概念:在jdk8之后,接口才能增加默认的方法
2、默认方法使用的关键字: default
3、语法: 访问修饰符 default 返回值类型 方法的名称 (参数列表) {方法体}
4、注意点:
	A.接口中的默认方法,必须通过实例化实现类才能进行调用。
	B.接口中的默认方法,实现类不是必须强制性需要重写。
	C.接口的实现类,需要调用接口中的默认方法,必须通过  接口的名称.super.方法名()。
b、调用方法一

先来看下接口:

然后是实现类:

然后调用:

通过多态创建对象,然后通过这个对象直接调用接口的默认方法。

c、调用方法二:

通过实现类的对象来调用接口的默认方法,但是前提必须是实现类中的方法通过 super 调用到接口中的默认方法。

5、接口中的静态方法 a、了解
1.概念:在jdk8之后,接口中才能存在静态方法。
2.使用的关键字修饰:static
3.语法: 访问修饰符 static 返回值类型 方法的名称 (参数列表) {方法体}
4.注意点:
	A.接口中定义方法,不必须强制进行重写。
	B.接口静态方法,只能通过接口的名称来进行调用。
b、调用

接口代码:

调用:

6、接口中私有的方法 a、了解
1.概念:在jdk9之后,接口中才能定义私有的方法。
2.注意点:
	A.接口中的默认方法是可以调用私有的方法,静态方法不能调用普通私有的方法。
	B.接口中静态的私有方法,默认方法与静态方法都是可以进行调用。
b、调用

由于博主没有搞 jdk 1.9,所以这里以后再补上。

三、Lambda表达式 1、了解 Lambda 表达式

1、本质:Lambda本质是一个接口 是一个匿名接口。

2、前提条件:必须是一个函数式接口,接口中只能有一个抽象方法,但是可以有默认的方法,例
子:Comparable

3、简化匿名内部类的写法。

4、语法:

(参数) ->{
	方法体
}

5、解释:
参数:表示的是接口中抽象方法的参数。
->:Lambda的语法,指向方法体。
{}:执行具体的操作。

2、通过例子了解 Lambda 表达式 a、通过匿名内部类创建线程,并用 Lambda 表达式简化
public class Demo1 {
    public static void main(String[] args) {
        new Thread(new Runnable() {            //   通过匿名内部类写一个线程
            @Override
            public void run() {
                System.out.println("喵喵喵");
            }
        }).start();{
        };

        new Thread(()->{                    //  Lambda 表达式简化匿名内部类
            System.out.println("喵喵喵");
        }).start();{
        };
    }
}
b、没有参数没有返回值的 Lambda 表达式

通过前面的前提条件,可以了解到,能够使用 Lambda 表达式的前提是必须是一个函数式接口,其他方法不管你有没有,里面只能有一个抽象方法。因此,我们可以手动写这么一个接口,然后自己手动的使用这个 Lambda 表达式。

接口代码:

public interface Inter1 {
    void show1();
}

主函数代码:

public class Demo02 {
    public static void main(String[] args) {
//        show(()->{      //  没有参数没有返回值
//            System.out.println("lambda表达式");
//        });

        show(()-> System.out.println("lambda表达式"));     //  简化。一行搞定。精简了大括号。
    }

    public static void show(Inter1 inter1){     //  实现这个接口
        inter1.show1();
    }
}
c、有参数没有返回值的 Lambda 表达式

接口代码:

public interface Inter2 {
    void show2(String name);
}

主函数代码:

public class Demo03 {
    public static void main(String[] args) {    //  有参数没有返回值

//        show("我是傻批",(String name)->{      //  只有一个参数的 Lambda 表达式
//            System.out.println(name);
//        });
        show("二狗", name -> System.out.println(name));   //  简化写法。只有一个参数的情况下,可以省略数据类型。精简了大括号。
    }

    public static void show(String name,Inter2 inter2){
        inter2.show2(name);
    }
}
d、有参数有返回值的 Lambda 表达式

接口代码:

public interface Inter3 {
    int show3(int a,int b);
}

主函数代码:

public class Demo04 {
    public static void main(String[] args) {
//        System.out.println(show(3, 5, (int a,int b)->{        //  两个参数的 Lambda 表达式。这里省略了接收返回值,直接输出。
//            return a*b;
//        }));

        System.out.println(show(3, 5, (int a,int b) -> a*b ));     //  简化写法。少了大括号和 return 语句。
    }

    public static int show(int a,int b,Inter3 inter3){
        return  inter3.show3(a, b);
    }
}
3、案例:用 Lambda 表达式代替匿名内部类传递比较器

还记得之前的一个排序写法,其中用到的传递比较器方法,当时用的是匿名内部类。这里通过 Lambda 表达式再优化一下:

主函数代码:

public class Demo01 {
    public static void main(String[] args) {
        String[] strArrays = {"a","ab","abc","abcd"};
        Arrays.sort(strArrays,getsort());
        System.out.println(Arrays.toString(strArrays));
    }
    public static Comparator getsort(){
//        return new Comparator() {         //  这里通过匿名内部类传递比较器
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.length()-o2.length();
//            }
//        };

//        return (String s1,String s2) ->{      //  通过 Lambda 表达式精简匿名内部类
//            return s1.length()-s2.length();
//        };

        return (String s1,String s2) -> s1.length()-s2.length();    // 简化写法。精简了大括号和 return 语句。
    }
}

这里的功能是根据字符个数进行排序。

4、Lambda简化方式小结

第一种情况:如果只有一个参数,可以省略其小括号与数据类型。
第二种情况:如果方法体只有一句话,可以省略大括号以及分号。
第三种情况:如果方法有返回值,方法体只有返回值这一句话,可以省略 retrun 分号、大括号。

四、四个函数式接口 1、了解相关知识

1、概念:函数式接口只能有一个抽象方法 可以存在其它的默认方法 以及静态方法。

2、函数式接口使用的注解:@FunctionalInterface 用于来检查是否是函数式接口。

3、函数式接口两种体现形式:
第一种:以函数式接口作为方法的参数。
第二种:以函数式接口作用方法的返回值。

2、Supplier——供给型接口


接口描述:
其实这个接口本身并没有提供什么功能,就是你使用了这个接口,那么就意味着会返回一个结果。至于是返回什么结果,有什么功能,完全由你自己去写。

a、使用供给性接口获取一个字符串

主函数代码:

public class Demo01 {
    public static void main(String[] args) {
//        String str = getStr(()->{         //  lambda 表达式
//            return "牛牛";
//                });

        String str = getStr(() ->"牛牛");  //  简化写法

        System.out.println(str);
    }

    public static String getStr(Supplier sup){
        return sup.get();
    }
}

效果:

b、使用供给性接口获取最小值

主函数代码:

public class Demo02 {
    public static void main(String[] args) {    //  通过供给型接口求出最小值
        
        int a = getStr(()->{    //  Lambda 表达式。下面开始写功能
            int min ;
            int[] nums = {1,8,-20,14,-2,20,9};
            min = nums[0];
            for (int i = 0; i < nums.length; i++) {
                if (min > nums[i]){
                    min = nums[i];
                }
            }
            return min;
        });
        
        System.out.println(a);
    }

    public static int getStr(Supplier supplier){
        return supplier.get();
    }
}
3、Consumer——消费型接口


作用:感觉就是取出一些数据,并对这些数据进行二次处理。

通过例子来了解

a、例子(一) ——取字符串的一部分

使用消费型接口对牛牛子进行消费--->得到的结果是牛牛。

public class Demo01 {
    public static void main(String[] args) {        //  消费型接口消费字符串。也就是取字符串某一部分
        getStr("牛牛子", n->{
            System.out.println(n.substring(0,2));
        });
    }

    public static void getStr(String s, Consumer con){
        con.accept(s);
    }
}
b、例子(二)——将一个字符串转换为大写,再转化为小写。
public class Demo02 {
    public static void main(String[] args) {    //  把字符串先转大写,再转小写.
        getStr("qweasd", (String s)->{
            System.out.println(s.toUpperCase());
        },(String w)->{
            System.out.println(w.toLowerCase());
        });
    }

    public static void getStr(String s, Consumer con1,Consumer con2){
        con1.andThen(con2).accept(s);
    }
}
c、例子(三)——取出数组中的字符串,并重新拼接字符串
//   需求: 对数组进行消费String [] arrays={"迪丽热巴:28","古力娜扎:24","渣渣辉:26"} 消费之后的字符串:
//        	姓名:迪丽热巴,年龄:28 姓名:古力娜扎,年龄:24 姓名:渣渣辉,年龄:26

public class Demo03 {
    public static void main(String[] args) {                //   对数组进行消费
        String [] arrays={"迪丽热巴:28","古力娜扎:24","渣渣辉:26"};
        getStr(arrays,  s->{
            System.out.print("姓名:"+s.split(":")[0]+",");
        }, (w->{
            System.out.println("年龄:"+w.split(":")[1]+"  ");
        }));
    }

    public static void getStr(String[] arrays, Consumer con1,Consumer con2){
        if (arrays != null && arrays.length>0){
            for (int i = 0; i < arrays.length; i++) {       //  对传进来的数组的每一个元素都进行比较
                con1.andThen(con2).accept(arrays[i]);
            }
        }
    }
}
4、Predicate——断言型接口

这个接口的作用就是进行判断处理

a、例子(一)——判断字符串长度是否大于5
public class Demo1 {
    public static void main(String[] args) {
        boolean flag = isFlag("qweasd", s -> {  //  断言型接口 判断字符串长度是否大于5
            return s.length()>5;
        });
        System.out.println(flag);
    }
    public static boolean isFlag(String s, Predicate predicate){
        return predicate.test(s);
    }
}
b、例子(二)——判断字符串长度是否大于5,再判断是否包含a
public class Demo2 {
    public static void main(String[] args) {    // 断言型接口 判断字符串长度是否大于5 判断字符串是否包含a
        boolean flag = isFlag("qweasdz", (s -> {
            return s.length()>5;
        }),(w->{
            return w.contains("a");
        }));
        System.out.println(flag);
    }

    public static boolean isFlag(String s, Predicate s1,Predicate s2){
        return s1.and(s2).test(s);
    }
}
c、例子(三)——将数组里面满足条件的数据添加到集合当中去
public class Demo3 {
    public static void main(String[] args) {    // 断言型接口 定义一个数组 String []array={"迪丽热巴","古丽热娜","苍老师","波多老师","小野老师"}
                                                // 将数组中元素的长度>=4 并且 包含老师 满足条件的数据存入的到集合
        String []array={"迪丽热巴","古丽热娜","苍老师","波多老师","小野老师"};
        List list =  isFlag(array, (s)->{
            return s.length()>=4;
        },(w)->{
            return w.contains("老师");
        });
        System.out.println(list);
    }

    public static List isFlag(String[] arrays, Predicate pre1,Predicatepre2){
        List list = new ArrayList<>();
        if (arrays!= null && arrays.length >0){
            for (int i = 0; i < arrays.length; i++) {
                if (pre1.and(pre2).test(arrays[i])){
                    list.add(arrays[i]);
                }
            }
        }
        return list;
    }
}
5、Function——函数型接口

目前感觉的作用是处理不同类型之间的转换

a、例子(一)——将 String 类型转换为 int 类型
public class Demo1 {
    public static void main(String[] args) {    //  使用函数型接口 将String类型转换为int类型
        int num = getStr("123", (s)->{
            return Integer.parseInt(s);		//	String 类型数据转换为 int 类型
        });
        System.out.println(num);
    }

    public static int getStr(String s, Function fun){
        return fun.apply(s);
    }
}
b、例子(二)——将 String 类型里面的数据除杂,最后取出里面的 int 类型
public class Demo2 {        //  使用函数型接口 将String(华子 12) 转换为 String 12 再将String 转换int 12
    public static void main(String[] args) {
        int num = getStr("华子 12", (s -> {
            return s.split(" ")[1];		//	以空格切割,切割之后是数组,取出 int 类型的数据
        }),(w->{
            return Integer.parseInt(w);
        }));
        System.out.println(num);
    }

    public static int getStr(String s, Function fun1,Function fun2){
        return fun1.andThen(fun2).apply(s);
    }
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/591330.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号