Java8-进阶

Java8-进阶

函数式接口

只包含一个抽象方法的接口

  • Function<T, R>

    接受一个输入参数,返回一个结果。

    Function接口包含以下方法:

    定义两个比较简单的函数:times2squared

    Function<Integer, Integer> times2 = e -> e * 2;
    Function<Integer, Integer> squared = e -> e * e;
    • R apply(T t)

      执行函数

      //return 8 - > 4 * 2
      Integer a = times2.apply(4);
      System.out.println(a);
    • compose

      先执行参数里面的操作,然后执行调用者

      //return 32 - > 4 ^ 2 * 2
      Integer b = times2.compose(squared).apply(4);
      System.out.println(b);
    • andThen

      先执行调用者操作,再执行参数操作

      //return 64 - > (4 * 2) ^ 2
      Integer c = times2.andThen(squared).apply(4);
      System.out.println(c);
    • identity

      总是返回传入的参数本身

      //return 4
      Integer d = identity.apply(4);
      System.out.println(d);
  • BiFunction<T, U, R>

    接受输入两个参数,返回一个结果

    • R apply(T t, U u)

      BiFunction<Integer, Integer, Integer> add = (x, y) -> x + y;
      //return 30
      System.out.println(add.apply(10,20));
  • Supplier<T>

    无参数,返回一个结果。

    • T get()

      Supplier<Integer> get= () -> 10;
      //return 10
      Integer a=get.get();
  • Consumer<T>

    代表了接受一个输入参数并且无返回的操作

    • void accept(T t)

      //return void
      Consumer<Integer> accept=x->{};
  • BiConsumer<T, U>

    代表了一个接受两个输入参数的操作,并且不返回任何结果

    • void accept(T t, U u)

      //return void
      BiConsumer<Integer,Integer> accept=(x,y)->{};
  • BinaryOperator<T> extends BiFunction<T,T,T>

    一个作用于于两个同类型操作符的操作,并且返回了操作符同类型的结果

    定义了两个静态方法:minBy,maxBy

  • Predicate<T>

    接受一个输入参数,返回一个布尔值结果。

    • test

      Predicate<String> predicate=x->x.startsWith("a");
      //return ture
      System.out.println(predicate.test("abc"));

Stream接口

  • Collector接口

    Collector是Stream的可变减少操作接口

    Collector

