Java第十五天(实训学习整理资料(十四)Java8中的常用新特性)

目录

一、Lambda表达式

特点:

二、函数式接口

1、特点:

2、函数式接口分类

三、方法引用和构造引用

1、方法引用

2、构造引用

四、Stream(流) API

1、定义

2、特点

3、流处理中的持续执行(中间方法)和终止方法

4、如何将数据集转化为Stream

五、接口中的默认方法和静态方法

六、日期时间API

七、OPtional(重要)

1、定义

2、常用方法

八、反射

1、定义

2、反射中所涉及的类

3、获取class的三种方式


一、Lambda表达式

        lambda表达式就是匿名函数,匿名函数可以作为参数传递,表示数据。目的是让代码更加简洁,开发更高效!

        (参数1,参数2...)->{函数体}

特点:

        * 参数的类型可以不写,lambda表达式可以根据上下文进行推断
        * 函数体如果只有一行代码,大括号可以不写。
        * 如果只有一行代码并且是作为返回值使用,则return也可以不写
        * lambda表达式与函数式接口绑定出现

案例1:利用lambda表达式改写Thread线程对象构建

//lambda表达式
        Thread thread = new Thread(() -> {
            System.out.println("倒数:3");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("倒数:2");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("倒数:1");
        });
        thread.start();

案例2:参数根据上下文自动推算

//参数x和y的类型进行了自动推算
        MyLambdaTest myLambdaTest = (x, y)->x+y;    //()->{return x+y;}

		interface MyLambdaTest{
			default void printName(){
				System.out.println(this.getClass().getName());
			}

			int sum(int a, int b);
		}

二、函数式接口

1、特点:

        只包含一个抽象方法的接口就是函数式接口。

        如果需要将接口设置为函数式接口,可以在接口上添加注解:

        @FunctionalInterface

2、函数式接口分类

jdk内置的函数式接口:

        java.util.function:(Function、Consumer、Supplier、Predicate)

函数型接口:有输入参数,也有返回值。Function

案例:

Function<String, Integer> fumc = (x)->x.length();

    Integer nihao = fumc.apply("nihao");
    System.out.println(nihao);

消费型接口:有参数,没有返回值。Consumer

供给型接口:没有参数,有返回值。Supplier

断言型接口:有输入参数,也有返回值,返回boolean类型。Predicate

补充案例:java支持不定长参数

public static void nums(int ... n){
			//System.out.println(n instanceof int[]);
			int sum = 0;
			for (int num:n) {
				sum+=num;
			}
			System.out.println("所有数值的总和是:"+sum);
		}

三、方法引用和构造引用

1、方法引用

        当要传递给Lambda体的操作已经有实现方法,可以直接使用方法引用

        写法:

        对象/类::方法名 //仅仅是引用但不执行

案例:

lambda:
		Consumer<String> consumer = (x)-> System.out.println(x);
        consumer.accept("hello world");

        lambda+函数引用:
        Consumer<String> consumer = System.out::println;	//此处只是引用out对象的println方法,而不是调用
        consumer.accept("hello world");
2、构造引用
//普通构造引用
	
	Supplier<Students> students = Students::new;
    students.get().printClassInfo();
	
	class Students{
		public void printClassInfo(){
			System.out.println(this.getClass().getName());
		}
	}
	
	//数组构造引用
	  //可以传递一个参数(表示数组长度),返回数组对象,通过相应类型的构造引用创建对象。
	  Integer[] arr = new Integer[5];
	  Function<Integer, Integer[]> integersFunc = (len)->new Integer[len];
	  //Integer数组的构造引用
	  Function<Integer, Integer[]> integersFunc1 = Integer[]::new;
	  Integer[] apply = integersFunc1.apply(6);
	  System.out.println(Arrays.toString(apply));

四、Stream(流) API

1、定义

        jdk1.8提供的一种数据流水线的处理API。

2、特点

        * Stream不会存储数据
        * Stream在处理完成后会返回一个持有新数据的Stream对象
        * Stream中存在持续执行和终止执行的方法(延迟现象)

3、流处理中的持续执行(中间方法)和终止方法

1-中间方法:(流水线的一个操作,不会导致流程结束)

        map (mapToInt, flatMap 等)、 filter、 distinct、

        sorted、 peek、 limit、 skip、 parallel、

        sequential、 unordered

2-终止方法:(调用后,流程结束)

        forEach、 forEachOrdered、 toArray、 reduce、

        collect、 min、 max、 count、 anyMatch、 allMatch、

        noneMatch、 findFirst、 findAny、 iterator

案例1:将流中的数据进行foreach遍历

int[] ints = {12, 25, 66, 71, 45, 99};
IntStream stream = Arrays.stream(ints);
stream.forEach(System.out::println);

案例2:通过中间方法filter过滤数据集中的大于等于60分的值

stream.filter((a)->(a>=60)?true:false).forEach(System.out::println);
4、如何将数据集转化为Stream

1-数组

        Arrays工具类中的stream方法

2-集合

        集合类身上具有stream方法

3-Stream自带的方法

        Stream.of(T ... data)

五、接口中的默认方法和静态方法

        默认方法: 被default修饰的方法。

        静态方法:直接通过接口名调用,而不需要创建接口的实现类实例。

六、日期时间API

        LocalDate; //日期

        LocalTime; //时间

        LocalDateTime; //日期时间

