软件设计之Java入门视频(22)

avatar
作者
猴君
阅读量:0

软件设计之Java入门视频(22)

视频教程来自B站尚硅谷:

尚硅谷Java入门视频教程,宋红康java基础视频
相关文件资料(百度网盘)
提取密码:8op3
idea 下载可以关注 软件管家 公众号

学习内容:

该视频共分为1-717部分
本次内容涉及 660-717(后续Java9、10、11新特性就不一一赘述)
在写代码时,总是需要来回切换界面来看代码要求,这里推荐Snipaste,可以把截图以窗口形式放在屏幕上
记录内容:

  1. 静态代理
  2. 动态代理
  3. Lambda表达式
  4. 函数式接口
  5. 方法引用
  6. Stream API

1、静态代理

interface  ClothFactory{     void produceCloth(); } //代理类 class  ProxyClothFactory implements ClothFactory{      private ClothFactory factory;//用被代理对象进行实例化      public ProxyClothFactory(ClothFactory factory) {         this.factory = factory;     }      @Override     public void produceCloth() {         System.out.println("代理工厂做准备工作");         factory.produceCloth();         System.out.println("代理工厂做后续工作");     } } //被代理类 class NikeClothFactory implements ClothFactory{      @Override     public void produceCloth() {         System.out.println("Nike工厂生产运动服");     } } public class StaticProxyTest {     public static void main(String[] args) {         //创建被代理类对象         NikeClothFactory ncf = new NikeClothFactory();         //创建代理类对象         ProxyClothFactory pcf = new ProxyClothFactory(ncf);          pcf.produceCloth();         //代理工厂做准备工作         //Nike工厂生产运动服         //代理工厂做后续工作     } } 

2、动态代理

interface Human{     String getBelief();     void eat(String food);  } //被代理类 class SuperMan implements Human{      @Override     public String getBelief() {         return "I believe";     }      @Override     public void eat(String food) {         System.out.println("我喜欢吃" + food);     } } /* * 想要实现动态代理,需要解决的问题 * 问题1:如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象 * 问题2:当通过代理类的对象调用方法时,如何动态的去调用被代理类中的同名方法*/ class  ProxyFactory{     //调用此方法,返回一个代理类的对象,解决问题1     public static Object getProxyInstance(Object obj){//obj:被代理类的对象         MyInvocationHandler handler =  new MyInvocationHandler();         handler.bind(obj);         return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),handler);     } } class MyInvocationHandler implements InvocationHandler{      private Object obj;//需要使用被代理类对象进行幅值     public void bind(Object obj){         this.obj = obj;     }     //通过代理类的对象,调用方法a时,会自动调用如下方法:invoke()     //将被代理类要执行的方法a的功能声明在invoke()中     @Override     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {         //method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法         //obj:被代理类对象         Object returnValue = method.invoke(obj, args);         return returnValue;     } } public class ProxyTest {     public static void main(String[] args) {         SuperMan superMan = new SuperMan();         //proxyInstance代理类的对象         Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);         proxyInstance.eat("四川麻辣");//我喜欢吃四川麻辣     } } 

3、Lambda表达式

