Java面向对象 OOP

Java面向对象编程 OOP

Java是一种高级语言
面向对象的三大特性 : 封装、继承、多态
面向对象是一个设计思想,更加贴合人们处理事物的方式

从语法角度上看: 类是用class修饰符的
类是抽象的,看不见也摸不着
类是自然界用来描述具有相同的特征行为的事物的统称
在编程中,特征 用 属性 来表述, 行为用 方法 来描述

对象

对象是类的具体实现, 万物皆为对象
类是对象的模板

成员变量 VS 局部变量

  • 在类中定义的变量 被成为 成员变量
  • 在方法中定义的变量,被成为局部变量

局部变量:

  1. 局部变量必须赋初值才能使用,没有默认值
  2. 作用范围: 从声明开始 到离他最近的代码块结束

成员变量:

  1. 使用方式: 有默认值,可以直接使用
  2. 作用范围: 在整个类中都可以使用

构造方法

  • 作用
  1. 用来创建对象
  2. 给属性赋值 (一般通过有参构造方法)
  • 特点:
  1. 构造方法的方法名和类名完全一致
  2. 构造方法不用设置返回值类型
  3. 构造方法通过 new 来调用

当一个类中没有提供构造方法的时候,JVM会默认提供一个无参的构造方法
如果类中提供了构造方法,那么JVM就不会在提供默认的构造方法

方法的重载

在一个类中,方法名允许重名、这种一个类中多个相同的方法名 就被称为方法重载

方法重载的要求

  1. 方法名相同
  2. 参数列表不同 (参数的个数不同 或 参数的类型不同)

实例代码块

特点: 在类中定义的代码块
作用: 在对象创建完成前、做一些初始化工作 ,
本质是 在构造方法 调用前执行的代码

权限修饰符

用来控制访问权限的
权限修饰符可以写在 类、 属性、方法、构造方法上

  • public (公共的)
  • protected (受保护的)
  • default/friendly (默认的、不写修饰符,就是默认的)
  • private (私有的)

类只能使用 public 或者 default 修饰
内部类 可以使用 所有权限修饰符

public : 可以在任意位置被访问和使用

protected : 修饰的方法、属性 只能在 子类 或者 同一个包 中 被使用

default : 只能在同一个包中被使用

private : 只能在自己的类中被使用

包 package

包可以理解成一个比较特殊的文件夹、是用来管理类文件的
是构成类的重要组成部分、是类的一部分,可以解决类名冲突问题
一个类的完整名字是 包 + 类
如果一个类 不在任何包下, 那么它会被存放在 default 包
包名 是一个标识符、必须在定义的时候遵循标识符的命名规范
包的命名采用 全小写、多个包之间 用 . 进行分割
包一般都会采用 公司/企业/组织的 官方域名的倒序
包 用 package 来表示,必须出现在源代码的第一行

www : (万维网), 一级域名 

qikux : (公司/组织的简称) :  二级域名

com : (行业性质) : 顶级域名 

导入包下的类

  • import 包.类 ;
import java.util.Scanner ;
  • import 包.* ;

批量将一个包下的所有类全部导入,推荐不推荐使用

import java.util.* ; 

import java.util. 无法导入 java.util.abc 下的类*

  • import static 包.类.静态方法
import static java.util.Arrays.toString

java中常见的内置包

  • java.lang : 是java的基础包,JDK默认会自动导入该包下的所有类,所以该包下的类,不需要导入直接可以使用

  • java.util : 是 JDK 提供的一个工具包,里面包含了大量的 工具类

  • java.io : 和 文件相关的一个包

  • java.net : 和 网络相关的一些包

  • java.sql : 和 数据库操作相关的一些包

封装

把自然界中具有相似属性和方法的事物封装到一个类中,并尽可能的私有化属性 方法进行公开。

Field 和 Property

  • Field : 在类中定义的成员变量
  • Property : 在类中定义的 set/get方法,去掉 set/get 之后,首字母变小写