定义自己的Stream

  • collect

    collect有两个接口:

    <R> R collect(Supplier<R> supplier,
                  BiConsumer<R, ? super T> accumulator,
                  BiConsumer<R, R> combiner);
    <R, A> R collect(Collector<? super T, A, R> collector);              
    • <1> <R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner)

      Supplier supplier是一个工厂函数,用来生成一个新的容器;

      BiConsumer accumulator也是一个函数,用来把Stream中的元素添加到结果容器中;

      BiConsumer combiner还是一个函数,用来把中间状态的多个结果容器合并成为一个(并发的时候会用到)

      Supplier<List<String>> supplier = ArrayList::new;
      BiConsumer<List<String>, String> accumulator = List::add;
      BiConsumer<List<String>, List<String>> combiner = List::addAll;
      
      //return [aaa1, aaa1],实现了Collectors.toCollection
      List<String> list1 = stringCollection.stream()
              .filter(x -> x.startsWith("a"))
              .collect(supplier, accumulator, combiner);
    • <2> <R, A> R collect(Collector<? super T, A, R> collector)

      Collectors是Java已经提供好的一些工具方法:

      List<String> stringCollection = new ArrayList<>();
      stringCollection.add("ddd2");
      stringCollection.add("aaa1");
      stringCollection.add("bbb1");
      stringCollection.add("aaa1");

      转换成其他集合:

      • toList

        //return [aaa1, aaa1]
        stringCollection.stream()
            .filter(x -> x.startsWith("a")).collect(Collectors.toList())
      • toSet

        //return [aaa1]
        stringCollection.stream()
            .filter(x -> x.startsWith("a")).collect(Collectors.toSet())
      • toCollection

        接口:

        public static <T, C extends Collection<T>> Collector<T, ?, C> toCollection(Supplier<C> collectionFactory)

        实现:

        //return [aaa1, aaa1]
        List<String> list = stringCollection.stream()
            .filter(x -> x.startsWith("a"))
            .collect(Collectors.toCollection(ArrayList::new));
      • toMap

        接口:

        public static <T, K, U>
        Collector<T, ?, Map<K,U>> toMap(Function<? super T, ? extends K> keyMapper,
                              Function<? super T, ? extends U> valueMapper) 

        实现:

        //return {aaa1=aaa1_xu}
        Function<String, String> xu = x -> x + "_xu";
        Map<String, String> map = stringCollection.stream()
            .filter(x -> x.startsWith("a"))
            .distinct()
            .collect(Collectors.toMap(Function.identity(), xu));

      转成值:

      • averagingDouble:求平均值,Stream的元素类型为double
      • averagingInt:求平均值,Stream的元素类型为int
      • averagingLong:求平均值,Stream的元素类型为long
      • counting:Stream的元素个数
      • maxBy:在指定条件下的,Stream的最大元素
      • minBy:在指定条件下的,Stream的最小元素
      • reducing: reduce操作
      • summarizingDouble:统计Stream的数据(double)状态,其中包括count,min,max,sum和平均。
      • summarizingInt:统计Stream的数据(int)状态,其中包括count,min,max,sum和平均。
      • summarizingLong:统计Stream的数据(long)状态,其中包括count,min,max,sum和平均。
      • summingDouble:求和,Stream的元素类型为double
      • summingInt:求和,Stream的元素类型为int
      • summingLong:求和,Stream的元素类型为long

      数据分区:

      • partitioningBy

        接口:

        public static <T> Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate)
        
        public static <T, D, A>
        Collector<T, ?, Map<Boolean, D>> partitioningBy(Predicate<? super T> predicate,
                                                           Collector<? super T, A, D> downstream)

        实现:

        Predicate<String> startA = x -> x.startsWith("a");
        //return {false=[ddd2, bbb1], true=[aaa1, aaa1]}
        Map<Boolean, List<String>> map2 = stringCollection.stream()
                .collect(Collectors.partitioningBy(startA));
        
        //return {false={false=[ddd2], true=[bbb1]}, true={false=[], true=[aaa1, aaa1]}}
        Predicate<String> end1 = x -> x.endsWith("1");
        Map<Boolean, Map<Boolean, List<String>>> map3 = stringCollection.stream()
                .collect(Collectors.partitioningBy(startA, Collectors.partitioningBy(end1)));

      数据分组:

      • groupingBy

        接口:

        public static <T, K> Collector<T, ?, Map<K, List<T>>> groupingBy(Function<? super T, ? extends K> classifier)
        
        public static <T, K, A, D>
        Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,
                                        Collector<? super T, A, D> downstream)
        
        public static <T, K, D, A, M extends Map<K, D>>
        Collector<T, ?, M> groupingBy(Function<? super T, ? extends K> classifier,Supplier<M> mapFactory,
                                Collector<? super T, A, D> downstream)

        实现:

        //rerurn {a=[aaa1, aaa1], b=[bbb1], d=[ddd2]}
        Function<String, String> stringStart = x -> String.valueOf(x.charAt(0));
        Map<String, List<String>> map4 = stringCollection.stream()
                .collect(Collectors.groupingBy(stringStart));
        
        //rerurn {ddd2=1, bbb1=1, aaa1=2}
        Map<String, Long> map5 = stringCollection.stream()
                .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        
        //rerurn {d=1, a=2, b=1}
        Map<String, Long> map6 = stringCollection.stream()
                .collect(Collectors.groupingBy(stringStart, LinkedHashMap::new, Collectors.counting()));
  • reduce

    reduce有三个接口:

    Optional<T> reduce(BinaryOperator<T> accumulator);
    
    <U> U reduce(U identity,
                 BiFunction<U, ? super T, U> accumulator,
                 BinaryOperator<U> combiner);
    
    T reduce(T identity, BinaryOperator<T> accumulator);
    • <1> Optional<T> reduce(BinaryOperator<T> accumulator)

      BinaryOperator<String> binaryOperator = (x, y) -> x + y;
      //rerurn ddd2aaa1bbb1aaa1
      String reduceStr1 = stringCollection.stream().reduce(binaryOperator).orElse("");
    • <2> T reduce(T identity, BinaryOperator<T> accumulator)

      //return start:ddd2aaa1bbb1aaa1
      String reduceStr2=stringCollection.stream().reduce("start:",binaryOperator);
    • <3> <U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner)

      第一个参数返回实例u,传递你要返回的U类型对象的初始化实例u

      BiFunction accumulator,负责数据的累加

      BinaryOperator combiner,负责在并行情况下最后合并每个reduce线程的结果

      List<Person> personList = new ArrayList<>();
      personList.add(new Person(10, 20));
      personList.add(new Person(20, 30));
      personList.add(new Person(30, 50));
      
      BiFunction<Person, Person, Person> biFunction = (x, y) -> new Person(x.getAge() + y.getAge(), x.getRate() + y.getRate());
      BinaryOperator<Person> binaryOperator1 = (x, y) -> new Person(x.getAge() + y.getAge(), x.getRate() + y.getRate());
      Person total = personList.stream().reduce(new Person(0, 0), biFunction, binaryOperator1);
      System.out.println("total:"+total);

    项目地址https://github.com/MyHerux/java-java8-learning

