黑马程序员JAVA学习第九节

本文详细介绍了Java中的函数式接口,包括@FunctionalInterface的使用、Lambda表达式的应用,以及Supplier、Consumer、Predicate、Function接口的实战。此外,还讲解了Stream流的概念、生成方式、中间操作和终结操作,以及类加载、反射和模块化的基础知识。
摘要由CSDN通过智能技术生成

黑马程序员JAVA学习第九节

(视频链接黑马程序员全套Java教程_Java基础入门教程,零基础小白自学Java必备教程_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili

本节主要内容是函数式接口,Stream流,类加载,反射,模块化。对应视频372-410。

函数式接口

1.函数式接口概述

1)概念   有且仅有一个抽象方法的接口
2)如何检测一个接口是不是函数式接口
@FunctionalInterface    放在接口定义的上方:如果接口是函数式接口,编译通过;如果不是,编译失败
3)注意事项
      我们自己定义函数式接口的时候,@FunctionalInterface是可选的,就算我不写这个注解,只要保证满足函数式接口定义的条件,也照样是函数式接口。但是,建议加上该注解

2.函数式接口作为方法的参数

如果方法的参数是一个函数式接口,我们可以使用Lambda表达式作为参数传递。

//Lambda方式
 startThread(() -> System.out.println(Thread.currentThread().getName() + "线程启动了"));

3.函数式接口作为方法的返回值

如果方法的返回值是一个函数式接口,我们可以使用Lambda表达式作为结果返回。

  private static Comparator<String> getComparator() {
    //匿名内部类的方式实现
//    return new Comparator<String>() {
//      @Override
//      public int compare(String s1, String s2) {
//        return s1.length()-s2.length();
//      }
//    };
   
//Lambda方式实现
    return (s1, s2) -> s1.length() - s2.length();
 }

4.常用函数式接口之Supplier

1)Supplier 接口
Supplier接口也被称为生产型接口,如果我们指定了接口的泛型是什么类型,那么接口中的get方法就会生产
什么类型的数据供我们使用。

2)常用方法  只有一个无参的方法

T get()   按照某种实现逻辑(由Lambda表达式实现)返回一个数据

public class SupplierTest {
  public static void main(String[] args) {
    //定义一个int数组
    int[] arr = {19, 50, 28, 37, 46};
    int maxValue = getMax(()-> {
     int max = arr[0];
     for(int i=1; i<arr.length; i++) {
       if(arr[i] > max) {
         max = arr[i];
       }
     }
return max;
   });
    System.out.println(maxValue);
 }
  //返回一个int数组中的最大值
  private static int getMax(Supplier<Integer> sup) {
    return sup.get();
 }
}

5.常用函数式接口之Consumer

1)Consumer 接口:Consumer接口也被称为消费型接口,它消费(使用)的数据的数据类型由泛型指定

2)方法:

3)代码

//操作一
    operatorString("林青霞", s -> System.out.println(s));
//操作二
    operatorString("林青霞", s -> System.out.println(new
StringBuilder(s).reverse().toString()));
   
    System.out.println("--------");
//传入两个操作使用andThen完成
    operatorString("林青霞", s -> System.out.println(s), s ->
System.out.println(new StringBuilder(s).reverse().toString()));
 }
  //定义一个方法,用不同的方式消费同一个字符串数据两次
  private static void operatorString(String name, Consumer<String> con1,
Consumer<String> con2) {
//    con1.accept(name);
//    con2.accept(name);
    con1.andThen(con2).accept(name);//上两句的改进版本
 }
  //定义一个方法,消费一个字符串数据
  private static void operatorString(String name, Consumer<String> con) {
    con.accept(name);
 }

6.常用函数式接口之Predicate

1)Predicate 接口  Predicate接口通常用于判断参数是否满足指定的条件

2)方法

3)代码

    boolean b1 = checkString("hello", s -> s.length() > 8);
    System.out.println(b1);
    boolean b2 = checkString("helloworld",s -> s.length() > 8);
    System.out.println(b2);
 }
  //判断给定的字符串是否满足要求
  private static boolean checkString(String s, Predicate<String> pre) {
//    return !pre.test(s);
    return pre.negate().test(s);//与上一句含义相同
 }

7. 常用函数式接口之Function

1)Function 接口  Function<T,R>接口通常用于对参数进行处理,转换(处理逻辑由Lambda表达式实现),然后返回一个新的值

2)方法

3)代码

//操作一
    convert("100",s -> Integer.parseInt(s));
//操作二
    convert(100,i -> String.valueOf(i + 566));
    //使用andThen的方式连续执行两个操作
    convert("100", s -> Integer.parseInt(s), i -> String.valueOf(i + 566));
 }
  //定义一个方法,把一个字符串转换int类型,在控制台输出
  private static void convert(String s, Function<String,Integer> fun) {
//    Integer i = fun.apply(s);
    int i = fun.apply(s);
    System.out.println(i);
 }