开发中一般要求 Field 和 Property 保持一致
ALT + 7 快捷键可以 打开 一个类的结构图

this 关键字

this 表示的 类对应的 对象, this 指的是 调用类中定义的 属性/方法 对应的那个对象
this 代表当前对象

  • this 可以调用成员变量
  • this 可以调用成员方法
  • this 可以调用构造方法 (构造方法调用类中的其他构造方法)

this 调用构造方法,需要后面跟 (), 并且 this在调用构造方法的时候,必须出现在 构造方法的第一句

toString()

将对象 以字符串的形式来表示
toString 来自于 Object类、是所有对象都拥有的一个方法
打印一个对象、本质上是打印这个对象的toString()方法

public String toString() {
    ...
}

Object 类

在 java.lang 包中,是Java中所有类型(8种基本数据类型除外)的父类,表示对象
Object中定义的所有方法,所有类都可以直接调用

Object 中常见的方法

  • String toString() : 以字符串的形式表示一个对象

  • Class<?> getClass() : 获取一个对象的类型,一个对象有且只有一个类型

// 比较两个对象是否是同一个类型 
obj.getClass()  ==  obj2.getClass() ;
  • int hashCode() : 获取一个对象的 哈希值 、主要运用与 和 has 算法相关的操作中

  • boolean equals(Object obj) : 用来比较两个对象内容是否相等、但 Object中的 equals 默认比较的是 两个对象的地址

== 的作用 

1. 如果是两个基本数据类型做比较,那么 == 比较的是 两个值是否相等
2. 如果是两个对象做比较,那么 == 比较的是两个对象的地址是否相等 
3. 如果两个对象需要比较内容,那么只能用 equals 进行比较,但 但 Object中的 equals 默认比较的是 两个对象的地址,如果需要,自己需要重写 equals 

  • clone() : 可以克隆一个对象, 是一个受保护的方法

  • finalize() : 用来进行垃圾回收的方法,但在 JDK9已经被标记为过时

equals 方法的使用

官方定义的是 用来比较两个对象的内容是否相等,但 Object 默认比较的是两个对象的地址是否相等
Objects.equals(a, b) : 比较 a 和 b 的内容是否相等,可以解决 a , b 为空,空指针的问题

如果在 自定义的类中,比较两个对象的内容是否一致 ???

public boolean equals(Object obj) {
    if (this == obj) return true ; 
    if (obj == null || obj.getClass() != Dog.class) return false ;
    Dog dog = (Dog) obj ;
    // 追个比较属性
    return Objects.equals(type, dog.type) && Objects.equals(color , dog.color)
}

static 修饰符

static 可以修饰 属性、方法、代码块、 内部类

static 修饰属性

如果一个属性被 static 修饰,那么这个属性就被称为 静态属性
类中定义的属性是所有对象都拥有的特征、每一个对象的属性对应的属性值都是 相互独立的
静态属性的值被类的所有对象所共享、本质上和 对象 没有关系 ,静态属性只和类有关系
静态属性 推荐使用 类来进行调用,而不推荐使用对象调用

static 修饰方法

如果一个方法被 static 修饰,那么这个方法就被称为 静态方式
静态方法通过 类 来调用,不推荐 使用 对象 来调用
static 修饰的方法 可以被子类继承、但不能被重写没有多态效果

空指针异常: 如果一个对象的值是 null, 那么在调用成员方法的时候,就会发生 NullPointException(空指针异常)

static 修饰代码块

类加载

当 JVM 第一次 读取一个类的时候、会将 类的字节码信息 读取到 内存中,这个过程被称为 类加载
一个类 只会发生一次 类加载、 类加载的产物 被称为 类对象
一个类的类对象只有一个、用 Class 表示 , 获取 类对象的方式有三种

类对象的获取方式
  • 对象.getClass()
  • 类.class
  • Class.forName(“类的全名”)
类加载过程
  1. 分配空间
  2. 加载 静态属性 (此时属性还没有值)
  3. 从上到下,一次读取 静态属性 和 静态代码块
  4. 检查静态属性是否有值、如果没有值、则设置默认值
  5. 将静态方法加载到 方法区