public class LambdaTest {     //语法格式一:无参,无返回值     @Test     public void test(){         Runnable r1 = new Runnable() {             @Override             public void run() {                 System.out.println("输出");             }         };         r1.run();          System.out.println("***********");         Runnable r2 = () -> {System.out.println("输出2");};         r2.run();     }     @Test     //语法格式二:Lambda 需要一个参数,但是没有返回值。     public void test1(){         Consumer<String> con = new Consumer<String>(){             @Override             public void accept(String s){                 System.out.println(s);             }         };         con.accept("你好");         System.out.println("********");         Consumer<String> con1 = (String s) -> {System.out.println(s);};     }     @Test     //语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”     public void test3(){         Consumer<String> con = new Consumer<String>(){             @Override             public void accept(String s){                 System.out.println(s);             }         };         con.accept("你好");         System.out.println("********");         Consumer<String> con1 = (s) -> {System.out.println(s);};     }     @Test     //语法格式四:Lambda 若只需要一个参数时,参数的小括号可以省略     public void test4(){         Consumer<String> con = new Consumer<String>(){             @Override             public void accept(String s){                 System.out.println(s);             }         };         con.accept("你好");         System.out.println("********");         Consumer<String> con1 = s -> {System.out.println(s);};     }     @Test     //语法格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值     public void test5(){         Comparator<Integer> com1 = new Comparator<Integer>() {             @Override             public int compare(Integer o1, Integer o2) {                 System.out.println(o1);                 System.out.println(o2);                 return o1.compareTo(o2);             }         };         System.out.println("**********");         Comparator<Integer> com2 = (o1,o2) -> {             System.out.println(o1);             System.out.println(o2);             return o1.compareTo(o2);         };         System.out.println(com2.compare(12,6));     }     @Test     //语法格式六:当 Lambda 体只有一条语句时,return 与大括号若有,都可以省略     public void test6(){         Comparator<Integer> com1 = (o1,o2) -> o1.compareTo(o2);;         System.out.println(com1.compare(12,6));     } } 

4、函数式接口

在这里插入图片描述

5、方法引用

使用情景:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用
方法引用本身上就是Lamda表达式,即也是函数式接口的实例
具体分为三种情况
1) 对象 :: 非静态方法
2)类::静态方法
3)类::非静态方法

 public class LambdaTest {     //情况一: 对象::实例方法     //Consumer中的void accept(T t)     //PrintStream中的void println(T t)     @Test     public void test(){        Consumer<String> con1 = str -> System.out.println(str);        con1.accept("北京");          System.out.println("**********");         PrintStream ps = System.out;         Consumer<String> con2 = ps::println;         con2.accept("beijing");     }     //     @Test     //情况二: 类::静态方法     //Comparator 中的int compare(T t1, T t2)     //Integer 中的int compare(T t1, T t2)     public void test1(){         Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);         System.out.println(com1.compare(12,13));         Comparator<Integer> com2 = Integer ::compare;         System.out.println(com2.compare(12,13));     }     @Test     //情况三: 类::实例方法     //Comparator中的int compare(T t1,T t2)     //String 中的int t1.compareTo(t2)     public void test3(){         Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);         System.out.println(com1.compare("abc","def"));         System.out.println("*********");          Comparator<String> com2 = String ::compareTo;         System.out.println(com2.compare("abc","def"));     }  }  

6、Stream API

1、Stream关注的是对数据的运算,与CPU打交道
2、集合关注的是数据的存储,与内存打交道
3、注意点
①Stream 自己不会存储元素。
②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream
③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

在这里插入图片描述

创建Stream

public class StreamAPITest {     //创建Stream方式一:通过集合     @Test     public void test1(){         List<Employee> employees = EmployeeData.getEmployees();          //default Stream<E> stream():返回一个顺序流         Stream<Employee> stream = employees.stream();         //default Stream<E> parallelStream():返回一个并行流         Stream<Employee> employeeStream = employees.parallelStream();     }     //创建Stream方式二:通过数组     @Test     public void test2(){         int[] arr = new int[]{1,2,3};         // 调用Arrays类的static <T> Stream<T> stream(T[] array): 返回一个流         IntStream stream = Arrays.stream(arr);         Employee e1 = new Employee(1001,"Tom");         Employee e2 = new Employee(1002,"Jerry");         Employee[] arr1 = new Employee[]{e1,e2};         Stream<Employee> stream1 = Arrays.stream(arr1);     }     //创建 Stream方式三:通过Stream的of()     @Test     public void test3(){         Stream<Integer> stream = Stream.of(1,2,3);     } } 

中间操作:筛选

public class StreamAPITest {     //创建Stream方式一:通过集合     @Test     public void test1() {         List<Employee> list = EmployeeData.getEmployees();         //filter(Predicate p)——接收Lambda,从流中排除某些元素         Stream<Employee>stream = list.stream();         stream.filter(e -> e.getSalary() > 7000).forEach(System.out ::println);         System.out.println();          //limit(long maxSize) 截断流,使其元素不超过给定数量         list.stream().limit(3).forEach(System.out ::println);         System.out.println();         //skip(long n)         //跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流与 limit(n) 互补         list.stream().skip(3).forEach(System.out ::println);          //distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素         list.add(new Employee(1010,"刘强东",40,8000));         list.add(new Employee(1010,"刘强东",40,8000));         list.add(new Employee(1010,"刘强东",40,8000));         list.stream().distinct().forEach(System.out ::println);     } 

中间操作:映射

 @Test     public void test2() { //        map(Function f)接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。         List<String> list = Arrays.asList("aa","bb");         list.stream().map(str -> str.toUpperCase()).forEach(System.out ::println);         Stream<Stream<Character>> streamStream = list.stream().map(StreamAPITest::fromStringToStream);         streamStream.forEach(s ->{             s.forEach(System.out ::println);         });         //flatMap(Function f)接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流         Stream<Character> characterStream = list.stream().flatMap(StreamAPITest::fromStringToStream);         characterStream.forEach(System.out::println);     }     //将字符串中多个字符构成的集合转换为对应的Stream的实例     public static Stream<Character> fromStringToStream(String str){         ArrayList<Character> list = new ArrayList<>();         for (Character c : str.toCharArray()){             list.add(c);         }         return list.stream();     } 

中间操作:排序

public class StreamAPITest {     //排序     @Test     public void test2() {         //sorted()——自然排序         List<Integer> list = Arrays.asList(12, 43, 11, 22, 8, 16);         list.stream().sorted().forEach(System.out::println);         //抛异常,原因:Employee没有实现Comparable接口 //        List<Employee> employees = EmployeeData.getEmployees(); //        employees.stream().sorted().forEach(System.out::println);         //sorted(Comparator com)——定制排序         List<Employee> employees = EmployeeData.getEmployees();         employees.stream().sorted((e1,e2) -> {             return Integer.compare(e1.getAge(),e2.getAge());         }).forEach(System.out::println);     } } 

终止操作:匹配与查找

public class StreamAPITest {     //匹配与查找     @Test     public void test2() {         List<Employee> employees = EmployeeData.getEmployees(); //        allMatch(Predicate p) 检查是否匹配所有元素         boolean allMatch = employees.stream().allMatch(e ->e.getAge() > 18);         System.out.println(allMatch); //        anyMatch(Predicate p) 检查是否至少匹配一个元素         boolean anyMatch = employees.stream().anyMatch(e ->e.getAge() > 18);         System.out.println(anyMatch); //        noneMatch(Predicate p) 检查是否没有匹配所有元素         boolean noneMatch = employees.stream().noneMatch(e ->e.getAge() > 100);         System.out.println(noneMatch); //        findFirst() 返回第一个元素         Optional<Employee> employee = employees.stream().findFirst();         System.out.println(employee); //        forEach(Consumer c) 内部迭代         employees.stream().forEach(System.out::println);         //使用集合的遍历操作         employees.forEach(System.out::println);     } } 

终止操作:归约

    //归约     @Test     public void test2() { //        reduce(T identity, BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 T         //计算1-10自然数和         List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);         Integer sum = list.stream().reduce(0, Integer::sum);         System.out.println(sum);  //        reduce(BinaryOperator b) 可以将流中元素反复结合起来,得到一个值。返回 Optional<T>         List<Employee> employees = EmployeeData.getEmployees();         Stream<Double> salaryStream = employees.stream().map(Employee::getSalary);         Optional<Double> sumMoney = salaryStream.reduce(Double::sum);         System.out.println(sumMoney);     } 

终止操作:收集

    //收集     @Test     public void test2() { //        collect(Collector c)将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法         List<Employee> employees = EmployeeData.getEmployees();         List<Employee> employeeList = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toList());         employeeList.forEach(System.out::println);          Set<Employee> employeeSet = employees.stream().filter(e -> e.getSalary() > 6000).collect(Collectors.toSet());         employeeSet.forEach(System.out::println);     } 

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!