<think>嗯,用户想了解Java入门中的数组进阶内容。首先,我得确定用户已经掌握了数组的基础,比如声明、初始化和访问元素。接下来需要介绍数组的进阶知识点。 多维数组是必须的,特别是二维数组,这在处理表格或矩阵时很常见。要说明如何声明和初始化,以及如何嵌套循环来遍历。例如,二维数组的静态和动态初始化方式。 然后,数组的常用方法,比如System.arraycopy和Arrays类的方法。这些工具类能简化操作,比如排序、填充和二分查找。需要提到Arrays.toString方便输出数组内容,避免手动拼接字符串。 内存管理部分也很重要,解释数组在内存中的存储方式,栈和堆的区别,以及引用类型的特性。这样用户能理解数组变量和实际对象的关系,避免浅拷贝的问题。 接下来是常见应用场景,比如算法中的最值查找、反转数组和基本排序算法。这部分需要给出示例代码,帮助用户理解如何应用数组解决实际问题。 异常处理也不能少,比如ArrayIndexOutOfBoundsException和NullPointerException,说明原因和解决方法,强调检查索引和初始化的重要性。 最后,可以提到数组的局限性,比如长度固定,引出集合框架作为后续学习内容。同时,对比数组和其他数据结构,帮助用户根据需求选择合适工具。 在整理结构时,要确保每个部分都有清晰的示例代码,并且用$$包裹独立公式,比如遍历二维数组的循环结构。注意用中文解释每个概念,避免术语混淆。检查LaTeX语法是否正确,比如矩阵的表示是否正确使用双美元符号。 可能用户需要实际应用的例子,所以每个知识点都要有代码片段,并说明应用场景。同时,提醒内存管理和异常处理,这些是初学者容易出错的地方。确保回答逻辑连贯,从基础到进阶逐步展开,帮助用户建立完整的数组知识体系。</think>我来为您梳理Java数组的进阶知识体系,通过关键知识点和示例代码帮助您系统掌握: $$ 二维数组内存模型(示例) $$ $$ \begin{matrix} arr[0][0] & arr[0][1] & arr[0][2] \\ arr[1][0] & arr[1][1] & arr[1][2] \\ \end{matrix} $$ 一、多维数组操作 1. 声明与初始化 ```java // 静态初始化 int[][] matrix = {{1,2}, {3,4}, {5,6}}; // 动态初始化 double[][][] cube = new double[3][4][5]; ``` 2. 遍历技巧(时间复杂度:$O(n^m)$) ```java for(int i=0; i<matrix.length; i++) { for(int j=0; j<matrix[i].length; j++) { System.out.print(matrix[i][j] + " "); } System.out.println(); } ``` 二、数组工具类 1. Arrays类核心方法 ```java int[] nums = {5,3,9,1}; Arrays.sort(nums); // 排序 → [1,3,5,9] int index = Arrays.binarySearch(nums, 5); // 二分查找 → 2 int[] copy = Arrays.copyOfRange(nums, 1, 3); // [3,5] ``` 2. 数组比较与填充 ```java Arrays.fill(nums, 0); // 全部填充0 boolean isEqual = Arrays.equals(arr1, arr2); ``` 三、内存管理机制 $$ 数组存储结构 $$ ``` 栈内存 堆内存 arr → [ ][ ][ ][ ] ``` - 引用传递示例 ```java int[] a = {1,2}; int[] b = a; // 浅拷贝 b[0] = 9; // a[0]也变为9 ``` 四、典型应用场景 1. 极值查找(时间复杂度:$O(n)$) ```java int max = Integer.MIN_VALUE; for(int num : array) { if(num > max) max = num; } ``` 2. 数组反转算法 ```java public static void reverse(int[] arr) { for(int i=0; i<arr.length/2; i++) { int temp = arr[i]; arr[i] = arr[arr.length-1-i]; arr[arr.length-1-i] = temp; } } ``` 五、异常处理要点 1. 常见异常类型 ```java try { int[] arr = null; System.out.println(arr[5]); // NullPointerException } catch(Exception e) { System.out.println("错误:" + e.getMessage()); } ``` 六、优化与扩展 1. 性能对比 - 连续内存访问 vs 随机访问 - 缓存命中率优化 2. 与集合类的对比 $$ \begin{array}{|c|c|c|} \hline 特性 & 数组 & ArrayList \\ \hline 长度 & 固定 & 动态 \\ \hline 类型 & 基本/对象 & 对象 \\ \hline 性能 & 高 & 略低 \\ \hline \end{array} $$ 进阶建议: 1. 结合算法学习:排序、查找、动态规划等 2. 尝试实现自定义的ArrayList 3. 学习NIO中的ByteBuffer 4. 探索数组在图形处理(如图像像素存储)中的应用 通过以上知识点的系统学习和实践,您将能够: 1. 熟练操作多维数组 2. 合理选择数组工具方法 3. 避免常见内存问题 4. 实现复杂数组算法 5. 为后续学习集合框架打下坚实基础 建议练习项目: - 矩阵乘法计算器 - 井字棋游戏逻辑 - 学生成绩统计系统 - 图像灰度处理程序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值