final 修饰符

final 最终的意思
final 可以修改 类 、属性、 方法 、局部变量

final 修饰属性
  • final 修饰一个变量、那么变量就成为了 常量
  • 常量在 Java中,要求使用 全大写 的命名规范 、多个单词用下划线分割(蛇形标识)
  • final 修饰一个属性、那么属性的默认值就失效了, 要求 必须赋初值
  • final 修饰的属性,一旦赋值,不可更改
  • final 修饰的属性如果是 基本数据类型 ,那么代表 值不可改变
  • final 修饰的属性 如果是 引用数据类型, 那么代表 指向的地址不可改变
final 修饰属性 可以 赋值的 位置 

1.  在声明属性的时候,直接赋值 (常用)
2.  在代码块中 完成属性 赋值 
3.  在构造方法中,完成属性赋值 (常用)

final 修饰 局部变量

一个局部变量 可以被 final 修饰,且可以不需要给 初始值, 在使用前 赋初值 即可

final 修饰 类

如果一个类 被 final 修饰,那么 这个类 是一个最终类, 不能被继承
如果一个类 被 final 修饰,那么这个类中所有的方法 都会被 final 自动修饰

final 修饰 方法

如果一个 方法 被 final 修饰, 那么这个方法是一个最终方法, 不允许被 子类重写

枚举 Enum

使用 关键字 enum 来表示 ,
枚举中的每一个值 都表示 枚举类型对应的对象
枚举类可以定义私有构造方法、完成枚举值含义的介绍

继承

方法的重写

一定是发生在父子类中,且在子类中进行方法的重写
当父类中提供的方法不满足子类的需求的时候,才进行重写
能重写的方式 一定是 可以继承的方法

  1. 修饰符 和 父类 保持相同 或者 比 父类 修饰符的 权限 更宽
  2. 返回值、方法名、参数列表 三者必须和父类完全相同
  3. 异常的处理 必须和 父类 保持 相同 或者 比 父类更窄

可以使用 CTRL + O 快速重写父类的方法

@Override 注解 可以写在 被重写的方法上,用来做语法检查,如果不符合重写的要求,则代码会直接编译不通过

super 关键字

super 可以调用 父类的 属性、 方法、 构造方法

形参 VS 实参

形参: 在声明一个方法, 方法参数列表中定义的 参数名
实参: 在调用方法的时候,传入的参数被称为 实参

形参: 形参参数名 不是特别重要,只要符合标识符命名规范即可,重要的形参对应的数据类型
实参: 内容和类型都很重要

参数传递
  1. 引用传递 : 如果参数类型是 引用数据类型,发生 引用传递
  2. 值传递 : 如果参数是基本数据类型,发生 值传递

Java严格来说,没有引用传递,所有传递都是值传递

抽象类 和 普通类的区别

  1. 抽象类使用 abstract class修饰 , 而 类只使用 class 修饰
  2. 抽象类中可以有抽象方法、但类中不能出现 抽象方法
  3. 抽象类有构造方法但不能创建对象, 类有构造方法且可以创建对象
  4. 抽象类不能被final 修饰,而类可以

多态

将子类对象赋值给父类引用,调用父类的方法、显示子类的结果
缺点: 会丢失子类的特性
优势: 程序的可扩展性会更强

  • 向上转型: 将子类对象赋值给父类引用 (自动转换)
  • 向下转型: 将指向父类的对象 赋值给子类引用 (强制转换)

对象是不是某个类型

对象 instanceof 类型

if (obj instanceof Type) {
    
    Type type = (Type) obj ;
     
}

JDK16 新增特性

if (obj instanceof Type type) {
    ... ;
}

内部类

在 类的里面 或者 方法的里面 定义的类

  • 成员内部类

  • 静态内部类 (常用)

  • 局部内部类 (忘记吧)

  • 匿名内部类 (常用)

成员内部类

在类中定义的成员类

public class Bank {

