• Java基础(十)


    复习

      静态方法与成员方法

    //另一个类里的静态和成员方法
    
    public class MyClass {
    
        //静态方法
    
        public static void method2() {
    
            System.out.println("静态方法2执行!");
    
        }
    
        //没有static,这是一个成员方法(实例方法,Instance Method)
    
        public void method3() {
    
            System.out.println("成员方法3执行!");
    
        }
    
    }
    
     
    
    /*
    
     * 定义方法的时候,有static和没有static有什么区别?
    
     *
    
     * 有static的方法,叫做静态方法.
    
     * 没有static的方法,叫做成员方法(实例方法).
    
     *
    
     * 定义静态方法的格式:
    
     * public static 返回值类型 方法名称(参数类型 参数名称){
    
     *      //方法体
    
     * }
    
     *
    
     * 定义成员方法的格式:
    
     * public 返回值类型 方法名称(参数类型 参数名称){
    
     *      //方法体
    
     * }
    
     *
    
     * 调用静态方法的格式:
    
     *      方法名(参数值);                 //直接调用本类当中的静态方法
    
     *      类名称.方法名(参数值);          //调用另外一个类当中的静态方法
    
     * 调用成员方法的格式:
    
     *      类名称 对象名 = new 类名称();       //首先创建对象
    
     *      对象名.成员方法名(参数值);      //通过对象名调用成员方法
    
     *
    
     * 1.如果不创建对象,那么通过类名称只能调用静态方法.
    
     * 2.如果创建了对象,那么通过对象名可以调用成员方法.
    
     * 3.通过对象名称也可以调用静态方法,然而不推荐这么做.
    
     */
    
    public class Demo01StaticVsInstance {
    
        public static void main(String[] args) {
    
            method1();     //调用本类当中的静态方法
    
           
    
            //注意:本类当中的静态方法,也可以通过类名称进行调用.
    
            Demo01StaticVsInstance.method1();     //调用本类当中的静态方法
    
           
    
            MyClass.method2();     //调用另外一个类当中的静态方法
    
           
    
            //需要调用成员方法,就必须借助对象
    
            MyClass obj = new MyClass();   //一定要首先创建一个对象
    
            obj.method3(); //然后才能通过对象去调用成员方法
    
           
    
            obj.method2(); //这种写法也可以,但是不推荐!
    
        }
    
       
    
        public static void method1() {
    
            System.out.println("静态方法1执行!");
    
        }
    
    }

    静态方法的简单使用

    //Cook类
    
    public class Cook {
    
        //这是一个静态方法,可以通过类名称进行调用
    
        public static void makeFood(String food) {
    
            System.out.println("将" + food + "做成可口的食物.");
    
        }
    
    }
    
     
    
    public class Demo02StaticInvoke {
    
        public static void main(String[] args) {
    
            //希望调用Cook这个类当中的静态方法makeFood
    
            //类名称.静态方法名(参数值)
    
            Cook.makeFood("白菜");
    
        }
    
    }

    方法引用

      Lambda的冗余场景

    //Cook类
    
    public class Cook {
    
        //这是一个静态方法,可以通过类名称进行调用
    
        public static void makeFood(String food) {
    
            System.out.println("将" + food + "做成可口的食物.");
    
        }
    
    }
    
     
    
    //保姆接口
    
    public interface Sitter {
    
        //保姆的工作,就是生米煮成熟饭
    
        public abstract void work(String food);
    
    }
    
     
    
    /*
    
     * 在某些场景之下,Lambda表达式要做的事情,其实在另外一个地方已经写过了.
    
     * 那么此时如果通过Lambda表达式重复编写相同的代码,就是浪费.
    
     * 那么如何才能复用已经存在的方法逻辑呢?
    
     */
    
    public class Demo03Lambda {
    
        public static void main(String[] args) {
    
            hireSitter(  sitter -> System.out.println("将" + sitter + "做成可口的食物.")  );
    
        }
    
       
    
        //雇佣一个保姆,并且让他去做饭
    
        public static void hireSitter(Sitter sitter) {
    
            sitter.work("白菜");
    
        }
    
    }

    体验方法引用

    //Cook类
    
    public class Cook {
    
        //这是一个静态方法,可以通过类名称进行调用
    
        public static void makeFood(String food) {
    
            System.out.println("将" + food + "做成可口的食物.");
    
        }
    
    }
    
     
    
    //保姆接口
    
    public interface Sitter {
    
        //保姆的工作,就是生米煮成熟饭
    
        public abstract void work(String food);
    
    }
    
     
    
    /*
    
     * 在某些场景之下,Lambda表达式要做的事情,其实在另外一个地方已经写过了.
    
     * 那么此时如果通过Lambda表达式重复编写相同的代码,就是浪费.
    
     * 那么如何才能复用已经存在的方法逻辑呢?
    
     */
    
    public class Demo03Lambda {
    
        public static void main(String[] args) {
    
            hireSitter(  sitter -> System.out.println("将" + sitter + "做成可口的食物.")  );
    
           
    
            hireSitter(  Cook ->  makeFood );
    
        }
    
       
    
        //雇佣一个保姆,并且让他去做饭
    
        public static void hireSitter(Sitter sitter) {
    
            sitter.work("白菜");
    
        }
    
    }

    类名称引用静态方法的格式

    //Cook类
    
    public class Cook {
    
        //这是一个静态方法,可以通过类名称进行调用
    
        public static void makeFood(String food) {
    
            System.out.println("将" + food + "做成可口的食物.");
    
        }
    
    }
    
     
    
    //保姆接口
    
    public interface Sitter {
    
        //保姆的工作,就是生米煮成熟饭
    
        public abstract void work(String food);
    
    }
    
    /*
    
     * 在某些场景之下,Lambda表达式要做的事情,其实在另外一个地方已经写过了.
    
     * 那么此时如果通过Lambda表达式重复编写相同的代码,就是浪费.
    
     * 那么如何才能复用已经存在的方法逻辑呢?
    
     *
    
     * 如果Lambda表达式需要做的事情,在另外一个类当中已经做过了,那么就可以直接拿过来替换Lambda.
    
     * 方法引用的写法:
    
     *
    
     * 通过类名称引用静态方法,格式:
    
     * 类名称::静态方法名
    
     */
    
    public class Demo03Lambda {
    
        public static void main(String[] args) {
    
            hireSitter(  sitter -> System.out.println("将" + sitter + "做成可口的食物.")  );
    
           
    
            hireSitter(  Cook ->  makeFood );
    
        }
    
       
    
        //雇佣一个保姆,并且让他去做饭
    
        public static void hireSitter(Sitter sitter) {
    
            sitter.work("白菜");
    
        }
    
    }

    类名称引用静态方法的练习

    //计算器函数式接口
    
    @FunctionalInterface
    
    public interface Calculator {
    
        //抽象方法的作用:求绝对值(如果是正数或者是0,那么仍然是本身;如果是负数,就要负负为正)
    
        public abstract int getAbs(int num);
    
    }
    
     
    
    /*
    
     * JDK当中已经给我们提供好了一个java.lang.Math类.其中有一个静态方法abs就可以实现求绝对值的功能.
    
     * 既然Math.abs方法已经存在了现成的做法,那么我就没有必要在用Lambda自己写一遍了.
    
     * 就可以通过方法引用,直接拿过来用.
    
     *
    
     * 格式:
    
     * 类名称::静态方法名
    
     */
    
    public class Demo01Abs {
    
        public static void main(String[] args) {
    
            method( num -> {
    
                int result;
    
                if(num >= 0) { //如果是正数或者是0.那么原封不动
    
                    result = num;
    
                }else {     //否则就是负数,应该负负为正
    
                    result = -num;
    
                }
    
                return result;
    
            } );
    
            System.out.println("===============================");
    
           
    
            //方法引用的意义:Math类当中有一个abs静态方法,已经有了现成的功能,直接拿过来用.
    
            method(Math::abs);
    
        }
    
       
    
        public static void method(Calculator calculator) {
    
            int result = calculator.getAbs(-25);
    
            System.out.println("结果是:" + result);
    
        }
    
    }

    对象名引用成员方法的格式

    //Cook类
    
    public class Cook {
    
        //这是一个成员方法,必须要有对象才能调用
    
        public void makeFood(String food) {
    
            System.out.println("将" + food + "做成可口的饭菜!" );
    
        }
    
    }
    
    //函数式接口
    
    public interface Sitter {
    
        public abstract void  work(String food);
    
    }
    
    /*
    
     * 方法引用的又一种格式:
    
     *
    
     * 通过对象引用成员方法,格式:
    
     * 对象名::成员方法名
    
     */
    
    public class Demo02MethodRef {
    
        public static void main(String[] args) {
    
            Cook cook = new Cook();        //创建了一个厨师对象
    
           
    
            //引用了cook对象当中的成员方法makeFood
    
            method(  cook::makeFood  );
    
        }
    
        public static void method(Sitter sitter) {
    
            sitter.work("土豆");
    
        }
    
    }

    对象名引用成员方法的练习

    //函数式接口
    
    @FunctionalInterface
    
    public interface Monitor {
    
        //将参数打印显示出来
    
        public abstract void show(String str);
    
    }
    
    /*
    
     * 问题:既然Lambda就是拿到参数,原封不动的交给println去使用.
    
     * 那么为什么不能直接交给println,而中间不用Lambda?
    
     * Lambda在这种场景当中,要做的事情,就是打印.而打印的功能在println当中已经有了.
    
     *
    
     * 这时候,可以使用方法引用.
    
     * 扩展一点:System.out其实就是一个JDK当中已经创建好的对象,而println就是System.out对象当中的成员方法
    
     *
    
     * 对象名::成员方法名
    
     * System.out.println
    
     *
    
     * 小结:
    
     * 1.一定要有函数式接口,才能使用Lambda.
    
     * 2.对于重复的Lambda场景,可以使用方法引用来进行简化.
    
     */
    
    public class Demo03Monitor {
    
        public static void main(String[] args) {
    
            //首先使用Lambda,间接调用println方法
    
            useMonitor(  (String str) -> {System.out.println(str);}  );
    
           
    
            //使用方法引用,直接交给了println方法引用去处理
    
            useMonitor(System.out::println);
    
        }
    
        public static void useMonitor(Monitor monitor) {
    
            monitor.show("Hello,World!");
    
        }
    
    }

    Stream流

      集合for遍历的冗余场景

    import java.util.ArrayList;
    
     
    
    /*
    
     * 题目:
    
     * 有一个集合里面存放的字符串,样子如:"赵丽颖,98","鹿晗,95","宋小宝,87"
    
     * 要求打印输出所有成绩当中大于90分的数字.
    
     *
    
     * 分析:
    
     * 1.首先定义一个集合ArrayList.存入指定格式的若干个字符串.
    
     * 2.我们只想要逗号后面的,那么就要分割字符串:split,然后取用结果数组当中的1号元素
    
     * 3.根据字符串切割出来的"98"仍然是一个String,需要转换成为int:Interger.parseInt静态方法
    
     * 4.要判断一下转换之后的int是不是大于90,筛选
    
     * 5.对筛选之后的最终结果进行打印输出.
    
     */
    
    public class Demo01ArrayList {
    
        public static void main(String[] args) {
    
            //首先创建一个集合,然后放入指定格式的字符串
    
            ArrayList<String> recordList = new ArrayList<>();
    
            recordList.add("赵丽颖,98");
    
            recordList.add("鹿晗,95");
    
            recordList.add("宋小宝,87");
    
           
    
            //应该拆分一下每个字符串,只要逗号后面的
    
            ArrayList<String> scoreList = new ArrayList<>();  //保存的多个字符串是:"98","95","87"
    
            for (int i = 0; i < recordList.size(); i++) {
    
                String record = recordList.get(i);    //当前字符串:"赵丽颖,98"
    
                String[] array = record.split(",");
    
                String score = array[1];   //"98"
    
                scoreList.add(score);
    
            }
    
           
    
            //将字符串"98"转换成为int数字98
    
            ArrayList<Integer> numList = new ArrayList<>();//保存的多个数字是:98,95,87
    
            for(int i = 0;i < scoreList.size();i++) {
    
                String score = scoreList.get(i);  //"98"
    
                int num = Integer.parseInt(score);
    
                numList.add(num);
    
            }
    
           
    
            //过滤一下,筛选,只要大于90的,小于等于90的不要
    
            ArrayList<Integer> resultList = new ArrayList<>();    //最终结果集合
    
            for(int i = 0;i < numList.size();i++) {
    
                int num = numList.get(i);  //98
    
                if(num > 90) {
    
                    resultList.add(num);
    
                }
    
            }
    
            //最后遍历最终结果集合,打印输出
    
            for(int i = 0; i < resultList.size();i++) {
    
                int result = resultList.get(i);
    
                System.out.println(result);
    
            }
    
        }
    
    }

    体验Stream的更优写法

    import java.util.ArrayList;
    
     
    
    /*
    
     * 题目:
    
     * 有一个集合里面存放的字符串,样子如:"赵丽颖,98","鹿晗,95","宋小宝,87"
    
     * 要求打印输出所有成绩当中大于90分的数字.
    
     *
    
     * 分析:
    
     * 1.首先定义一个集合ArrayList.存入指定格式的若干个字符串.
    
     * 2.我们只想要逗号后面的,那么就要分割字符串:split,然后取用结果数组当中的1号元素
    
     * 3.根据字符串切割出来的"98"仍然是一个String,需要转换成为int:Interger.parseInt静态方法
    
     * 4.要判断一下转换之后的int是不是大于90,筛选
    
     * 5.对筛选之后的最终结果进行打印输出.
    
     */
    
    public class Demo01ArrayList {
    
        public static void main(String[] args) {
    
            //首先创建一个集合,然后放入指定格式的字符串
    
            ArrayList<String> recordList = new ArrayList<>();
    
            recordList.add("赵丽颖,98");
    
            recordList.add("鹿晗,95");
    
            recordList.add("宋小宝,87");
    
           
    
            //Stream API更优写法!
    
            recordList.stream().map(s -> s.split(",")[1]).map(Integer::parseInt)
    
                .filter(n -> n > 90).forEach(System.out::println);
    
        }
    
    }

    思想概述

         

    获取Stream流的常用方式

    import java.util.ArrayList;
    import java.util.stream.Stream;
    
    /*
     * Java 8当中的"流"其实就是Stream接口的对象.
     * JDK提供了一个流接口:java.util.stream.Stream<T>
     * 
     * 如何获取流?
     * 1.根据集合获取流:集合名称.stream()
     * 2.根据数组获取流:Stream.of(数组名称)
     */
    public class Demo03GetStream {
        public static void main(String[] args) {
            //1.根据集合获取流
            ArrayList<String> list = new ArrayList<>();
            list.add("迪丽热巴");
            list.add("古力娜扎");
            list.add("玛尔扎哈");
            
            Stream<String> streamA = list.stream();
            
            //2.根据数组获取流,数组当中的元素必须是引用类型才行
            String[] arrayStr = {"Hello","World","Java"};
            Stream<String> streamB = Stream.of(arrayStr);
            
            Integer[] arrayInteger = {10,20,30};
            Stream<Integer> streamC = Stream.of(arrayInteger);
        }
    }

    map映射方法

    /*
     * 获取流之后,可以使用映射方法:map(用于转换的Lambda表达式)
     * 
     * 映射:就是将一个对象转换成为另一个对象,把老对象映射到新对象上.
     * 
     * "赵丽颖,98"     转换成为  "98"  将一个长字符串转换成为一个短字符串
     * "98"          转换成为     98    将一个字符串转换成为一个int数字
     */
    public class Demo04StreamMap {
        public static void main(String[] args) {
            //这个集合当中存放的是字符串类型
            ArrayList<String> list = new ArrayList<>();
            list.add("100");
            list.add("200");
            list.add("300");
            
            Stream<Integer> steramA = list.stream().map((String str) -> {
                int num = Integer.parseInt(str);
                return num;
            });
            Stream<Integer> steramB = list.stream().map(str -> {
                int num = Integer.parseInt(str);
                return num;
            });
            Stream<Integer> steramC = list.stream().map((String str) -> {
                return Integer.parseInt(str);
            });
            Stream<Integer> steramD = list.stream().map(Integer::parseInt);
            System.out.println("==========================");
            
            ArrayList<String> list2 = new ArrayList<>();
            list2.add("赵丽颖,98");
            list2.add("鹿晗,95");
            list2.add("宋小宝,87");
            
            Stream<String> stream1 = list2.stream().map((String str) -> {
                String[] array = str.split(",");
                String result = array[1];
                return result;
            });
            
            Stream<String> stream2 = list2.stream().map(s -> {
                String[] array = s.split(",");
                String result = array[1];
                return result;
            });
            
            Stream<String> stream3 = list2.stream().map(s -> {
                String[] array = s.split(",");
                return array[1];
            });
            
            Stream<String> stream4 = list2.stream().map(s -> {
                return s.split(",")[1];
            });
            
            Stream<String> stream5 = list2.stream().map(s -> s.split(",")[1]);
        }
    }

    filter过滤方法

    import java.util.ArrayList;
    import java.util.stream.Stream;
    
    /*
     * 如果希望对流当中的元素进行过滤,可以使用过滤方法:
     * 
     * filter(能产生boolean结果的Lambda):如果参数Lambda生产了true,则要元素;如果产生了false,则不要元素.
     */
    public class Demo05SteramFilter {
        public static void main(String[] args) {
            ArrayList<Integer> list1 = new ArrayList<>();
            list1.add(90);
            list1.add(85);
            list1.add(60);
            
            Stream<Integer> stream1 = list1.stream().filter((Integer num) -> {
                boolean b = num > 80;
                return b;
            });
            Stream<Integer> stream2 = list1.stream().filter(num -> {
                boolean b = num > 80;
                return b;
            });
            Stream<Integer> stream3 = list1.stream().filter(num -> {
                return num > 80;
            });
            Stream<Integer> stream4 = list1.stream().filter(num -> num > 80);
            System.out.println("==========================");
            
            ArrayList<String> list2 = new ArrayList<>();
            list2.add("赵丽颖");
            list2.add("赵丽颖");
            list2.add("宋小宝");
            
            Stream<String> streamA = list2.stream().filter((String str) -> {
    //            boolean b = "赵丽颖".equals(str);
                boolean b = str.equals("赵丽颖");
                return b;
            });
            
            Stream<String> streamB = list2.stream().filter(str -> {
                boolean b = str.equals("赵丽颖");
                return b;
            });
            
            Stream<String> streamC = list2.stream().filter(str -> {
                return str.equals("赵丽颖");
            });
            
            Stream<String> streamD = list2.stream().filter(s -> s.equals("赵丽颖"));
        }
    }

    forEach遍历方法

    import java.util.ArrayList;
    import java.util.stream.Stream;
    
    /*
     *     如果希望在流当中进行元素的遍历操作,可以使用forEach方法:
     * 
     *     forEach(Lambda表达式):意思是,对流当中的每一个元素都要进行操作.
     *     参数Lambda表达式必须是一个能够消费一个参数,而且不产生数据结果的Lambda.
     * 
     *     例如:
     *     Lambda:        s -> System.out.println(s);
     *     方法引用:    System::println
     */
    public class Demo06SteramForEach {
        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            list.add("迪丽热巴");
            list.add("古力娜扎");
            list.add("玛尔扎哈");
            
            Stream<String> streamA = list.stream();
            streamA.forEach((String str) -> {
                System.out.println(str);
            });
            System.out.println("================");
            
            list.stream().forEach((String str) -> {
                System.out.println(str);
            });
            System.out.println("================");
            
            list.stream().forEach(str -> {
                System.out.println(str);
            });
            System.out.println("================");
            
            list.stream().forEach(System.out::println);
        }
    }

    并发的Stream流

    import java.util.ArrayList;
    
    /*
     *     流当中的元素如果特别多,那么只有一个人在逐一,挨个儿处理,肯定比较慢,费劲.
     *     如果对流当中的元素,使用多个人同时处理,这就是"并发".
     * 
     *     如何才能获取"并发流"(支持并发操作的流):
     *     .parallelStream()
     * 
     *     注意事项:
     *     1.使用并发流操作的时候,到底有几个人进行同时操作呢?不用管,JDK自己处理.
     *     2.只要正确使用,就不会出现多个人抢到同一个元素的情况.
     *     3.如果已经获取了一个普通的流,那么只要再调用一下parallel()方法也会变成并发流.
     * 
     *     总结:
     *     1.直接获取并发流: .parallelStream()
     *     2.已经获取了普通流,然后升级成为并发流: .stream().parallel()
     */
    public class Demo07StreamParallel {
        public static void main(String[] args) {
            ArrayList<String> list = new ArrayList<>();
            for (int i = 1; i <= 100; i++) {
                list.add("Hello-" + i);
            }
            
            //这是只有一个人在做打印输出的操作
    //        list.stream().forEach(System.out::println);
            
            //获取一个并发流
    //        list.parallelStream().forEach(System.out::println);
            
            //如果已经获取了一个普通的流,那么只要再调用一下parallel()方法也会变成并发流
            list.stream().parallel().forEach(System.out::println);
        }
    }

    模块化

      思想概述

         

    可以解决的问题

         

    认识module-info.java文件

        在Java的一个模块中,需要使用module-info.java文件描述模块信息。

        

    将Eclipse项目改造为模块

      可以通过下面的操作将Eclipse的Java Project改造成一个Java9的模块:

        1.    点击项目名称,右键选择Configure,点击 Create module-info java 选项。

        2.    在生成的module-info.java文件中编写导出exports和依赖requires等信息。

        3.    点击项目名称,右键选择Build Path,点选最后一项Configure Build Path。在Projects

      标签中选中Modulepath,然后右侧Add所需要依赖的模块。

        1. 创建

         

        2. 名字输入

         

        3. 如果有其它模块依赖我,那么其他模块下面的3个包都可以访问

         

         

        4. 可以访问谁不可以访问谁

         

    设置模块间的依赖关系

         

         

    知识总结

      1.    对比一下静态方法与成员方法的区别:

        a)  静态方法与对象无关,可以直接通过类名称调用:

          类名称.静态方法名(参数值);

        b) 成员方法一定要有对象才能使用:

          对象名.成员方法名(参数值);

      2.    方法引用:如果Lambda表达式想做的事情,在某一个地方某一个方法已经做过了,那么就可以使用方法引用来替代Lambda。

      3.    方法引用的方式:

        a)通过类名称引用静态方法:类名称::静态方法名

        b)通过对象名引用成员方法:对象名::成员方法名

      4.    Stream 流式思想:简化了普通的集合操作,类似于流水线。Stream流在Java当中就是一个java.util.stream.Stream<T>接口的对象。.

        a)如何获取流:

          i.     通过集合获取:集合名称stream()

          ii.     通过数组获取:Stream.of(数组名称)注意,数组当中必须是引用类型元素

        b)映射的方法:map,参数是一个负责转换的Lambda表达式

        c)过滤的方法:filter,参数是一个可以产生boolean结果的Lambda表达式

        d)遍历的方法:forEach,参数也是一个Lambda,Lambda对应的抽象方法应该只有一个参数并且不产生返回值。

        e)如何获取并发流

          i.     直接一次性获取并发流:.parallelStream()

          ii.     首先获取普通流,然后继续变成并发流:.stream().parallel()

      5.    模块化思想可以为我们带来两点好处:

        a)  整体一整个,文件体积太大。如果只是用到了其中的一部分内容,就会浪费。

        b) 精确控制package包级别的访问控制。只有导出的包,模块之外才可以访问,否则只能模块内部自己访问。

        c)  模块的描述信息module-info.java文件的基本内容:

          module本模块的名称{

            exports导出的包名称;

            requires需要依赖的其他模块名称;

                    }

  • 相关阅读:
    HDU 3999 The order of a Tree (排序二叉树的先序遍历)
    如何从 100 亿 URL 中找出相同的 URL?
    Tomcat源码分析 | 一文详解生命周期机制Lifecycle
    SqlSession与SqlSessionFactory到底是什么关系?
    spring boot-jpa整合QueryDSL来简化复杂操作
    EasyExcel读写Excel
    如何将List集合中相同属性的对象合并
    @Data 注解引出的 lombok
    MySQL配置连接
    Django创建
  • 原文地址:https://www.cnblogs.com/loveyoul9/p/11483424.html
Copyright © 2020-2023  润新知