案例:

//获取当前时间
		  LocalDateTime now = LocalDateTime.now();
		  //System.out.println(now.toString());

		  //日期时间格式化输出
		  String format = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
		  System.out.println(format);

		  //5天之后的日期
		  LocalDateTime localDateTime = now.plusDays(5);
		  System.out.println(localDateTime.toString());

		  //计算两个日期之间相差的天数
		  //创建未来某个日期的对象: 2023-1-15 10:00:00
		  LocalDateTime parse = LocalDateTime.parse("2023-01-15T10:00:00");

		  long until = Math.abs(parse.until(now, ChronoUnit.DAYS));
		  System.out.println(until);

七、OPtional(重要)

1、定义

        OPtional是一个数据容器,可以更好的表达数据是否存在的状态,对空指针可控。

2、常用方法

        Optional.of(T t):创建一个Optional实例;

        Optional.ofNullable(T t):若t不为空创建一个Optional实例否则创建一个空实例;

        Optional.empty():创建一个空的Optional实例;

        isPresent():判断是否包含值;

        orElse(T t):如果调用对象包含值,返回该值,否则返回t;

        orElseGet(Supplier s):如果调用对象包含值,返回该值,否则返回s获取的值;

        map(Function f):如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty();

        flatMap(Function mapper):与map类似,要求返回值必须是Optional。

案例:避免空指针问题

String str = null;
	//Optional 控制空指针,避免程序运行时由于异常导致终止
	Optional<String> str1 = Optional.ofNullable(str);
	System.out.println(str1.orElse("").length());

八、反射

1、定义

        反射是指动态获取类或者对象的信息(属性和方法),以及动态操作对象的属性和方法的类,动态分析和使用类的信息的类。java为程序员提供的一种可以基于已经存在的对象进行反向探知的能力。

2、反射中所涉及的类

        Class //表示一个类

        Method //方法

        Field //字段,属性

        Constructor //构造器

3、获取class的三种方式

要操作一个类的字节码,需要首先获取到这个类的字节码。

  • Class.forName() //Class的静态方法

  • 对象.getClass() //通过对象的getClass方法

  • 类.class //通过类的class属性

案例1:Class.forName

 //字节码
  Class<?> uClass = Class.forName("cn.hxzy.apimod.day14.UserControl");

  //转化为对应的类型
  UserControl userControl = (UserControl) uClass.newInstance();

  boolean stat = userControl.registUser("张三", "123456");
  System.out.println(stat);

案例2:类.Class

 Class<UserControl> userControlClass = UserControl.class;
  //new UserControl()
  UserControl userControl = userControlClass.newInstance();   

案例3:获取所有方法

 //获取类中的所有方法
  Method[] methods = userControlClass.getMethods();   //包括隐藏父类Object中的方法
  Stream<Method> metdStream = Stream.of(methods);
  metdStream.forEach(System.out::println);

案例4:获取字段(忽略权限修饰符)

Field[] fields = userControlClass.getDeclaredFields();
Stream<Field> fields1 = Stream.of(fields);
fields1.forEach(System.out::println);

案例5:获取构造器

//获取构造
Constructor<?>[] constructors = userControlClass.getDeclaredConstructors();
Stream<Constructor<?>> constructors1 = Stream.of(constructors);
constructors1.forEach(System.out::println);

案例6:通过构造器创建对象

Class<UserControl> userControlClass = UserControl.class;

//基于带参数的构造器创建对象
Constructor<UserControl> constructor = userControlClass
        .getDeclaredConstructor(Integer.class, String.class, String.class, String.class);
constructor.setAccessible(true);    //允许访问
UserControl userControl = constructor.newInstance(1, "zhangsan", "123456", "成都");
String address = userControl.getAddress();
System.out.println(address);

案例7:执行方法

 //获取字节码
  Class<UserControl> userControlClass = UserControl.class;

  //获取当前对象
  UserControl userControl = userControlClass.newInstance();

  //获取方法
  Method registUser = userControlClass.getMethod("registUser", String.class, String.class);

  //执行方法
  Object methodResult = registUser.invoke(userControl, "lisi", "ls123456");
  System.out.println(methodResult);

案例8:设置字段

//获取字节码
Class<UserControl> userControlClass = UserControl.class;

//创建对象
UserControl userControl = userControlClass.newInstance();

//获取字段
Field name = userControlClass.getDeclaredField("name");
name.setAccessible(true);
name.set(userControl, "wangwu");

Object nameField = name.get(userControl);
System.out.println(nameField);

案例9:获取类实现的接口

//获取字节码
Class<UserControl> userControlClass = UserControl.class;

//获取当前类实现的接口
Class<?>[] interfaces = userControlClass.getInterfaces();
for (Class<?> interfaceItm:interfaces) {
    System.out.println(interfaceItm.getName());
}

案例10:获取注解

//获取字节码
Class<UserControl> userControlClass = UserControl.class;

//获取方法
Method registUser = userControlClass
        .getMethod("registUser", String.class, String.class);

//获取当前方法上被修饰的注解,如果当前方法上被@Deprecated修饰,则输出,该方法不可用
Deprecated annotation = registUser.getAnnotation(Deprecated.class);
//System.out.println(annotation.toString());
if(null != annotation) {
    System.out.println("方法即将被废弃,不推荐使用!");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值