    public  class ATM {
    
    }
}

// 创建 ATM 对象
Bank.ATM atm = new Bank().new ATM(); 

静态内部类

在类中定义的 静态类

public class Bank {

    public static class ATM {
    
    }
}

// 创建 ATM 对象
Bank.ATM atm = new Bank.ATM(); 

局部内部类

在方法中定义的类

public  class Bank {

    public int getMoney(int money) {
    
        class ATM {
            public getMoney(int money) {
                return money ;
            }
        }
        
        return new ATM().getMoney(money);
    }
}

匿名内部类

  • 本质: 快速的构建一个类的子类(匿名类)对象
// 快速创建一个 Dog 的子类对象
Dog dog = new Dog() { ... }

设计模式 - 建造者模式

  1. 在类中,定义一个静态内部类作为 外部类的 建造者
  2. 在建造者类中,提供多个 方法用来完成 外部类 对象的属性赋值
  3. 在建造者类中,提供一个 build() 用来返回一个外部类的对象
  4. 在类中,通常定义一个静态的 builder() 来返回一个 建造者对象

将 对象的 属性(特征) 和 方法(行为)进行一个分离
对象中的属性交由建造者进行管理
对象中的方法由自己来调用

Lombok

对模板化代码进行快速生成的插件
在工程中引入 Lombok.jar

Lombok常用注解

  • @Getter

用来生成对应的 get方法、可以写在类上 或者 属性上

  • @Setter

用来生成对应的 set方法、可以写在类上 或者 属性上

  • @ToString

用来生成类中的 toString方法, 只能应用于 类上

  • @EqualsAndHashCode

用来生成类中的 equals 和 hashCode 方法, 只能应用于类上

  • @Data

等价于在类上,同时使用 @Setter, @Getter, @ToString, @EqualsAndHashCode

  • @NoArgsConstructor

用来在类上 快速生成无参构造

  • @AllArgsConstructor

用来在类上,快速生成 带有 所有参数的构造方法,参数的顺序由 在类上属性的定义顺序来决定

  • @RequiredArgsConstructor

配合 @NonNull(非空注解), 来定义指定参数的构造方法, 将所有的 @NonNull 注解的Field属性 作为 构造方法的参数

  • @Builder

用来给 当前标记的类 提供 建造者模式

一般情况下,如果类中使用了 @Builder 注解, 那么 无参构造就不会被提供,所以通常情况下使用 @Builder注解,推荐使用 @Data, @NoArgsConstructor, @AllArgsConstructor
如果类中不需要建造者模式,那么一般推荐使用 @Data 注解

  • @Builder.Default

给属性设置默认值,如果使用了@Builder , 那么 属性中的默认值默认在建造者模式下不会生效,如果希望生效,则需要在属性前面添加 @Builder.Default

接口

接口是一种规范和标准, 用关键字 interface 标识接口
接口是一种特殊的抽象类
接口中所有的属性 都是 public static final 修饰的 (公开静态常量)
接口中的方法在 JDK7 以及一下版本,都是 公开 抽象方法
接口可以提高程序的可扩展性、降低程序之间的耦合度(低耦合高内聚)
一个类可以实现多个接口 (接口和类之间采用 多实现,使用 implements 关键字 )
接口描述的是一个对象 有没有 能力
接口与接口之间采用 多继承、使用 extends 关键字

接口 VS 类

  • 接口 使用 interface 修饰, 类使用 class修饰
  • 类是描述一个具有相同特征和行为的事物统称、接口是描述一种规范和标准
  • 接口与接口采用 多继承、接口和类采用多实现,而类与类采用单继承
  • 类中可以由 代码块,构造方法、方法、属性、内部类
  • 接口中不能有 代码块 和 构造方法
  • 类可以创建对象、接口不能,接口需要对应的子类去构建对象

接口 VS 抽象类

  • 接口中属性都是 public static final 修饰的, 而 抽象类中的属性 没有要求
  • 接口中的方法(JDK7)都是抽象方法, 而抽象类中 可以没有抽象方法
  • 接口中没有构造方法,而抽象类中有构造方法
  • 接口与接口采用 多继承、接口和类采用多实现,而类与类采用单继承

