首页  > 思维解答  > 

Java继承(extends)简明教程(javaprivate用法)

  • 浏览4040次
  • lengsiwei.com
  • 评论0条
  • 导读继承是面向对象的三大特征之一。继承和现实生活中的“继承”的相似之处是保留一些父辈的特性,从而减少代码冗余,提高程序运行效率。  Java 中的继承就是在已经存在类的基础上进行扩展,从而产生新的类。已经存在的类称为父类、基类或超类,而新产生的...

    继承是面向对象的三大特征之一。继承和现实生活中的“继承”的相似之处是保留一些父辈的特性,从而减少代码冗余,提高程序运行效率。

      Java 中的继承就是在已经存在类的基础上进行扩展,从而产生新的类。已经存在的类称为父类、基类或超类,而新产生的类称为子类或派生类。在子类中,不仅包含父类的属性和方法,还可以增加新的属性和方法。

      Java 中子类继承父类的语法格式如下:

      修饰符 class class_name extends extend_class { // 类的主体}

      其中,class_name 表示子类(派生类)的名称;extend_class 表示父类(基类)的名称;extends 关键字直接跟在子类名之后,其后面是该类要继承的父类名称。例如:

      public class Student extends Person{}

      Java 的继承通过 extends 关键字来实现,extends 的英文意思是扩展,而不是继承。extends 很好的体现了子类和父类的关系,即子类是对父类的扩展,子类是一种特殊的父类。从这个角度看,使用继承来描述子类和父类的关系是错误的,用扩展更恰当。

      那么为什么国内把 extends 翻译为“继承”呢?子类扩展父类之后就可以获得父类的属性和方法,这与汉语中的继承(子类从父类获得一笔财富称为继承)具有相似性。

      Java 与 C++ 定义继承类的方式十分相似。Java 用关键字 extends 代替了 C++ 中的冒号(:)。在 Java 中,所有的继承都是公有继承, 而没有 C++ 中的私有继承和保护继承。


    类的继承不改变类成员的访问权限,也就是说,如果父类的成员是公有的、被保护的或默认的,它的子类仍具有相应的这些特性,并且子类不能获得父类的构造方法。

      例 1

      教师和学生都属于人,他们具有共同的属性:姓名、年龄、性别和身份证号,而学生还具有学号和所学专业两个属性,教师还具有教龄和所教专业两个属性。下面编写 Java 程序代码,使教师(Teacher)类和学生(Student)类都继承于人(People)类,具体的实现步骤如下。

      1)创建人类 People,并定义 name、age、sex、sn 属性,代码如下:

      public class People { public String name; // 姓名 public int age; // 年龄 public String sex; // 性别 public String sn; // 身份证号 public People(String name, int age, String sex, String sn) { this.name = name; this.age = age; this.sex = sex; this.sn = sn; } public String toString() { return "姓名:" + name + "n年龄:" + age + "n性别:" + sex + "n身份证号:" + sn; }}

      如上述代码,在 People 类中包含 4 个公有属性、一个构造方法和一个 toString() 方法。

      2)创建 People 类的子类 Student 类,并定义 stuNo 和 department 属性,代码如下:

      public class Student extends People { private String stuNo; // 学号 private String department; // 所学专业 public Student(String name, int age, String sex, String sn, String stuno, String department) { super(name, age, sex, sn); // 调用父类中的构造方法 this.stuNo = stuno; this.department = department; } public String toString() { return "姓名:" + name + "n年龄:" + age + "n性别:" + sex + "n身份证号:" + sn + "n学号:" + stuNo + "n所学专业:" + department; }}

      由于 Student 类继承自 People 类,因此,在 Student 类中同样具有 People 类的属性和方法,这里重写了父类中的 toString() 方法。

      注意:如果在父类中存在有参的构造方法而并没有重载无参的构造方法,那么在子类中必 须含有有参的构造方法,因为如果在子类中不含有构造方法,默认会调用父类中无参的构造方法,而在父类中并没有无参的构造方法,因此会出错。

      3)创建 People 类的另一个子类 Teacher,并定义 tYear 和 tDept 属性,代码如下:

      public class Teacher extends People { private int tYear; // 教龄 private String tDept; // 所教专业 public Teacher(String name, int age, String sex, String sn, int tYear, String tDept) { super(name, age, sex, sn); // 调用父类中的构造方法 this.tYear = tYear; this.tDept = tDept; } public String toString() { return "姓名:" + name + "n年龄:" + age + "n性别:" + sex + "n身份证号:" + sn + "n教龄:" + tYear + "n所教专业:" + tDept; }}

      Teacher 类与 Student 类相似,同样重写了父类中的 toString() 方法。

    最后推荐正在学习java的小伙伴可以观看学习下方视频。

    尚学堂给同学们带来全新的Java300集课程啦!java零基础小白自学Java必备优质教程_手把手解学习Java,让学习成为一种享受_哔哩哔哩_bilibili

    JAVA的访问控制2-public,protected,private和package-private

    JAVA的访问控制2-public,protected,private和package-private

    在前文JAVA的访问控制1-访问控制的必要性,包中介绍了访问控制的由来以及包的概念,本文将继续介绍访问控制的关键字publicprotectedprivate以及没有关键字时默认的package-private
    这些关键字可以用于修饰字段,方法和内部类,另外,只有public和默认的package-private可以用于外部类定义。

    package-private默认权限

    当字段等没有任何修饰符时,就是默认权限,也就是包访问权限。包访问权限可以让当前包的所有类进行调用,其他包的类则无法调用。
    比如,类Persion在包
    org.xxx.model下,代码如下:

    package org.xxx;public class Person {    String name;    String getName() {        return name;    }}

    那么,同样在包org.xxx.model下的其他类就可以访问到name字段和getName()方法,而其他包,比如org.xxx.util包下的类,就无法访问。
    默认权限的一个用途是单元测试,被测试类中一些待测试字段和方法设置为默认权限,测试类可以方便地设置和调用。
    大部分的方法都可以设置为包访问权限。

    public

    public关键字表示所有人都可以访问,通常是用于对外开放的方法上,如下所示:

    package org.xxx.package1;public class Formatter{    public String describe() {        return "formatter";    }}

    Formatter的包是org.xxx,提供了一个describe()的方法,该方法可以被任何类调用。可以像下面这样来使用:

    package org.xxx.package2;import org.xxx.package1.Formatter;public class User{    public String describeFormatter() {        Formatter formatter = new Formatter();        return formatter.describe();    }}

    使用Formatter的类位于另一个包下面,是可以正常使用的。

    一般而言,不建议public修饰字段,如果开放某个字段,可以提供对应的gettersetter方法,比如:

    public class Person {    // private修饰符 后面会提到    private String name;    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }}

    这个也叫java bean,是一种非常常见的使用方法。

    public修饰字段一般是用于常量的声明,比如一周有七天,很多地方需要使用这个信息,就可以声明一个常量public static final int DAYS_OF_WEEK = 7;,后面需要用这个数字进行计算的都使用DAYS_OF_WEEK常量来计算,可以使代码比较清晰明了。

    private

    private关键字意味着这个方法/字段无法被其他类以常规方法(非常规方法指反射)访问,包括同一个包里面的其他类,也无法访问。下面是一个样例:

    public class Constants {    public static final int DAYS_OF_WEEK = 7;    private Constants() {    }}

    这个样例中,private被用到了构造器上,说明这个类无法被其他类通过new Constants()的方法实例化,原因是这个类是用于定义常量的类,它本身不需要被实例化。上文提到的常量一般可以通过这种方式定义。
    如果某个常量只在一个类里面使用,也可以直接定义在类内部,比如:

    public class WeekUtil {    private static final int DAYS_OF_WEEK = 7;    public static int daysOfWeeks(int weekNum) {        return DAYS_OF_WEEK * weekNum;    }}

    daysOfWeeks(int weekNum)方法可以计算指定周数有多少天,这里就使用private来定义了DAYS_OF_WEEK常量。

    protected

    protected修饰的内容可以被子类访问,无论子类在哪个包下都可以。

    比如我们有一个类Animal在包org.example下,声明了一个age字段:

    package org.example;public class Animal {    protected int age;}

    有一个类Duck继承了这个类,它在org.example.duck下:

    package org.example;import org.example.Animal;public class Duck extends Animal{    public int ageOfDuck(){        return age;    }}

    Duck中是可以自由使用age字段的。

    package-private与protected

    这两种权限很容易混淆,在使用时,可以分开来看。**两种权限是相互独立的,只要满足其中一条就可以访问到。**比如上文的类Animal,加了个字段:

    package org.example;public class Animal {    protected int age;    String name;}

    子类在org.example包里面时,包权限生效,name可以被访问到,子类不在org.example里面时,只能访问到age。同一个包里面的其他类,只能访问到name字段。

    玩转 Java8 Stream,让你代码更高效紧凑简洁

    玩转 Java8 Stream,让你代码更高效紧凑简洁

    文章目录

    前言

    一、Stream 特性

    二、Stream 创建

    2.1 用集合创建流

    2.2 用数组创建流

    2.3 Stream静态方法

    三、Stream 使用案例

    3.1 遍历 forEach

    3.2 过滤 filter

    3.3 查找 findFirst,findAny

    3.4 匹配 match

    3.5 映射 map

    3.6 截取流 limit

    3.7 排序 sorted

    3.8 去重 distinct

    3.9 统计 summaryStatistics

    3.10 归约 reduce

    3.11 归集 toList,toSet,toMap

    3.12 分组 partitioningBy,groupingBy

    3.13 合并 joining

    四、演示代码获取

    前言

    Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Oracle 公司于 2014 年 3 月 18 日 Java 8 ,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等。
    新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中。它可以让你以一种声明的方式处理数据,从而写出高效率、干净、简洁的代码。
    这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。

    一、Stream 特性

      元素是特定类型的对象,形成一个队列。 Java中的Stream不会存储元素,而是按需计算按照特定的规则对数据进行计算,一般会输出结果。

      Stream不会改变数据源,一般情况下会产生一个新的集合或者新值。

      Stream流的,可以是集合,数组,I/O channel, 产生器generator 等等。

      Stream具有延迟执行特性,只有调用终端操作时,中间操作才会执行。中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。

      以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

    Stream流的操作可以大概分为2种:

      中间操作:每次操作都返回流对象本身。

      终端操作:一个流只可以进行一次终端操作,即产生一个新的集合或者新值。终端操作结束后流无法再次使用。

    二、Stream 创建

    在 Java 8 中, Stream可以由集合或数组创建而来,生成的流有2种类型:

    stream() :串行流,由主线程按顺序对流执行操作。parallelStream() :并行流,内部以多线程并行执行的方式对流进行操作,但前提是流中的数据处理没有顺序要求。例如计算集合中的数量之和。如果流种数据量很大,并行流可以加快处理速度。串行流可以通过parallel()方法把顺序流转换成并行流。

    2.1 用集合创建流

    因为集合继承或实现了java.util.Collection接口,而Collection接口定义了stream()parallelStream()方法,所以可通过集合的stream() 和parallelStream()方法创建流。

    // 创建集合List<String> list = Arrays.asList("张三", "李四", "王五");// 创建一个串行流Stream<String> stream = list.stream();// 创建一个并行流Stream<String> parallelStream = list.parallelStream();123456

    2.2 用数组创建流

    使用java.util.Arrays.stream(T[] array)方法用数组创建流。

    // 创建数组String[] persons = {"张三", "李四", "王五"};// 创建一个串行流Stream<String> stream = Arrays.stream(persons);// 创建一个并行流Stream<String> parallelStream = Arrays.stream(persons).parallel();123456

    2.3 Stream静态方法

    使用Stream的静态方法生成Stream,例如of()iterate()generate()等。

    Stream<String> stream2 = Stream.of("张三", "李四", "王五");// 输出5个奇数 1 3 5 7 9Stream<Integer> stream3 = Stream.iterate(1, x -> x + 2).limit(5);stream3.forEach(System.out::println);// 生成2个UUIDStream<UUID> stream4 = Stream.generate(UUID::randomUUID).limit(2);stream4.forEach(System.out::println);123456789

    三、Stream 使用案例

    以下所有案例会基于学生数据,学生类,以及测试数据如下:

    package com.nobody;/** * @Description 学生类 * @Author Mr.nobody * @Date 2021/1/17 * @Version 1.0 */public class Student {    // 主键    private String id;    // 姓名    private String name;    // 年龄    private int age;    // 性别    private String sex;    // 成绩    private double score;    public Student(String id, String name, int age, String sex, double score) {        this.id = id;        this.name = name;        this.age = age;        this.sex = sex;        this.score = score;    }	// 省略get和set方法,toString方法,如若测试需自行添加12345678910111213141516171819202122232425262728
    List<Student> students = new ArrayList<>(16);students.add(new Student("1", "张三", 18, "male", 88));students.add(new Student("2", "李四", 17, "male", 60));students.add(new Student("3", "王五", 18, "male", 100));students.add(new Student("4", "赵六", 20, "male", 10));students.add(new Student("5", "董七", 14, "female", 95));students.add(new Student("6", "幺八", 21, "male", 55));students.add(new Student("7", "老九", 20, "female", 66));students.add(new Student("8", "小明", 18, "male", 100));students.add(new Student("9", "小红", 22, "female", 95));students.add(new Student("10", "小张", 25, "male", 90));1234567891011

    3.1 遍历 forEach

    students.stream().forEach(System.out::println);// 输出结果Student{id='1', name='张三', age=18, sex=male, score=88.0}Student{id='2', name='李四', age=17, sex=male, score=60.0}Student{id='3', name='王五', age=18, sex=male, score=100.0}Student{id='4', name='赵六', age=20, sex=male, score=10.0}Student{id='5', name='董七', age=14, sex=female, score=95.0}Student{id='6', name='幺八', age=21, sex=male, score=55.0}Student{id='7', name='老九', age=20, sex=female, score=66.0}Student{id='8', name='小明', age=18, sex=male, score=100.0}Student{id='9', name='小红', age=22, sex=female, score=95.0}Student{id='10', name='小张', age=25, sex=male, score=90.0}12345678910111213

    3.2 过滤 filter

    // 过滤出成绩100分的学生List<Student> students1 =        students.stream().filter(student -> student.getScore() == 100).collect(Collectors.toList());students1.forEach(System.out::println);// 输出结果Student{id='3', name='王五', age=18, sex=male, score=100.0}Student{id='8', name='小明', age=18, sex=male, score=100.0}12345678

    3.3 查找 findFirst,findAny

    一般filter和find搭配使用,即从过滤符合条件的数据中,获得一个数据。

    // 串行流,匹配第一个Optional<Student> studentOptional =        students.stream().filter(student -> student.getAge() >= 20).findFirst();if (studentOptional.isPresent()) {    Student student = studentOptional.get();    System.out.println(student);}// 上面输出语句可简写如下// studentOptional.ifPresent(System.out::println);// 并行流,匹配任意一个,findAny一般用于并行流Optional<Student> studentOptiona2 =        students.parallelStream().filter(student -> student.getAge() >= 20).findAny();studentOptiona2.ifPresent(System.out::println);// 输出结果Student{id='4', name='赵六', age=20, sex=male, score=10.0}Student{id='7', name='老九', age=20, sex=female, score=66.0}123456789101112131415161718

    3.4 匹配 match

    // 是否存在100分的学生boolean anyMatch = students.stream().anyMatch(student -> student.getScore() == 100);// 是否全部学生都100分boolean allMatch = students.stream().allMatch(student -> student.getScore() == 100);// 是否全部学生都没有100分boolean noneMatch = students.stream().noneMatch(student -> student.getScore() == 100);System.out.println(anyMatch);System.out.println(allMatch);System.out.println(noneMatch);// 输出结果truefalsefalse1234567891011121314

    3.5 映射 map

    映射,顾名思义,将一个对象映射成另外一个对象。即一个Stream流中的所有元素按照一定的映射规则,映射到另一个流中。映射有map和flatMap两种类型:

    map:接收一个函数作为参数,此函数作用到Stream中每一个元素,形成一个新的元素,所有新的元素组成一个新的流。

    flatMap:接收一个函数作为参数,它将流中的每个元素都转换成另一个流,然后把所有流再连接形成一个最终流。

    // 获取每个学生的姓名List<String> studentNames =        students.stream().map(Student::getName).collect(Collectors.toList());System.out.println(studentNames);// 每个学生的成绩加10分List<Double> studentScores = students.stream().map(student -> student.getScore() + 10)        .collect(Collectors.toList());System.out.println(studentScores);// 输出结果[张三, 李四, 王五, 赵六, 董七, 幺八, 老九, 小明, 小红, 小张][98.0, 70.0, 110.0, 20.0, 105.0, 65.0, 76.0, 110.0, 105.0, 100.0]123456789101112
    List<String> list = Arrays.asList("a-b-c-d", "g-h-i");List<String> list1 = list.stream().flatMap(s -> Arrays.stream(s.split("-"))).collect(Collectors.toList());System.out.println(list1);// 输出结果[a, b, c, d, g, h, i]123456

    3.6 截取流 limit

    // limit方法用于获取指定数量的流。例如下面演示取出学习成绩大于70的5个人List<Student> students2 = students.stream().filter(student -> student.getScore() > 70)        .limit(5).collect(Collectors.toList());students2.forEach(System.out::println);// 跳过第一个再取2个List<Student> students8 = students.stream().skip(1).limit(2).collect(Collectors.toList());// 获取5个int随机数,按从小到大排序Random random = new Random();random.ints().limit(5).sorted().forEach(System.out::println);// 输出结果Student{id='1', name='张三', age=18, sex=male, score=88.0}Student{id='3', name='王五', age=18, sex=male, score=100.0}Student{id='5', name='董七', age=14, sex=female, score=95.0}Student{id='8', name='小明', age=18, sex=male, score=100.0}Student{id='9', name='小红', age=22, sex=female, score=95.0}-14902027141453405473683321553883993981099579920123456789101112131415161718192021

    3.7 排序 sorted

    sorted 方法用于对流中的元素进行排序,有两种排序:

    sorted():自然排序,流中元素需要实现Comparable接口。

    sorted(Comparator<? super T> comparator):需要自定义排序器。

    // 按成绩升序List<Student> students3 = students.stream().sorted(Comparator.comparing(Student::getScore))        .collect(Collectors.toList());System.out.println("按成绩升序");students3.forEach(System.out::println);// 按成绩降序List<Student> students4 =        students.stream().sorted(Comparator.comparing(Student::getScore).reversed())                .collect(Collectors.toList());System.out.println("按成绩降序");students4.forEach(System.out::println);// 按成绩升序,再按年龄升序List<Student> students5 = students.stream()        .sorted(Comparator.comparing(Student::getScore).thenComparing(Student::getAge))        .collect(Collectors.toList());System.out.println("按成绩升序,再按年龄升序");students5.forEach(System.out::println);// 按成绩升序,再按年龄降序List<Student> students6 = students.stream().sorted((s1, s2) -> {    if (s1.getScore() != s2.getScore()) {        return (int) (s1.getScore() - s2.getScore());    } else {        return (s2.getAge() - s1.getAge());    }}).collect(Collectors.toList());System.out.println("按成绩升序,再按年龄降序");students6.forEach(System.out::println);123456789101112131415161718192021222324252627

    3.8 去重 distinct

    List<String> list2 = Arrays.asList("a", "b", "a", "c", "f", "e", "f");List<String> list3 = list2.stream().distinct().collect(Collectors.toList());Set<String> stringSet = list2.stream().collect(Collectors.toSet()); // list转set也可以达到去重效果System.out.println(list3);System.out.println(stringSet);// 输出结果[a, b, c, f, e][a, b, c, e, f]123456789

    3.9 统计 summaryStatistics

    一些收集器能产生统计结果,例如Collectors提供了一系列用于数据统计的静态方法,它们主要用于int、double、long等基本类型上。

    // 总和统计summaryStatisticsDoubleSummaryStatistics doubleSummaryStatistics =        students.stream().mapToDouble(Student::getScore).summaryStatistics();System.out.println("平均值:" + doubleSummaryStatistics.getAverage());System.out.println("总个数:" + doubleSummaryStatistics.getCount());System.out.println("最大值:" + doubleSummaryStatistics.getMax());System.out.println("最小值:" + doubleSummaryStatistics.getMin());System.out.println("总和值:" + doubleSummaryStatistics.getSum());// 输出结果平均值:75.9总个数:10最大值:100.0最小值:10.0总和值:759.0123456789101112131415
    // 统计个数long count = students.stream().count();// 平均值Double averageScore =        students.stream().collect(Collectors.averagingDouble(Student::getScore));// 最大值和最小值Optional<Double> maxScore = students.stream().map(Student::getScore).max(Double::compare);Optional<Double> minScore = students.stream().map(Student::getScore).min(Double::compare);// 求和double sumScore = students.stream().mapToDouble(Student::getScore).sum();// 一次性统计所有DoubleSummaryStatistics doubleSummaryStatistics1 =        students.stream().collect(Collectors.summarizingDouble(Student::getScore));System.out.println("单个维度计算:");System.out.println("统计个数:" + count);System.out.println("平均值:" + averageScore);maxScore.ifPresent(aDouble -> System.out.println("最大值:" + aDouble));minScore.ifPresent(aDouble -> System.out.println("最小值:" + aDouble));System.out.println("求和:" + sumScore);System.out.println("一次性统计所有:" + doubleSummaryStatistics1);// 输出结果单个维度计算:统计个数:10平均值:75.9最大值:100.0最小值:10.0求和:759.012345678910111213141516171819202122232425262728

    3.10 归约 reduce

    归约,把一个流归约(缩减)成一个值,能实现对集合求和、求乘积和求最值等操作。

    List<Integer> integerList = Arrays.asList(6, 7, 1, 10, 11, 7, 13, 20);// 求和Optional<Integer> sum1 = integerList.stream().reduce(Integer::sum);// 求和,基于10的基础上Integer sum2 = integerList.stream().reduce(10, Integer::sum);// 求最大值Optional<Integer> max1 = integerList.stream().reduce((x, y) -> x > y ? x : y);// 求最大值,基于与50比较的基础上Integer max2 = integerList.stream().reduce(50, Integer::max);Optional<Integer> min = integerList.stream().reduce(Integer::min);// 求乘积Optional<Integer> product = integerList.stream().reduce((x, y) -> x * y);System.out.println("原始集合:" + integerList);System.out.println("集合求和:" + sum1.get() + "," + sum2);System.out.println("集合求最大值:" + max1.get() + "," + max2);System.out.println("集合求最小值:" + min.get());System.out.println("集合求积:" + product.get());// 输出结果原始集合:[6, 7, 1, 10, 11, 7, 13, 20]集合求和:75,85集合求最大值:20,50集合求最小值:1集合求积:8408400123456789101112131415161718192021222324

    3.11 归集 toList,toSet,toMap

    Java中的Stream不会存储元素,而是按需计算按照特定的规则对数据进行计算,一般会输出结果。所以流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。比较常用的是toList、toSet和toMap,以及复杂的toCollection、toConcurrentMap等。

    // 获取学生名字,形成新的list集合List<String> studentNames1 =        students.stream().map(Student::getName).collect(Collectors.toList());// 获取年龄大于等于15的年龄set集合Set<Integer> ageSet = students.stream().filter(student -> student.getAge() >= 15)        .map(Student::getAge).collect(Collectors.toSet());// 创建学生ID和学生实体的mapMap<String, Student> studentMap =        students.stream().collect(Collectors.toMap(Student::getId, student -> student));System.out.println(studentNames1);System.out.println(ageSet);studentMap.forEach((key, value) -> System.out.println(key + ":" + value));// 输出结果[张三, 李四, 王五, 赵六, 董七, 幺八, 老九, 小明, 小红, 小张][17, 18, 20, 21, 22, 25]1:Student{id='1', name='张三', age=18, sex=male, score=88.0}2:Student{id='2', name='李四', age=17, sex=male, score=60.0}3:Student{id='3', name='王五', age=18, sex=male, score=100.0}4:Student{id='4', name='赵六', age=20, sex=male, score=10.0}5:Student{id='5', name='董七', age=14, sex=female, score=95.0}6:Student{id='6', name='幺八', age=21, sex=male, score=55.0}7:Student{id='7', name='老九', age=20, sex=female, score=66.0}8:Student{id='8', name='小明', age=18, sex=male, score=100.0}9:Student{id='9', name='小红', age=22, sex=female, score=95.0}10:Student{id='10', name='小张', age=25, sex=male, score=90.0}1234567891011121314151617181920212223242526

    3.12 分组 partitioningBy,groupingBy

    partitioningBy(分区):stream中的元素按条件被分为两个Map。
    groupingBy(分组):stream中的元素按条件被分为多个Map。

    // 按条件学生成绩是否大于等于60,划分为2个组Map<Boolean, List<Student>> studentScorePart = students.stream()        .collect(Collectors.partitioningBy(student -> student.getScore() >= 60));// 按性别分组Map<String, List<Student>> studentSexMap =        students.stream().collect(Collectors.groupingBy(Student::getSex));// 按年龄分组Map<Integer, List<Student>> studentAgeMap =        students.stream().collect(Collectors.groupingBy(Student::getAge));// 先按性别分组,再按年龄分组Map<String, Map<Integer, List<Student>>> collect = students.stream().collect(        Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));System.out.println("按条件学生成绩是否大于等于60,划分为2个组:");studentScorePart.forEach((aBoolean, students7) -> {    System.out.println("成绩大于等于60?:" + aBoolean);    students7.forEach(System.out::println);});System.out.println("按性别分组:");studentSexMap.forEach((sex, students7) -> {    System.out.println("性别?:" + sex);    students7.forEach(System.out::println);});System.out.println("按年龄分组:");studentAgeMap.forEach((age, students7) -> {    System.out.println("年龄:" + age);    students7.forEach(System.out::println);});System.out.println("先按性别分组,再按年龄分组:");collect.forEach((sex, integerListMap) -> {    System.out.println("性别:" + sex);    integerListMap.forEach((age, students7) -> {        System.out.println("年龄:" + age);        students7.forEach(System.out::println);    });});//输出结果按条件学生成绩是否大于等于60,划分为2个组:成绩大于等于60?:falseStudent{id='4', name='赵六', age=20, sex=male, score=10.0}Student{id='6', name='幺八', age=21, sex=male, score=55.0}成绩大于等于60?:trueStudent{id='1', name='张三', age=18, sex=male, score=88.0}Student{id='2', name='李四', age=17, sex=male, score=60.0}Student{id='3', name='王五', age=18, sex=male, score=100.0}Student{id='5', name='董七', age=14, sex=female, score=95.0}Student{id='7', name='老九', age=20, sex=female, score=66.0}Student{id='8', name='小明', age=18, sex=male, score=100.0}Student{id='9', name='小红', age=22, sex=female, score=95.0}Student{id='10', name='小张', age=25, sex=male, score=90.0}按性别分组:性别?:femaleStudent{id='5', name='董七', age=14, sex=female, score=95.0}Student{id='7', name='老九', age=20, sex=female, score=66.0}Student{id='9', name='小红', age=22, sex=female, score=95.0}性别?:maleStudent{id='1', name='张三', age=18, sex=male, score=88.0}Student{id='2', name='李四', age=17, sex=male, score=60.0}Student{id='3', name='王五', age=18, sex=male, score=100.0}Student{id='4', name='赵六', age=20, sex=male, score=10.0}Student{id='6', name='幺八', age=21, sex=male, score=55.0}Student{id='8', name='小明', age=18, sex=male, score=100.0}Student{id='10', name='小张', age=25, sex=male, score=90.0}按年龄分组:年龄:17Student{id='2', name='李四', age=17, sex=male, score=60.0}年龄:18Student{id='1', name='张三', age=18, sex=male, score=88.0}Student{id='3', name='王五', age=18, sex=male, score=100.0}Student{id='8', name='小明', age=18, sex=male, score=100.0}年龄:20Student{id='4', name='赵六', age=20, sex=male, score=10.0}Student{id='7', name='老九', age=20, sex=female, score=66.0}年龄:21Student{id='6', name='幺八', age=21, sex=male, score=55.0}年龄:22Student{id='9', name='小红', age=22, sex=female, score=95.0}年龄:25Student{id='10', name='小张', age=25, sex=male, score=90.0}年龄:14Student{id='5', name='董七', age=14, sex=female, score=95.0}先按性别分组,再按年龄分组:性别:female年龄:20Student{id='7', name='老九', age=20, sex=female, score=66.0}年龄:22Student{id='9', name='小红', age=22, sex=female, score=95.0}年龄:14Student{id='5', name='董七', age=14, sex=female, score=95.0}性别:male年龄:17Student{id='2', name='李四', age=17, sex=male, score=60.0}年龄:18Student{id='1', name='张三', age=18, sex=male, score=88.0}Student{id='3', name='王五', age=18, sex=male, score=100.0}Student{id='8', name='小明', age=18, sex=male, score=100.0}年龄:20Student{id='4', name='赵六', age=20, sex=male, score=10.0}年龄:21Student{id='6', name='幺八', age=21, sex=male, score=55.0}年龄:25Student{id='10', name='小张', age=25, sex=male, score=90.0}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102

    3.13 合并 joining

    将stream中的元素用指定的连接符(没有的话,则直接连接)连接成一个字符串。

    String joinName = students.stream().map(Student::getName).collect(Collectors.joining(", "));System.out.println(joinName);// 输出结果张三, 李四, 王五, 赵六, 董七, 幺八, 老九, 小明, 小红, 小张12345

    原文:https://blog.csdn.net/chenlixiao007/article/details/112752413?utm_medium=distribute.pc_category.none-task-blog-hot-6.nonecase&depth_1-utm_source=distribute.pc_category.none-task-blog-hot-6.nonecase&request_id=

    作者: Μr.ηobοdy

    欢迎点赞+评论+转发!!

    再见容易再见难