Stream流

1.Stream 流的好处
  1)直接阅读代码的字面意思即可完美展示无关逻辑方式的语义
  2)Stream 流把真正的函数式编程风格引入到Java中

2.Stream流的常见生成方式

     1)Stream流的思想

  

  2)生成 Stream流的方式
    (1)Collection 体系集合
              使用默认方法stream()生成流, default Stream stream()
    (2)Map 体系集合
              把Map转成Set集合,间接的生成流
    (3)数组
              通过Stream接口的静态方法of(T... values)生成流

   3)代码

//Collection体系的集合可以使用默认方法stream()生成流
    List<String> list = new ArrayList<String>();
    Stream<String> listStream = list.stream();
    Set<String> set = new HashSet<String>();
    Stream<String> setStream = set.stream();
    //Map体系的集合间接的生成流
    Map<String,Integer> map = new HashMap<String, Integer>();
    Stream<String> keyStream = map.keySet().stream();
    Stream<Integer> valueStream = map.values().stream();
    Stream<Map.Entry<String, Integer>> entryStream = map.entrySet().stream();
  //数组可以通过Stream接口的静态方法of(T... values)生成流
    String[] strArray = {"hello","world","java"};
    Stream<String> strArrayStream = Stream.of(strArray);
    Stream<Integer> intStream = Stream.of(10, 20, 30);

3.Stream流中间操作方法

1)常见方法

4. Stream流终结操作方法

1)概念:终结操作的意思是,执行完此方法之后,Stream流将不能再执行其他操作

2)

5.Stream流的收集操作

1)概念 对数据使用Stream流的方式操作完毕后,可以把流中的数据收集到集合中

2)

类加载

1.类加载的描述
当程序要使用某个类时,如果该类还未被加载到内存中,则系统会通过类的加载,类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况,JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为类加载或者类初始化

2.类的连接
验证阶段:用于检验被加载的类是否有正确的内部结构,并和其他类协调一致
准备阶段:负责为类的类变量分配内存,并设置默认初始化值
解析阶段:将类的二进制数据中的符号引用替换为直接引用
3.类的初始化
在该阶段,主要就是对类变量进行初始化
4.类的初始化步骤
1)假如类还未被加载和连接,则程序先加载并连接该类
2)假如该类的直接父类还未被初始化,则先初始化其直接父类
3)假如类中有初始化语句,则系统依次执行这些初始化语句
注意:在执行第 2个步骤的时候,系统对直接父类的初始化步骤也遵循初始化步骤1-3
4.类的初始化时机
1)创建类的实例
2)调用类的类方法
3)访问类或者接口的类变量,或者为该类变量赋值
4)使用反射方式来强制创建某个类或接口对应的 java.lang.Class对象
5)初始化某个类的子类
6)直接使用 java.exe命令来运行某个主类

5.类加载器的作用

负责将 .class文件加载到内存中,并为之生成对应的 java.lang.Class 对象

反射

1.反射的概述

是指在运行时去获取一个类的变量和方法信息。然后通过获取到的信息来创建对象,调用方法的一种机制。由于这种动态性,可以极大的增强程序的灵活性,程序不用在编译期就完成确定,在运行期仍然可以扩展。

2.获取Class类对象的三种方式

1)类名 .class属性
2)对象名 .getClass()方法
3)Class.forName( 全类名)方法

    //使用类的class属性来获取该类对应的Class对象
    Class<Student> c1 = Student.class;
    System.out.println(c1);
    Class<Student> c2 = Student.class;
    System.out.println(c1 == c2);//true
    System.out.println("--------");
    //调用对象的getClass()方法,返回该对象所属类对应的Class对象
    Student s = new Student();
    Class<? extends Student> c3 = s.getClass();
    System.out.println(c1 == c3);
    System.out.println("--------");
    //使用Class类中的静态方法forName(String className)
    Class<?> c4 = Class.forName("com.itheima_02.Student");
    System.out.println(c1 == c4);

3.反射获取构造方法并使用

1)Class类获取构造方法对象的方法

4.Constructor类用于创建对象的方法

T newInstance(Object...initargs)   根据指定的构造方法创建对象

5.反射获取成员变量并使用

1)Class类获取成员变量对象的方法

模块化

1.模块的基本使用

1)创建模块(按以前讲解的方式创建模块,包,类,定义方法)

在项目中创建两个模块。一个是myOne,一个是myTwo

2)在myOne模块中src目录下,创建module-info.java(描述性文件),该文件专门定义模块名,访问权限,模块依赖等信息,描述性文件中使用模块导出和模块依赖来进行配置并使用

3)​​​​​​​

2.模块服务的使用

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值