JDK8 接口的语法

  • 允许在接口中定义 default 修饰的成员方法, 主要解决接口中定义的多个方法重载复用的问题
  • 允许在接口中定义 public static 修饰的 方法

JDK9 接口的语法

  • 允许在接口中定义 private 修饰的成员方法,主要解决 default 修饰的成员方法 代码复用问题

JDK8 函数式接口 FunctionInterface

如果一个接口有且只有一个 抽象方法(不包含Object中定义的方法),那么这个接口就被称为函数式接口
如果一个接口是函数式接口,则可以使用一个注解 @FunctionalInterface 标记
如果一个接口是函数式接口 , 那么这个接口可以使用 Lambda 表达式 快速构建接口的子类对象

Lambda表达式

Lambda 表达式的语法:

  1. (参数列表) -> {… 方法的具体实现代码… }
  2. lambda表达式返回的是 该接口的子类对象

参数列表:

  1. 如果 没有参数, 则只需要写一个 () 即可
  2. 如果 有参数 ,括号中参数类型 可以省略
  3. 如果只有一个参数,可以在省略类型后,再省略 小括号

方法实现:

  1. 如果 实现代码只有一个语句 、则可以省略 { … }
  2. 如果省略大括号后,代码中包含 return ,则 必须省略 return

Comparable 接口

可比较, 如果一个类希望它的对象能够进行比较大小, 那么这个类就可以实现 Comparable接口,重写 compareTo(T obj) 方法
compareTo 返回一个 int ,如果 大于0 ,代表 调用者 大, 如果等于0,代表 一样大, 如果小于0,代表 被比较的对象大

Comparator 接口

用来比较2个对象的大小,即使对象没有实现 Comparable接口,也可以进行大小的比较
int compare(T o1, T o2) 抽象方法,是专门用来 制定比较对象大小的 标准


 // 3月份生日,固定薪资4000
SalariedEmployee salariedEmployee = new SalariedEmployee("张三", 3, 4000);
// 4月生日,时薪 50
HourlyEmployee hourlyEmployee = new HourlyEmployee("李四", 4, 175, 50);

// 如果 对象没有实现 Comparable接口,那么默认是不能比较大小的 ,但是 可以通过 Comparator 接口制定比较规则
int month = 3;
Comparator<Employee> comparator = (a, b) -> {
    double as = a.getSalary(month);
    double bs = b.getSalary(month);
    if (as > bs) return 1;

    if (as == bs) return 0;

    return -1;
} ;

// 比较两个员工薪资的高低 
int compare = comparator.compare(salariedEmployee, hourlyEmployee);

System.out.println(compare);

  • Comparator.reverseOrder() : 返回一个 Comparator 对象, 按照对象的默认提供的排序规则的相反规则进行比较,前提是对象所在的类必须实现Comparable 接口
  • Comparator.naturalOrder() : 返回一个 Comparator 对象,按照对象的默认比较规则,前提是对象所在的类必须实现Comparable 接口

public static void sort(Employee[] employee, Comparator comparator) {

}

Iterable

可迭代的, 如果一个类的对象希望能够被循环遍历,那么可以让这个类实现 Iterable 接口
重写 Iterable 接口中 的 iterator 方法,返回一个 迭代器
如果一个实现了Iterable 接口 ,那么就可以拥有 iterator遍历、 增强for循环、 forEach

Iterator

迭代器中有2个重要的抽象方法
hasNext() : 用来判断是否有下一个数据
next() : 用来获取下一个数据、并将索引 + 1

函数式接口的分类

函数式接口 对象的创建 可以通过 lambda表达式 , 它还支持 方法的引用,语法式 ::
方法引用: 在程序中,刚好有一个方法能够满足 函数式接口中抽象方法的实现要求,那么此时就可以通过 :: 的方式引入这个方法
作为 函数式接口中抽象方法的具体代码实现

  • 消费型接口

函数式接口中的抽象方法,只有参数,没有返回值(void), 那么该接口就被称为 消费型接口
Consumer : 消费一个参数
BiConsumer : 消费二个参数

// 构建一个Consumer的子类对象,负责将消费的数据 打印出来 
Consumer consumer = a -> System.out.println(a) ; 

成员方法 和 静态方法 

成员方法 使用 对象 来进行调用 ------>  对象::方法
静态方法 使用 类 来进行调用  ------>   类::方法

类:: 静态方法
类:: 成员方法 ----> 如果类引用成员方法,那么成员方法相当于默认第一个参数 是 类对应的对象 

打印语句是一个 消费者 
System.out.println("xxxxx") ; 
Consumer con = System.out::println

  • 生产型接口

抽象方法 没有参数,但有返回值
Supplier :

如何引用无参构造方法: 类型::new即可实现引用无参构造作为生产者对应的抽象方法的具体实现代码

Supplier<Car> sup = Car::new ; 

Car car = sup.get();
  • 功能型接口

既是生产者、又是消费者的函数式接口,被称为功能型接口
接口中的抽象方法,既有参数又有返回值

Function<T, R> : 消费一个 T, 返回一个 R
BiFunction<T, U, R> : 消费一个 T 和 U , 返回一个 R

BiFunction<Integer, Integer, Integer>  fn = Integer::sum ; 
int x = fn.apply(3, 6) ; // 9   

Function<Double, Double> f = Math::sqrt; 
double x = f.apply(25)  // 5
  • 断言型接口

是一个特殊的功能型接口, 生产的一定是 boolean 类型

Predicate : 消费一个 T, 返回一个 boolean
BiPredicate<T, U> : 消费一个 T 和 U , 返回一个 boolean

函数式接口在API中的应用

  • Stream 流式处理 : 主要用来处理数据的, 整个流式处理不会影响原有的数据

开始流 : 如何将数据转成流
中间流 : 对数据进行加工和处理
终止流 : 结束整个流式处理、完成对数据的组装

如何将数据(数组)转成流

  • IntStream stream = Arrays.stream(array) 将数组转成stream流
  • IntStream stream = Arrays.stream(array, start, end) 将数组指定的区间内的数据转成Stream流
  • IntStream.of(val…) : 将多个值转成 stream 流

常见的中间流

所有的中间流,默认都采用延迟加载,只有在调用终止流的时候,中间流才会执行对应的代码

  • map(IntUnaryOperator mapper) : IntUnaryOperator 是一个功能型接口,消费一个 int , 返回一个 int

只对流中的数据做修改,不会影响 流中数据的 类型 和 个数

  • mapToLong(IntToLongFunction mapper) : IntToLongFunction 是一个功能型接口,消费一个 int , 返回一个 long

只对流中的数据做修改,不会影响 流中数据的个数, 但流中数据的类型会发生改变

  • mapToDouble(IntToDoubleFunction mapper): IntToDoubleFunction是一个功能型接口,消费一个 int , 返回一个 double

只对流中的数据做修改,不会影响 流中数据的个数, 但流中数据的类型会发生改变

  • mapToObj(DoubleFunction<? extends U> mapper) : 消费一个数字, 返回一个任意的数据类型

只对流中的数据做修改,不会影响 流中数据的个数, 但流中数据的类型会发生改变

  • filter(Predicate predicate) : 过滤满足条件的数据,返回 0 ~ N个值

会将不满足条件的数据过滤掉,流中剩下的数据都是满足条件的数据,流中的数据个数可能会减少, 但对应的数据内容 不会发生任何变化

  • distinct() : 对流中的数据 进行去重

  • skip(n) : 跳过前面 n 个数据

  • dropWhile(Predicate predicate) : 删除满足条件的数据,直到不满足为止, JDK9

  • takeWhile(Predicate predicate) : 保留满足条件的数据、直到不满足为止, JDK9

  • peek(Consumer consumer) : 和 forEach用法类似,但peek是一个中间流,主要用来观察数据在流中的状态

常见的终止流

  • toArray(): 将流中的数据放入到数组中

  • max() : 获取数组中的最大值

  • min() : 获取数组中的最小值

  • sum() : 获取数组中元素的和

  • average() : 获取数组中元素的平均值

  • count() : 获取流中元素的个数

  • forEach() : 遍历流中的元素

  • allMatch(Predicate predicate) : 断言流中的数据全部满足指定的条件, 返回boolean

  • anyMatch(Predicate predicate) : 断言流中有元素满足指定的条件, 返回boolean

  • noneMatch(Predicate predicate) : 断言流中的所有元素全部不满足指定的条件, 返回boolean

  • findAny() : 获取 流中的一个元素, 主要应用于多线程环境

  • findFirst() : 获取 流中的第一个元素

  • int reduce(int identity, IntBinaryOperator op) : 用来进行统计

identity : 进行统计的结果的初始值
IntBinaryOperator : 消费两个参数 以 a, b 为例子 a 代表 上一轮统计的结果,如果是第一次进来,那么 a 会取 identity 作为初始值
b 代表 本轮要统计的数据、如果是第一次进来,则默认是 流中的 第一个数据, IntBinaryOperator 生产一个数据,生产的数据作为本轮统计的结果
会自动赋值给下一轮中的 a 作为值 下一轮 a 的初始值

  • int reduce(IntBinaryOperator op) : 用来进行统计

IntBinaryOperator : 消费两个参数 以 a, b 为例子 a 代表 上一轮统计的结果,如果是第一次进来,那么 a 会取 流中的第一个值作为初始值
b 代表 本轮要统计的数据、如果是第一次进来,则默认是 流中的 第二个数据, IntBinaryOperator 生产一个数据,生产的数据作为本轮统计的结果

  • forEach() : 遍历流中的元素

  • allMatch(Predicate predicate) : 断言流中的数据全部满足指定的条件, 返回boolean

  • anyMatch(Predicate predicate) : 断言流中有元素满足指定的条件, 返回boolean

  • noneMatch(Predicate predicate) : 断言流中的所有元素全部不满足指定的条件, 返回boolean

  • findAny() : 获取 流中的一个元素, 主要应用于多线程环境

  • findFirst() : 获取 流中的第一个元素

  • int reduce(int identity, IntBinaryOperator op) : 用来进行统计

identity : 进行统计的结果的初始值
IntBinaryOperator : 消费两个参数 以 a, b 为例子 a 代表 上一轮统计的结果,如果是第一次进来,那么 a 会取 identity 作为初始值
b 代表 本轮要统计的数据、如果是第一次进来,则默认是 流中的 第一个数据, IntBinaryOperator 生产一个数据,生产的数据作为本轮统计的结果
会自动赋值给下一轮中的 a 作为值 下一轮 a 的初始值

  • int reduce(IntBinaryOperator op) : 用来进行统计

IntBinaryOperator : 消费两个参数 以 a, b 为例子 a 代表 上一轮统计的结果,如果是第一次进来,那么 a 会取 流中的第一个值作为初始值
b 代表 本轮要统计的数据、如果是第一次进来,则默认是 流中的 第二个数据, IntBinaryOperator 生产一个数据,生产的数据作为本轮统计的结果
会自动赋值给下一轮中的 a 作为值 下一轮 a 的初始值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java面向对象程序设计是一种使用Java语言进行编程的方法。它基于面向对象的编程范式,强调将问题划分为多个独立的对象,并通过对象之间的交互解决问题。 Java是一种通用的、跨平台的高级编程语言,广泛用于各个领域的软件开发面向对象程序设计是Java的核心特性之一,也是其成功的关键因素之一。通过使用面向对象程序设计,开发人员可以将复杂的问题分解为多个简单的对象,每个对象负责特定的功能,从而提高代码的复用性和可维护性。 Java面向对象程序设计的主要特点包括封装、继承和多态。封装可以将对象的实现细节隐藏起来,只暴露必要的接口给其他对象使用,增加了代码的安全性和可读性。继承允许一个类继承另一个类的属性和方法,从而减少了代码的重复编写,提高了代码的可重用性。多态允许一个对象以不同的形态呈现,提供了更灵活的代码设计和扩展能力。 Java面向对象程序设计的核心概念包括类、对象、方法和属性。类是创建对象的模板,它包含了对象的特征和行为。对象是类的实例,具有类定义的属性和方法。方法是类和对象的行为,用于实现特定的功能。属性是类和对象的特征,描述了它们的状态。 对于初学者来说,掌握Java面向对象程序设计是非常重要的。它不仅能帮助他们理解程序的结构和组织,还能提高他们的问题分析和解决能力。Java面向对象程序设计的基本概念和技巧也适用于其他面向对象的编程语言,为进一步学习和掌握其他编程语言奠定了良好的基础。 总而言之,Java面向对象程序设计是一种强大且灵活的编程方法,它能够帮助开发人员构建可维护和可扩展的软件系统。通过深入学习和应用Java面向对象程序设计的原理和技术,开发人员能够更好地理解和利用Java语言的特性,提高自己的编程水平。 ### 回答2: 《Java面向对象程序设计PDF》是一本关于Java编程语言面向对象程序设计的电子书。它涵盖了Java编程语言的基础知识和面向对象编程的核心概念。该书主要分为以下几个部分: 首先,它介绍了Java语言的基本语法,包括变量、数据类型、运算符等。这些基础知识对于理解后续的面向对象编程非常重要。 其次,它详细介绍了面向对象编程的核心概念,如类、对象、继承、多态等。通过实例和案例分析,读者可以深入理解这些概念的原理和应用。 此外,该书还介绍了Java的常用类库和API,如集合框架、输入输出流等。这些类库和API为Java开发者提供了丰富的功能和工具,能够提高开发效率和代码质量。 最后,该书还涵盖了一些高级主题,如异常处理、多线程编程、网络编程等。这些主题对于开发具有复杂功能和高性能要求的应用程序非常重要。 总体而言,该书全面而系统地介绍了Java面向对象程序设计的基础知识和高级应用。它适合初学者入门以及有一定Java编程经验的开发者进一步提高自己的编程能力。读者可以通过学习该书,掌握Java面向对象编程的核心概念和技术,从而能够设计和开发出功能强大、灵活性好的Java应用程序。 ### 回答3: Java面向对象程序设计(Object-oriented Programming,简称OOP)是一种应用广泛的程序设计模式,使用Java编程语言进行实现。Java语言将数据和操作封装在对象中,通过定义类和对象之间的关系来实现程序的设计和开发。 在Java面向对象程序设计中,开发者将问题抽象为对象模型,将问题的属性和行为封装在类中。通过创建对象,可以实例化类,并使用类提供的方法进行操作和交互。这种设计思想使得程序具有更高的可重用性和可维护性。 Java面向对象程序设计的优点之一是封装性。通过将数据和方法封装在对象中,可以隐藏内部实现的细节。这样的设计可以有效地保护数据的完整性和安全性,同时提供更加清晰的接口,方便其他对象与之交互。 另一个优点是继承性。Java面向对象程序设计通过继承机制,实现类与类之间的关联和扩展。继承可以使得代码的重用更加方便,提高了程序的可扩展性。同时,借助多态性的特性,可以进行更灵活的编程和适应不同的需求。 此外,Java面向对象程序设计还具有多线程、异常处理和异常处理等特性,使得程序开发更加灵活和稳定。 总的来说,Java面向对象程序设计是一种强大的编程模式,通过封装、继承、多态等基本特性,使得程序更加模块化、可维护性强、可扩展性高。同时,Java面向对象程序设计还提供了很多其他特性,如多线程和异常处理等,使得程序开发变得更加方便和稳定。对于想要学习Java编程或进行软件开发的人来说,掌握Java面向对象程序设计是非常重要的一部分。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值