Java基础(一)

文章目录

注释

  • 单行注释
  • 多行注释
  • 文档注释
public class Demo {
    public static void main(String[] args) {
        // 单行注释

        /*
        * 多行注释
        * */

        /**
         * 文档注释
         */
        System.out.println("开始注释");
    }
}

字面量

告诉程序员:数据在程序中的书写形式

整数型字面量:1 、2、 3 、100、 -100、 -20 …
浮点型字面量:1.3 、1.2、 3.14…
布尔型字面量:true、false没有其它值了,表示真和假,true表示真,false表示假
字符型字面量:‘a’、‘b’、‘中’
字符串型字面量:“abc”、“a”、“b”、“中国”

所有的字符型只能使用单引号括起来。
所有的字符串型只能使用双引号括起来

关键字

Java语言中已经赋予了特定含义的
在这里插入图片描述

标识符

用来标识类名、对象名、变量名、方法名、类型名、数组名、文件名的有效字符序列。

命名规则

由字母、数字、下划线“_”、美元符号“$”或者“¥”组成
首字符不能是数字
不能把java关键字和保留字作为标识符。
标识符对大小写敏感

在这里插入图片描述

// 也是正确的
        int 数字 = 100;
        System.out.println(数字);

建议规范

在这里插入图片描述

变量

含义

变量其实就是内存当中存储数据的最基本的单元。
存数据用的,而且这个数据是可变的,所以叫做变量

作用

如果只有字面量,没有变量机制的话,下面代码虽然都是10,但是这3个10占用三块不同的内存空间,所以需要变量来使内存可以重复利用。

数据在计算机的存储

数值:
二进制、最小单元是字节(8bit)

文本:
字符-》ASCII码-》数值

图片:
像素点-》三个颜色-》数值

声音:
波形图-》数值

数据类型

在这里插入图片描述

基本数据类型

在这里插入图片描述

引用数据类型

变量存放地址
数组

接口

详细见下面的一级标题

类型转换

自动类型转换

  • 类型范围小的变量可以直接赋值类型范围大的变量
        byte a = 11;
        int b = a;

在这里插入图片描述
在这里插入图片描述

  • 表达式中,小范围类型变量转换为较大范围类型变量,然后再参与计算
  • 表达式结果的类型由最高类型决定
  • byte short char直接转换为int参与运算,直接转化为int 就算是byte+byte也是(害怕越界)

强制类型转换

大范围类型变量不可以直接赋值给小范围类型变量

在这里插入图片描述

  • 强转可能会导致数据的丢失(溢出)
  • 浮点数转换为整数的时候,直接丢掉小数部分,保留整数部分

运算符

运算符:一种特殊符号,用以表示数据的运算、赋值和比较数与整数

运算符分类:算术运算符、赋值运算符、比较运算符、逻辑运算符、三元运算符

算术运算符

在这里插入图片描述
在这里插入图片描述

+与字符串运算的时候充当连接符,结果依旧是一个字符串

“abc”+11 = “abc11” 能算则算,不能算则连接

++ 只能操作变量,不能用于字面量

赋值运算符

=是从右向左看的

下面的都是存在强制类型转换的
在这里插入图片描述

比较运算符

在这里插入图片描述

逻辑运算符

在这里插入图片描述
在这里插入图片描述
Java中,& | 无论左边是false还是true 右边都是要执行的

三元运算符

条件表达式?值1:值2
条件表达式为true则返回值1,为false则返回值2

运算符优先级

java输入

import java.util.Scanner;

public class Demo {
    public static void main(String[] args) {
        //1、导包:idea自动导包
        //2、得到一个键盘扫描类对象
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户年龄");
        //3、调用sc的功能,来接受int类型
        int age = sc.nextInt();//等待用户输入一个int 直到用户按下了回车键才会拿到数据
        System.out.println("请输入用户名字");
        String name = sc.next();
        System.out.println("用户:"+name + age);
    }
}

流程控制

顺序 选择 循环

选择结构

在这里插入图片描述
在这里插入图片描述

  • Java的switch中的表达式只能是 byte short int char,JDK5开始支持枚举,JDK7开始支持string,不支持double、float。、long
  • case后面的值不可以重复,只能是字面量

循环结构

for

在这里插入图片描述

while

在这里插入图片描述

do while

在这里插入图片描述

死循环

在这里插入图片描述

break和continue

  • break:跳出本次循环
  • continue:结束本次循环的当前执行

break只能用于循环和switch
continue只能用于循环

数组

数组是数据的集合,一个容器,用来存储任何类型的数据,包括原始数据类型和引用数据类型,但是一旦指定了数组的类型之后,就只能用来存储指定类型的数据。
在这里插入图片描述

定义数组

静态初始化数组

定义数组的时候直接给数组赋值

在这里插入图片描述
注意:

  • 数据类型[] 数组名 === 数据类型 数组名[]
  • 什么类型的数组只能存放什么类型的数据(自动类型转换)

动态初始化数组

定义数组的时候先不存入具体的元素值,仅确定数组存储的数据类型和数组长度

数组声明其长度后不可改变
在这里插入图片描述

注意:静态和动态初始化数组是独立的,不可以混用
在这里插入图片描述
动态初始化数组元素默认值规则
在这里插入图片描述

访问

在这里插入图片描述

二维数组

数组变量的声明:
语法: 数据类型[][] 数组名;,如:int[][] num;double[][] d;String[][] str;

数组对象的创建:
语法:数组名 = new 数据类型[外长度][内长度];,如:num = new int[4][3];,数组声明其长度后不可改变

赋值:
语法:数组名[外下标][内下标] = 数据;,如:num[0][0]= 3;

数组元素的使用及遍历:
语法:数组名[外下标][内下标],获取指定下标是数据。

方法

概述

方法是一种语法结构,它可以把一段代码封装成一个功能,以便重复调用

在这里插入图片描述

好处:

  • 提高代码的复用性,提高开发效率
  • 让程序的逻辑更清晰

注意点

  • 方法在类中位置无所谓,但是不能在方法里面定义方法
  • 返回类型为void 不需要return ,返回值类型为具体类型,return必须是该类型
  • return下面不能编写代码
  • 方法不调用就不会执行,方法传参严格按照形成类型

参数传递机制

Java的参数传递机制都是:值传递

传输的是实参变量中存储的值的副本

基本类型的参数传递
引用类型的参数传递

方法重载

一个类中,可以出现多个重名的方法,但是他们的形参列表不同,那么这些方法就称为方法重载

只要是名称相同、形参列表不同(形参的个数、类型、顺序),那么就是方法重载。其他的都不管(修饰符、返回值类型无所谓)

面向对象

五大成员:变量、方法、构造器、内部类、代码块

封装 继承 多态

类:对象的设计图(对象的模板)
对象:本质是一种特殊的数据结构

在这里插入图片描述
一个代码文件中,可以写多个class类,但是只能有一个public而且必须修饰代码文件名

构造器

创建对象的时候自动调用构造器
在这里插入图片描述

  • 如果不写构造器,编译器自动生成一个无参构造器
  • 如果定义了有参数构造器,那么编译器不会自动生成无参构造器
  • (和C++class相同)

this

this就是变量,用于方法中拿到当前对象(哪个对象调用方法,this就指向该对象)

应用场景:解决变量名称冲突的问题

封装

封装(encapsulation)就是把抽象出的数据[属性]和对数据的操作[方法]封装在一起,数据被保护在内部,程序的其它部分只有通过被授权的操作[方法],才能对数据进行操作。
合理隐藏 合理暴露

好处:

(1)只能通过规定的方法访问数据
(2)隐藏类的实例细节,方便修改和实现。

实体类

一种特殊形式的类:

  • 成员都是私有的,提供getter和setter
  • 必须有一个公共无参构造函数

只负责数据存取,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。

实体类

package javabean;

public class Student {
    private String name;
    private int age;


    public Student(String name,int age) {
        this.name=name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

static关键字

静态,可以修饰成员变量和成员方法

类变量和实例变量

**应用场景:**如果某个数据只需要一份,且希望能够被共享(访问、修改),则该数据可以定义成类变量来记住

比如说,我们想要知道一个类有多少对象那么就用到static
在这里插入图片描述
成员变量的执行原理
在这里插入图片描述

类方法和实例方法

成员方法的执行原理
在这里插入图片描述

类方法最常见的就是做工具类(类内的方法都是类方法)

  • 因为创建对象会占用内存,导致浪费内存
  • 提高了代码复用 使用方便 提高了开发效率
  • 工具类没有必要创建对象,那么可以将构造器设为私有

注意事项

  • 类方法中不可以直接访问实例成员,只可以访问类成员
  • 实例方法既可以直接访问实例成员,又可以直接访问类成员
  • 实例方法中可以出现this,类方法中不可以出现this

应用知识:代码块

代码块在实际开发的时候用处不大,主要是看源码的时候用得到

分为静态代码块和实例代码块

静态代码块

  • 格式:static{}
  • 特点:类加载(加载到方法区,只要写class就会加载)时自动执行,类只会加载一次所以静态代码块也只会执行一次
  • 作用:完成类的初始化,例如对静态成员进行初始化赋值
public class Student {
    static int age;
    static {
        System.out.println("静态代码块");
        age=50;
    }
}



public class Test {
    public static void main(String[] args) {
        System.out.println(Student.age);
        System.out.println(Student.age);
    }
}

在这里插入图片描述
实例代码块

  • 格式:{}
  • 特点:每次创建对象的时候,执行实例代码块,在构造器前执行
  • 作用:和构造器一样,都是用来完成对象的初始化的,例如:对实例变量进行初始化赋值

public class Test {
    public static void main(String[] args) {
        System.out.println(Student.age);
        System.out.println(Student.age);

        System.out.println("-----------------------");
        Student s1 = new Student();
        Student s2 = new Student("hello");
    }
}


public class Student {
    String name;
    static int age;

    //静态代码块
    static {
        System.out.println("静态代码块");
        age = 50;
    }

    //实例代码块
    {
        System.out.println("实例代码块");
    }

    public Student() {
        System.out.println("无参数构造器");
    }

    public Student(String name) {
        this.name = name;
        System.out.println("有参数构造器");
    }

}

在这里插入图片描述

应用知识:单例设计模式

什么是设计模式?
一个问题通常有n种解法,其中肯定有一种解法是最优的,这个最优的解法被人总结出来了,称之为设计模式。
设计模式有20多种,对应20多种软件开发中会遇到的问题。

单例设计模式:一个类只能有一个对象

饿汉式单例写法:在获取对象的时候,对象已经提前创建好了

  • 构造器私有
  • 定义一个类变量记住类的一个对象
  • 定义一个类方法返回对象
//由于a是类成员 所以只有在类加载的时候创建一下 
//所有后续无论调用多少次getObject类方法都是返回的同样的a地址
public class A {
    private static A a = new A();
    private A(){}

    public static A getInstance(){
        return a;
    }
}

懒汉式单例写法:在获取对象的时候,对象才会被创建

  • 构造器私有
  • 定义一个类变量记住类的一个对象
  • 定义一个类方法返回对象
public class B {
    private static B b;
    private B(){}

    public static B getInstance(){
        if (b==null)b=new B();
        return b;
    }
}

单例设计模式的应用场景和好处:
runtime类、电脑任务管理器

继承

基本

关键字**extends**

子类继承父类所有的非私有的成员

子类的对象是由父类和子类共同完成的

public class B extends A{}
//B 派生类  A 基类 

权限修饰符

private 缺省 protected public

  • public:任意类都可以访问
  • private:只能在本类访问
    在这里插入图片描述

单继承

  • java与C++不同,Java仅支持单继承,即一个类只能继承一个直接父类;但是支持多层继承
  • Object是所有类的祖先
class A{}//等价于 class A extends Object{}

方法重写

当子类觉得父类中的某个方法不好用,或者无法满足自己的需求时,子类可以重写一个方法名称、参数列表一样的方法,去覆盖父类的这个方法,这就是方法重写

重写的注意事项:

  • 重写后,方法的访问,Java会遵循就近原则
  • 子类重写父类方法的时候,访问权限必须大于等于父类方法的权限(public>protected>缺省)
  • 私有、静态方法不能重写
  • 使用@Override,可以检查我们方法重写的格式是否正确,代码可读性也更好
  • 重写的方法返回值类型必须与被重写的方法的返回值类型一样,或者范围更小

但是我们使用的时候一般就是 声明不变,重新实现

应用场景:重写Object的toString()方法

public class A {
    private String name;
    private int age;
    public A(){}
    public A(String name,int age){
        this.name=name;
        this.age=age;
    }
    @Override
    public String toString(){
        return "name="+name+",age="+age;
    }
}

不重写
在这里插入图片描述
重写
在这里插入图片描述

子类访问其他成员

public class Test {
    public static void main(String[] args) {
        Son s = new Son();
        s.print();
    }
}

class Fater{
    String name="父类名字";
}
class Son extends Fater{
    String name = "子类名字";

    void print(){
        String name = "局部名称";
        System.out.println(name);//局部
        System.out.println(this.name);//本类
        System.out.println(super.name);//父类
    }
}

就近原则

子类构造器

特点

子类的全部构造器,都会调用父类的构造器然后再调用自己

默认情况下,子类全部构造器第一行都是为super(),这个就是调用父类的无参构造器

如果父类没有无参数构造器,则我们必须在子类构造器的第一行手写super(...),指定去调用父类的有参数构造器

一个类的任意构造器中,我们可以通过this(...)去调用该类的其他构造器

一个构造器中不能同时有this()super()

应用场景

public class Test {
    public static void main(String[] args) {
        Teacher t = new Teacher("李梅",36,"Java C++");
    }
}

class Person{
    private String name;
    private int age;

    Person(){}
    Person(String name,int age){
        this.name=name;
        this.age=age;
    }
}
class Teacher extends Person{
    private String skill;

    Teacher(){}
    Teacher(String name,int age,String skill){
        super(name,age);
        this.skill=skill;
    }
    Teacher(String name,int age){
        this(name,age,"打豆豆");
    }
}

多态

概念

多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态

People p = new Student();

People p = new Teacher();

//人即可能是学生有可能是老师

前提:

  • 有继承/实现关系
  • 存在父类引用子类对象
  • 存在方法重写

注意:多态是对象、行为的多态,Java中的成员变量不谈多态

public class Test {
    public static void main(String[] args) {
        Person p1 = new Teacher();
        p1.print();//I am teacher  方法:编译看左边 运行看右边
        System.out.println(p1.name);//person 变量:编译看左边 运行看左边
    }
}

class Person{
    public String name = "person";
    void print(){
        System.out.println("I am person");
    }
}
class Teacher extends Person{
    public String name = "teacher";
    @Override
    void print(){
        System.out.println("I am teacher");
    }
}

好处

  • 右边对象是解耦合的,便于扩展和维护
  • 使用父类类型的形参可以接受一切子类对象,扩展性更强、更便利

缺点

多态下不能直接使用子类独有的功能

解决方式强制类型转换

  • 自动类型转换:父类 变量名=new 子类
  • 强制类型转换:子类 变量名=(子类)父类变量

强制类型转换注意点:

  • 存在继承/实现时,就可以进行强制类型转换,编译阶段不会报错。
  • 但是,运行时,如果发现对象的真实类型与强转后的类型不同会报错(ClassCastException)

**建议:**使用 instanceof 判断当前对象的真实类型

public class Test {
    public static void main(String[] args) {
        Person p1 = new Teacher();
        p1.print();

//        Teacher t1 = (Teacher) p1;//编译不报错
//        t1.teacher();
//
//        Student s1 = (Student) p1;//编译不报错 运行报错 真实类型不匹配 ClassCastException

        //建议使用
        if (p1 instanceof Teacher){
            Teacher t1 = (Teacher) p1;//编译不报错
            t1.teacher();
        }else{
            Student s1 = (Student) p1;
            s1.test();
        }
    }
}

class Person {
    public String name = "person";

    void print() {
        System.out.println("I am person");
    }
}

class Teacher extends Person {
    public String name = "teacher";

    @Override
    void print() {
        System.out.println("I am teacher");
    }

    void teacher() {
        System.out.println("teaching~~");
    }
}

class Student extends Person {
    public String name = "Student";

    @Override
    void print() {
        System.out.println("I am Student");
    }

    void test() {
        System.out.println("test~~");
    }
}

final关键字

final是最终的意思,可以修饰 类 方法 变量

  • 修饰类:类不能被继承
  • 修饰方法:方法不能被重写
  • 修饰变量:变量只能被赋值一次(类似于const)
    • 局部变量
    • 成员变量
      • 静态成员变量
      • 实例成员变量

final修饰变量

  • final修饰基本类型的变量,变量存储的数据不能被改变
  • final修饰引用类型的变量,变量存储的地址不能被改变,但地址所指向对象的内容是可以被改变的

常量(单词大写,下划线隔开)

  • static final修饰的成员变量
  • 程序编译的时候,常量会被宏替换:出现常量的地方全部会被替换为被记住的字面量,使用常量和字面量性能是一样的

抽象类

概述

abstract关键字,修饰类是抽象类,修饰方法是抽象方法

注意点

  • 抽象类中不一定有抽象方法,有抽象方法的一定是抽象类
  • 抽象方法没有函数体,只有函数声明
  • 类该有的成员(成员变量、方法、构造器)抽象类都可以有
  • 抽象类不可以实例化对象,仅作为一个父类让子类继承
  • 一个类继承抽象类,必须重写所有的抽象方法,否则这个类也要定义为抽象类

好处

父类知道每个子类都要做某个行为,但每个子类要做的情况不一样,父类就定义成抽象方法,交给子类去重写实现,我们设计这样的抽象类,就是为了更好的支持多态,

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog("kitt");
        animal.cty();

        animal=new Cat("xixi");
        animal.cty();
    }
}

abstract class  Animal{
    private String name;
    Animal(){}
    Animal(final String name){
        this.name=name;
    }
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    abstract public void cty();
}

class Dog extends Animal{
    Dog(){}
    Dog(final String name){
        super(name);
    }
    @Override
    public void cty() {
        System.out.println(getName()+"=wang-wang-wang~~");
    }
}
class Cat extends Animal{
    Cat(){}
    Cat(final String name){
        super(name);
    }
    @Override
    public void cty() {
        System.out.println(getName()+"=miao-miao-miao~~");
    }
}

场景:模板方法设计模式

解决的问题:方法中存在重复代码的问题

写法:

  • 定义一个抽象类
  • 在里面定义两个方法,一个是模板方法:放相同的代码里,一个是抽象方法:具体实现交给子类完成

模板方法建议final修饰

package oop_abstract;

public class Test {
    public static void main(String[] args) {
        /**
         * 猫和狗都有一个叫
         * 第一句和最后一句都是一样的 中间的叫不一样
         */
        Dog d = new Dog();
        d.cry();

        Cat c = new Cat();
        c.cry();
    }
}

abstract class  Animal{
    //模板方法禁止重写(专业一些)
    public final void cry(){
        System.out.println("开始了");
        System.out.println(selfC());
        System.out.println("结束了");
    }

    abstract String selfC();
}

class Dog extends Animal{

    @Override
    String selfC() {
        return "wang";
    }
}
class Cat extends Animal{

    @Override
    String selfC() {
        return "miao";
    }
}

接口

简述

关键字interface

public interface 接口名{
    //只能有变量和方法,不能有其他成员
    //变量 -> 常量
    //方法 -> 抽象方法
}

接口不能创建对象,是用来**被类实现(implements)**的,实现接口的类称为实现类

修饰符 class 实现类 implements 接口1,接口2...{}

一个类可以实现多个接口,实现类必须重写所有接口的所有抽象方法

public class Test {
    public static void main(String[] args) {
        T t = new T();
        t.printA();
    }
}

class T implements A,B{
    @Override
    public void printA() {
        System.out.println("helloA");
    }

    @Override
    public void printB() {
        System.out.println("helloB");
    }
}
interface A{
    //默认常量
    String SCHOOL_NAME="XUPT";

    //默认抽象方法
    void printA();
}
interface B{
    //默认常量
    String SCHOOL_NAME="XUPT";

    //默认抽象方法
    void printB();
}

好处

  • 弥补了类单继承的不足,一个类同时可以实现多个接口
  • 让程序可以面向接口编程,这样程序员就可以灵活方便的切换各种业务实现
    在这里插入图片描述
import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ClassManager cm = new ClassManager();
        cm.printInfo();
        cm.printScore();
    }
}

class ClassManager {
    private ArrayList<Student> students = new ArrayList<>();
    private StudentOperator studentOperator = new StudentOperatorImpl2();//只需要更改这里就可以修改功能

    public ClassManager() {
        students.add(new Student("古力娜扎", '女', 82.5));
        students.add(new Student("迪丽热巴", '女', 72.5));
        students.add(new Student("八嘎亚历", '男', 85.65));
        students.add(new Student("玛卡巴卡", '男', 92.5));
        students.add(new Student("无锡碧玺", '男', 62.5));
        students.add(new Student("吴京", '男', 78.5));
    }

    public void printInfo() {
        studentOperator.printAllInfo(students);
    }

    public void printScore() {
        studentOperator.printScore(students);
    }
}

//全部信息 + 平均分
class StudentOperatorImpl1 implements StudentOperator {

    @Override
    public void printAllInfo(ArrayList<Student> students) {
        System.out.println("====================");
        for (Student student : students) {
            System.out.println(student.getName() + "-" + student.getScore());
        }
        System.out.println("====================");
    }

    @Override
    public void printScore(ArrayList<Student> students) {
        double score = 0;
        for (Student student : students) {
            score += student.getScore();
        }
        System.out.println(score/students.size());
    }
}

//全部信息男女人数 + 平均分去掉最大最小
class StudentOperatorImpl2 implements StudentOperator {

    @Override
    public void printAllInfo(ArrayList<Student> students) {
        System.out.println("====================");
        int count1 = 0, count2 = 0;
        for (Student student : students) {
            System.out.println(student.getName() + "-" + student.getScore());
            if (student.getSex()=='男')
                count1++;
            else
                count2++;
        }
        System.out.println("男生人数:"+count1);
        System.out.println("女生人数:"+count2);
        System.out.println("总人数:"+students.size());
        System.out.println("====================");
    }

    @Override
    public void printScore(ArrayList<Student> students) {
        double score = 0;
        double max = students.get(0).getScore(), min = students.get(0).getScore();
        for (Student student : students) {
            max = Math.max(max,student.getScore());
            min = Math.min(min,student.getScore());
            score += student.getScore();
        }
        System.out.println((score-max-min)/(students.size()-2));
    }
}

interface StudentOperator {
    void printAllInfo(ArrayList<Student> students);

    void printScore(ArrayList<Student> students);
}

class Student {
    private String name;
    private char sex;
    private double score;


    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public Student() {
    }

    public Student(String name, char sex, double score) {
        this.name = name;
        this.score = score;
        this.sex = sex;
    }
}

JDK8之后接口新特性

public interface A{
    default void test1(){
        /*
        默认public 使用default修饰
        只能使用接口的类实现对象调用
        */
    }
    
    static void test2(){
        /*
        静态方法 默认public
        只能使用接口名调用
        */
    }
    
    private void test3(){
        /*
        JDK9之后支持
        接口内部调用
        */
    }
    
}
  • 增强接口本身能力,便于项目的扩展和维护

接口多继承

一个接口可以同时继承多个接口

便于实现类的实现

interface A{}
interface B{}
interface C extends A,B{}

注意事项

  • 接口多继承:存在方法名冲突,不支持多继承

  • 类多实现接口:存在方法名冲突,不支持多实现

  • 一个类继承父类,又同时实现了接口,父类和接口中存在方法名冲突,优先调用父类的方法

class F{
    public void run(){
        System.out.printIn("fu");
    }
}

interface A{
     public void run(){
        System.out.printIn("A");
    }
}

class Z extends F implements A{}

Z z = new Z();
z.run();//fu
  • 一个类实现了多个接口,多个接口中存在同名的默认方法,可以不冲突,这个类重写该方法即可。
interface A{
     public void run(){
        System.out.printIn("A");
    }
}
interface B{
     public void run(){
        System.out.printIn("B);
    }
}
                           
class C implements A,B{
    @Override
    public void run(){}//不报错
}

内部类

当一个类的内部,包含了一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。

成员内部类

就是类中的一个普通成员,类似前面我们学过的普通的成员变量、成员方法

public class Innter {
    public static void main(String[] args) {
        Outer.Inner in = new Outer().new Inner();//创建对象
        in .test();
    }
}


class Outer{
    private int a=1;
    class Inner{
        public static String name; //JDK 16之后才支持定义静态成员
        private int a=2;
        Inner(){}
        public void test(){
            int a = 3;
            System.out.println(a);
            System.out.println(this.a);
            System.out.println(Outer.this.a);//可以访问外部类的成员
        }
    }
}

静态内部类

static修饰的内部类,所属外部类自己持有

public class Innter {
    public static void main(String[] args) {
        Outer.Inner in = new Outer.Inner();
        in.test();
    }
}


class Outer{
    private int a = 1;
    //可以访问外部类的静态成员 不能直接访问实例成员
    static class Inner{
        public int age;
        public static String name; //JDK 16之后才支持定义静态成员
        private int a=2;
        Inner(){}
        public void test(){
            int a = 3;
            System.out.println(a);
            System.out.println(this.a);
        }
    }
}

局部内部类

定义在方法中、代码块中、构造器等

鸡肋语法

匿名内部类

重点

特殊的局部内部类;不需要声明类的名字

本质就是一个子类,会立刻创建一个对象

方便创建一个子类对象

public class Innter {
    public static void main(String[] args) {
        /**
        一个子类 立即创建一个对象
        */
        Animal dog = new Animal() {
            @Override
            public void cry() {
                System.out.println("汪汪汪");
            }
        };
        dog.cry();
    }
}
abstract class Animal{
    public abstract void cry();
}
应用场景

作为一个参数传输给方法

public class Innter {
    public static void main(String[] args) {
        go(new Animal() {
            @Override
            public void run() {
                System.out.println("🐕在run");
            }
        });
    }
    private static void go(Animal a){
        a.run();
    }
}
interface Animal{
    void run();
}

GUI的应用

import javax.swing.*;
import java.awt.event.ActionEvent;

public class Main {
    public static void main(String[] args) {
        JFrame win = new JFrame("登录页面");
        JPanel panel = new JPanel();
        win.add(panel);

        JButton but = new JButton("登录");
        win.add(but);
		
        // 简化代码 AbstractAction接口的一个实现类 重写actionPerformed
        but.addActionListener(new AbstractAction() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(win,"登录一下");
            }
        });

        win.setSize(400,400);
        win.setLocationRelativeTo(null);
        win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        win.setVisible(true);
    }
}

枚举

认识枚举

枚举是一个特殊的类

在这里插入图片描述

格式

修饰符 enum 枚举类型{
    名称1,名称2,...;
    其他成员;
}
package Enum;

public class Test {
    public static void main(String[] args) {
        A a = A.X;
        System.out.println(a);
    }
}
enum A{
    //枚举类第一行必须罗列枚举对象的名字,这些名称都是常量,每个常量都是枚举类的一个对象
    X,Y,Z;
    //枚举类的构造器是私有的 写不写都是私有的
    //枚举类是最后的 不能被继承
    //提供一些额外的API values valueOf name ordinal
}

抽象枚举

抽象类不可以实例化对象,但是枚举在内部的第一行是实例化对象的 所以要重写抽象方法

public enum B{
    X(){
        @Override
        public void run() {
            System.out.println("running");
        }
    },Y("张三"){
        @Override
        public void run() {
            System.out.println(getName()+"running");
        }
    };
    private String name;
    B() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    B(String name) {
        this.name = name;
    }

    public abstract void run();
}

可以实现单例设计模式

public enum A{
    X;
}

应用场景

用来表示一组信息,然后作为参数进行传输

选择定义一个一个的常量来表示一组信息,并作为参数传输:参数值不受约束。
选择定义枚举表示一组信息,并作为参数传输:代码可读性好,参数值得到了约束,对使用者更友好,建议使用!

泛型

认识泛型

定义类、方法、接口时,同时声明了一个或者多个类型变量<E>,称为泛型类、泛型方法、泛型接口,统称泛型

作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。

泛型的本质:把具体的数据类型作为参数传给类型变量。

泛型类

模板

修饰符 class 类名<类型变量1,...>{}
package String;

public class array<E> {
    private Object[] arr= new Object[10];//Object是所有类的父类
    private int length;

    public boolean add(E e) {
        arr[length++] = e;
        return true;
    }

    public E get(int index) {
        return (E) arr[index];//强制类型转换
    }

    public int size() {
        return length;
    }
}

class Dog<T extends Animal>{}T 只能是Animal或者其子类

泛型接口

模板

修饰符 interface 接口名<类型变量1,...>{}
public interface Data<T extends Animal>{//T 只能是Animal或者其子类
    void add(T t);
    ArrayList<T>get(String name);
}

泛型方法

模板

修饰符 <类型变量1,...> 返回值类型 方法名(形参列表){}
import java.util.ArrayList;

public class Car {
    public static void main(String[] args) {

    }

//    public static <T> int count(ArrayList<T> t){
//        return 5;
//    }

    //?是个泛型通配符 接受所有的类型
    //对其限制 ? extends car(car以及其子类  上限是car)
    //        ? super car(car以及其父类 下限是car)
    public static int count(ArrayList<?> t) {
        return 1;
    }
}

泛型通配符?

注意事项

  • **泛型擦除:**泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中不存在泛型

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  • 泛型不支持基本基本数据类型,仅支持引用数据类型

常用API

API应用程序编程接口 别人写好的轮子
在这里插入图片描述

包:用来分类的管理各种不同程序,类似文件夹,建包有利于程序的管理和维护

注意事项

  • 同一个包下的类可以直接访问
  • 调用其他包下的程序,必须导包(import 导包)
  • 如果当前程序中,要调用]ava提供的程序,也需要先导包才可以使用;但是java.lang下的不需要导包,可以直接使用
  • 如果当前程序中,要调用多个不同包下的程序,而这些程序名正好一样,此时默认只能导入一个程序,另一个程序必须带包名访问。

String

java.lang.String

常用构造器

直接赋值
在这里插入图片描述

或者

在这里插入图片描述

常用方法

在这里插入图片描述

package String;

public class test {
    public static void main(String[] args) {
        String n = "hello yb0os1";
        //长度
        System.out.println(n.length());

        //根据索引获取字符
        System.out.println(n.charAt(6));

        //字符串转化为字符数组
        char[] s = n.toCharArray();
        for (int i = 0; i < s.length; i++) {
            System.out.print(s[i]+" ");
        }
        System.out.println();

        //判断字符串内容是否相同 大小写敏感
        String n1 = new String("hello yb0os1");
        String n2 = new String("hello yb0os1");
        System.out.println(n1==n2);
        System.out.println(n.equals(n2));

        //判断字符串内容是否相同 大小写不敏感
        String c1="34Af7";
        String c2="34af7";
        System.out.println(c1.equalsIgnoreCase(c2));

        //截取字符串内容 [beg,end)
        String mainS = "我是最好的编程语言";
        System.out.println(mainS.substring(0,5));//[0,5)
        System.out.println(mainS.substring(5));//[5,结尾)

        //替换字符串
        String info = "你真是一个大垃圾啊 垃圾东西";
        String re = info.replace("垃圾","**");
        System.out.println(re);

        //判断字符串中是否包含某个关键字 大小写敏感
        String ss = "java Jasda";
        System.out.println(ss.contains("java"));

        //判断字符是否以某个字符开头 大小写敏感
        String rs1 = "Java";
        System.out.println(rs1.startsWith("J"));
        System.out.println(rs1.startsWith("ja"));

        //分割字符串 放入字符串数组中
        String[] res = "张无忌 武警 吴京 赵敏 殷素素".split(" ");
        for (int i = 0; i < res.length; i++) {
            System.out.println(res[i]);
        }

    }
}

注意事项

  • string是不可变对象
    在这里插入图片描述

  • 双引号(就是隐式的调用new String(“字符串”))写出的字符串对象是放在字符串常量池里面,且相同的字符串只存储一份
    在这里插入图片描述

  • new出来的字符串对象,每new一次都会产生一个新对象存放着堆内存中
    在这里插入图片描述

String s1=String("a");//创建两个对象 一个在字符串常量池里面 一个在堆内存
String s2 = "a"; //创建0个对象

变量的运算是放在堆里面的
在这里插入图片描述

案例

验证码

import java.util.Random;

public class Code {
    public static String codes = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    public static void main(String[] args) {
        String code = getCodes(5);
        System.out.println(code);
    }
    public static String getCodes(int n){
        Random r = new Random();
        StringBuilder code= new StringBuilder();
        for (int i = 0; i < n; i++) {
            code.append(codes.charAt(r.nextInt(codes.length())));
        }
        return code.toString();
    }
}

简单登录

import java.util.Scanner;

public class Login {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        for (int i = 0; i < 3; ++i) {
            System.out.print("请输入账号:");
            String name = sc.next();
            System.out.print("请输入密码:");
            String password = sc.next();
            if (name.equals("yb0os1") && password.equals("123456")) {
                System.out.println("欢迎进入系统");
                break;
            } else {
                System.out.println("错误~~ 重新输入");
            }
        }
    }
}

ArrayList

一种最常用的集合

常用构造器

在这里插入图片描述

常用方法

在这里插入图片描述
注:倒数第二个方法只删除第一个位置出现的o

import java.util.ArrayList;

public class Demo {
    public static void main(String[] args) {
        ArrayList list1 = new ArrayList();//可以存储任意类型的数据
        list1.add(1);
        list1.add("he");
        System.out.println(list1);

        ArrayList<String>list2=new ArrayList<>();//只能存储String
        list2.add("yb0os1");
        list2.add("hello");
        list2.add(1,"wochadui");
        System.out.println(list2);
    }
}

案例

边遍历边删除存在一些小问题

import java.util.ArrayList;

public class DeleteAllTarget {

    public static void main(String[] args) {
        //集合中找数据并且删除
        //如果直接删除会导致bug 删除不干净
        ArrayList<String>list=new ArrayList<>();
        list.add("枸杞");
        list.add("C++");
        list.add("Java");
        list.add("yb0os1");
        list.add("Python");
        list.add("红枸杞");
        list.add("黑枸杞");
     /*   for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            if (s.contains("枸杞")){
                list.remove(s);
                --i;//解决bug方法一:每次删除就回退一个单位
            }
        }*/
        //解决bug方法二:从后向前遍历删除
        for (int i = list.size()-1; i >=0 ; i--) {
            String s = list.get(i);
            if (s.contains("枸杞"))list.remove(i);
        }
        System.out.println(list);
    }
}

Object类

Object是所有类的祖宗类 所有类都可以使用Object提供的方法

常见方法

在这里插入图片描述

import java.util.Objects;

public class _Object_ {
    public static void main(String[] args) throws CloneNotSupportedException {
        Student stu1 = new Student("李四",18);
        //toString存在的意义是被重写的直接输出对象==对象.toString()
        System.out.println(stu1);
        Student stu2 = new Student();
        //equals默认判断内存地址是否相同 存在的意义也是被重写 判断内容
        System.out.println(stu1.equals(stu2));
        //clone是protected的 所以不同包下的文件的对象不可以直接访问 要在类中重写 然后类还要实现Cloneable
        //clone默认是浅克隆 引用数据类型拷贝的是地址 而不是新的
        Student stu3 = (Student) stu1.clone();
    }
}

//Cloneable是一个标记接口 实现了才能clone
class Student implements Cloneable{
    private String name;
    private int age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        //浅克隆 调用父类的
        return super.clone();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)return true;
        //为空 或者 类型不同 直接false
        if (obj==null || this.getClass()!=obj.getClass())return false;
        return this.getAge() == ((Student) obj).getAge() && Objects.equals(this.getName(),((Student)obj).getName());
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

浅克隆 深克隆

Objects类

一个工具类 提供了很多操作对象的静态方法

常见方法

在这里插入图片描述

Object子类重写equals 比较字符串的时候 为什么使用Objects.equals而不是Stringequals

因为如果使用String的 当调用者是null的时候报错 而Objects的不会有这个问题

import java.util.Objects;

public class _Objects_ {
    public static void main(String[] args) {
        String name1 = null;
        String name2="yb0os1";

        System.out.println(Objects.equals(name1,name2));
//        System.out.println(name1.equals(name2));//报错 NullPointerException

        System.out.println(Objects.isNull(name1));//等价 name1 == null 内部就是这样实现的
        System.out.println(Objects.nonNull(name1));//等价 name1 != null 内部就是这样实现的
    }
}


//Objects的equals的源码如下,所以他更加安全
public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

包装类

把基本数据类型包装成对象
在这里插入图片描述

Integer为例子

import java.util.ArrayList;

public class _Integer_ {
    public static void main(String[] args) {
        Integer i = new Integer(5);//已经废除
        Integer j = Integer.valueOf(5);

        //自动装箱:可以自动把基本类型的数据转换成对象。
        Integer k = 5;

        //自动拆箱:可以自动把包装类型的对象转换成对应的基本数据类型
        int l = k;

        ArrayList<Integer> intArr = new ArrayList<>();
        intArr.add(15);//自动装箱	
        int rs = intArr.get(0);//自动拆箱

        System.out.println("------------------------");

        //基本类型数据转化为字符串
        Integer a = 50;
        String rs1 = Integer.toString(a);
        String rs2 = a.toString();//继承的Object

        System.out.println(rs1 + 1);
        System.out.println(rs2 + 1);

        //字符串类型转化为基本数据类型
        String ageStr = "19";
//        int age = Integer.parseInt(ageStr);
        int age = Integer.valueOf(ageStr); // 推荐这个 只需要记一个
        System.out.println(age + 1);

        String scoreStr = "99.5";
//        double score = Double.parseDouble(scoreStr);
        double score = Double.valueOf(scoreStr);
        System.out.println(score + 0.65);
    }
}

StringBuilder

可变字符串对象,用来操作字符串的

StringBuilderString更适合做字符串的修改操作,效率更高 代码更简洁

常用方法

在这里插入图片描述

public class _StringBuilder_ {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("yb0os1");

        //拼接:几乎支持所有的类型
        s.append(12);
        s.append(3.14);
        s.append(true);
        s.append("y");
        s.append(new Object());
        System.out.println(s);

        //append支持链式编程
        s=new StringBuffer();
        s.append(1).append(2).append(3).append("!点火~~");
        System.out.println(s);

        //翻转:直接在自身修改
        s.reverse();
        System.out.println(s);

        //长度
        System.out.println(s.length());

        //StringBuilder转换为String
        String rs = s.toString();
        System.out.println(rs);
    }
}

为什么操作字符串推荐使用StringBuilder而不是String

效率更高

  • 频繁的拼接、修改建议StringBuilder
  • 其余建议String

StringBuffer

StringBuilder用法一模一样

区别

StringBuilder是线程不安全的,StringBuffer是线程安全的

StringJoiner

在这里插入图片描述

import java.util.StringJoiner;

public class _StringJoiner_ {
    public static void main(String[] args) {
        //间隔,   开始[    结束]
        StringJoiner s = new StringJoiner(", ","[","]");
        //只能加入字符串
        s.add("yb0os1");
        s.add("hello");
        System.out.println(s);
    }
}

Math类

数学工具类:静态方法

常用方法

在这里插入图片描述

public class _Math_ {
    public static void main(String[] args) {
        //abs可传入int double 返回正数
        System.out.println(Math.abs(-55));
        System.out.println(Math.abs(-5.5));

        //ceil 向上取整  返回的double
        System.out.println(Math.ceil(4.01));
        System.out.println(Math.ceil(-2.5));

        //floor 向下取整  返回的double
        System.out.println(Math.floor(4.01));
        System.out.println(Math.floor(-2.5));

        //round 四舍五入  返回的long
        System.out.println(Math.round(4.01));
        System.out.println(Math.round(-2.5));

        //max min

        //pow 取次方 double
        System.out.println(Math.pow(2,3));//2^3

        //random 去随机数 默认[0.0,1.0)
        System.out.println(Math.round(Math.random()*10));
    }
}

System类

系统工具类:静态方法

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

public class _System_ {
    public static void main(String[] args) {
        /**
         * 终止当前运行的Java虚拟机
         * 非0代表异常终止
         * 0代表正常终止
         */
//        System.exit(0);//(不建议使用)
//        System.out.println(11);//执行不到了

        /***
         * 获取当前系统时间 返回的是long
         * 毫秒值:从1970-1-1 0:0:0开始到此刻的毫秒值
         * 可以用于性能分析
         */
        long time = System.currentTimeMillis();
//        System.out.println(time);
        for (int i = 0; i < 10000; i++) {
            System.out.println("dassssssssssssssssssssssssssssssssssssssssss");
        }
        long timenew = System.currentTimeMillis();
        System.out.println((timenew-time)+"ms");
    }
}

Runtime类

程序运行的运行环境

单例类
在这里插入图片描述

import java.io.IOException;

public class _Runtime_ {
    public static void main(String[] args) throws IOException, InterruptedException {
        //获取当前java应用程序关联的运行对象
        Runtime r = Runtime.getRuntime();

        //终止当前虚拟机
//        r.exit(0);

        //获取虚拟机能够使用的处理器数
        System.out.println(r.availableProcessors());

        //返回java虚拟机中内存总量 long 字节
        System.out.println(r.totalMemory()/1024.0/1024.0+"MB");

        //返回java虚拟机中可用内存量
        System.out.println(r.freeMemory()/1024.0/1024.0+"MB");

        //启动某个程序 并返回代表该程序的对象 Process 类型
        Process p = r.exec("D:\\XJad\\XJad\\XJad.exe");
        Thread.sleep(5000);
        p.destroy();

    }
}

BigDecimal

用的多

解决浮点数运算时出现结果失真的情况

不要使用BigDecimal(double val)

在这里插入图片描述

import java.math.BigDecimal;
import java.math.RoundingMode;

public class _BigDecimal_ {
    public static void main(String[] args) {
        double a = 0.1;
        double b = 0.3;
        System.out.println(a+b);

        System.out.println("--------------------");

//        BigDecimal c = new BigDecimal(Double.toString(a));
//        BigDecimal d = new BigDecimal(Double.toString(b));
        //等价
        BigDecimal c = BigDecimal.valueOf(a);
        BigDecimal d = BigDecimal.valueOf(b);
        System.out.println(c.add(d));
        System.out.println(c.subtract(d));
        System.out.println(c.multiply(d));
        //向上取 2为小数
        System.out.println(c.divide(d,2, RoundingMode.HALF_UP));

        double rs = c.doubleValue();
        System.out.println(rs);
    }
}

JDK8之前传统的日期、时间类

Date

在这里插入图片描述

import java.util.Date;

public class _Date_ {
    public static void main(String[] args) {
        Date date = new Date();
        //系统时间信息
        System.out.println(date);

        //时间毫秒值
        long time = date.getTime();
        System.out.println(time);

        //时间毫秒值转换为系统时间信息
        time+=10*1000;
        Date d = new Date(time);
        System.out.println(d);
    }
}

SimpleDateFormat

简单时间格式化

在这里插入图片描述

时间格式

在这里插入图片描述

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class _SimpleDateFormat_ {
    public static void main(String[] args) throws ParseException {
        Date d = new Date();
        long time = d.getTime() + 5 * 1000;

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss EEE a");
        System.out.println(sdf.format(d));
        System.out.println(sdf.format(time));

        System.out.println("----------------------------");

        //字符串时间称为日期对象
        String dataStr = "2024-5-19 13:14:00";
        //创建简单日期格式化对象 时间格式必须和字符串的相同
        SimpleDateFormat sdatef = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d2 = sdatef.parse(dataStr);
        System.out.println(d2);
    }
}

简单的使用

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class _MiaoSha {
    private final static String BEGIN = "2023年11月11日 0:0:0";
    private final static String END = "2023年11月11日 0:10:0";
    public static void main(String[] args) throws ParseException {
        String Jia = "2023年11月11日 0:01:18";
        String Pi = "2023年11月11日 0:10:51";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        Date dJia = sdf.parse(Jia);
        Date dPi = sdf.parse(Pi);
        Date begin=sdf.parse(BEGIN);
        Date end=sdf.parse(END);

        long timeBeg = begin.getTime();
        long timeEnd = end.getTime();
        long timePi = dPi.getTime();
        long timeJia = dJia.getTime();

        if (timePi>=timeBeg&&timePi<=timeEnd){
            System.out.println("小皮秒杀成功,还剩下"+(timeEnd-timePi)/1000.0+"s");
        }else{
            System.out.println("小皮秒杀失败,超出"+(timePi-timeEnd)/1000.0+"s");
        }

        if (timeJia>=timeBeg&&timeJia<=timeEnd){
            System.out.println("小贾秒杀成功,还剩下"+(timeEnd-timeJia)/1000.0+"s");
        }else{
            System.out.println("小贾秒杀失败,超出"+(timeJia-timeEnd)/1000.0+"s");
        }
    }
}

Calendar

抽象类

代表系统此刻时间对应的日历

通过它可以单独的修改年月日时分年

可变对象,都是在原对象的基础上进行改动的

在这里插入图片描述

import java.util.Calendar;
import java.util.Date;

public class _Calendar_ {
    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
//        System.out.println(c);

        //获取日历的某个信息
        System.out.println(c.get(Calendar.YEAR));
        System.out.println(c.get(Calendar.MONTH));//月份从0开始计算的

        //拿到日历的日期对象
        Date d = c.getTime();
        System.out.println(d);

        //拿到时间毫秒值
        long time = c.getTimeInMillis();
        System.out.println(time);

        //修改日历的某个信息
        c.set(Calendar.MONTH,4);
        System.out.println(c.get(Calendar.MONTH));

        //为某个信息加/减多少
        c.add(Calendar.DAY_OF_MONTH,5);
        
    }
}

JDK8之后新增的日期、时间类

在这里插入图片描述

LocalDate、LocalTime、LocalDateTime

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

LocalDate为例子 其余都大差不差

import javax.security.auth.callback.LanguageCallback;
import java.time.LocalDate;

public class _Local_ {
    public static void main(String[] args) {
        LocalDate ld = LocalDate.now();//不可变对象

        //获取日期对象的信息
        int year =ld.getYear();//年
        int month=ld.getMonthValue();//月(1-12)
        int day =ld.getDayOfMonth();//日
        int dayofYear =ld.getDayOfYear();//一年中的第几天
        int dayOfWeek=ld.getDayOfWeek().getValue();// 星期几
        System.out.println(year+"-"+month+"-"+day);
        System.out.println(dayOfWeek);

        //修改某个信息 withxxx
        LocalDate ld1 = ld.withYear(2049);
        LocalDate ld2 = ld.withMonth(12);

        //把某个信息加多少 plusxxx
        LocalDate ld3 = ld.plusYears(5);
        LocalDate ld4 = ld.plusMonths(4);

        //把某个信息减多少 minusxxx
        LocalDate ld5 = ld.minusDays(5);
        LocalDate ld6 = ld.minusYears(1);

        //获取指定日期的LocalDate对象
        LocalDate ld7 = LocalDate.of(2025,5,19);

        //判断两个日期对象 是否相等 是否在前 是否在后
        System.out.println(ld5.equals(ld6));
        System.out.println(ld5.isAfter(ld6));
        System.out.println(ld5.isBefore(ld6));
    }
}

LocalDateTime独有的

转成其他两个对象

LocalDateTime ldt = LocalDateTime,now();

LocalDate ld = ldt.toLocalDate();
LocalTime lt = ldt.toLocalTime();

ZoneId、ZonedDateTime

ZoneId:时区id

ZonedDateTime:时区时间

在这里插入图片描述

import java.time.Clock;
import java.time.ZoneId;
import java.time.ZonedDateTime;

public class _Zone_ {
    public static void main(String[] args) {
        //获取系统默认时区
        ZoneId zoneId = ZoneId.systemDefault();
        System.out.println(zoneId.getId());
        System.out.println(zoneId);

        //获取java支持的所有时区Id
        System.out.println(zoneId.getAvailableZoneIds());

        //时区id封装成ZoneId
        ZoneId zoneId1 = zoneId.of("America/New_York");

        //获取某个时区的时间
        ZonedDateTime now = ZonedDateTime.now(zoneId1);
        System.out.println(now);
        //世界标准时间
        System.out.println(ZonedDateTime.now(Clock.systemUTC()));
        //默认是系统默认时区
        System.out.println(ZonedDateTime.now());

        //getxxx withxxxx plusxxx minusxxx 都有
        
    }
}

Instant

时间线上的某个时刻/时间戳

精确到纳秒

在这里插入图片描述

import java.time.Instant;

public class _Instant_ {
    public static void main(String[] args) {
        /***
         * 作用:
         * 做代码的性能分析
         * 记录用户的操作时间点
         */

        //获取对象
        Instant instant = Instant.now();
        System.out.println(instant);

        //获取总秒数
        long second = instant.getEpochSecond();
        System.out.println(second);

        //不够1秒的纳秒数
        int nano = instant.getNano();
        System.out.println(nano);
    }
}

DateTimeFormatter

格式化器,用于时间的格式化、解析

JDK之前线程不安全

在这里插入图片描述

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class _DateTime_ {
    public static void main(String[] args) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");

        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);

        //格式化时间
        String ts = dateTimeFormatter.format(now);
        System.out.println(ts);

        //另外的写法
        System.out.println(now.format(dateTimeFormatter));

        //解析时间
        String dateStr = "2033年12月01日 12:12:03";
        LocalDateTime ldt = LocalDateTime.parse(dateStr,dateTimeFormatter);
        System.out.println(ldt);
    }
}

Period、Duration

计算时间间隔

在这里插入图片描述

import java.time.LocalDate;
import java.time.Period;

public class _period_ {
    public static void main(String[] args) {
        LocalDate start = LocalDate.of(2023,12, 1);
        LocalDate end = LocalDate.of(2024,1,23);
        Period between = Period.between(start, end);
        System.out.println(between);
        System.out.println(between.getYears());
        System.out.println(between.getMonths());
        System.out.println(between.getDays());
    }
}

在这里插入图片描述

import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;

public class _Duration_ {
    public static void main(String[] args) {
        LocalDateTime start = LocalDateTime.of(2024,1,10,11,11,20);
        LocalDateTime end = LocalDateTime.of(2024,2,1,11,11,11);

        Duration between = Duration.between(start, end);

        System.out.println(between.toDays());
        System.out.println(between.toHours());
        System.out.println(between.toSeconds());//秒
        System.out.println(between.toMillis());//毫秒
        System.out.println(between.toNanos());//纳秒
    }
}

Arrays类

操作数组的工具类

在这里插入图片描述

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.IntToDoubleFunction;

public class _Arrays_ {
    public static void main(String[] args) {
        int[] arr = {12,321,5,6,54,112};
        System.out.println(Arrays.toString(arr));

        //指定范围的拷贝  [beg,end)
        int[] arr2 = Arrays.copyOfRange(arr,1,3);
        System.out.println(Arrays.toString(arr2));

        //拷贝数组 可以指定新数组长度
        int[] arr3 = Arrays.copyOf(arr,10);
        System.out.println(Arrays.toString(arr3));

        //把数组中原数据改为新数据再存进去
        //把所有的价格都打八折 放入原数组
        double[] prices = {19.2,25.6,123.55,33.6};
        Arrays.setAll(prices, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int index) {
                return BigDecimal.valueOf(prices[index]).multiply(BigDecimal.valueOf(0.8)).doubleValue();
            }
        });
        for (double price : prices) {
            System.out.print(price+" ");
        }

        System.out.println();
        //排序 默认升序 从小到大
        Arrays.sort(prices);
        for (double price : prices) {
            System.out.print(price+" ");
        }
        System.out.println();
        //如果存储的是对象 怎么排序?
        /***
         * 方法一、类中实现Comparable接口的compareTo方法
         * 方法二、使用另外的sort 创建Comparator比较器 创建一个匿名内部类
         */
        YStudent[]yStudents = new YStudent[4];
        yStudents[0] = new YStudent("悟空",999);
        yStudents[1] = new YStudent("白猴子",18);
        yStudents[2] = new YStudent("六耳猕猴",347);
        yStudents[3] = new YStudent("貂蝉",18);

//        Arrays.sort(yStudents);
        Arrays.sort(yStudents, new Comparator<YStudent>() {
            @Override
            public int compare(YStudent o1, YStudent o2) {
                return o1.getAge()-o2.getAge();
            }
        });
        for (YStudent yStudent : yStudents) {
            System.out.println(yStudent.getName()+"_"+yStudent.getAge());
        }
    }

}

class YStudent implements Comparable<YStudent> {
    private String name;
    private int age;

    public YStudent() {
    }

    public YStudent(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


    @Override
    public int compareTo(YStudent o) {
        /***
         * this左边对象 o右边对象
         * 正整数 交换
         * 负整数 不变位置
         */
        return this.age-o.age;
    }
}

JDK8新特性

lambda表达式

基本认识

简化匿名内部类的代码写法

在这里插入图片描述

public class Test {
    public static void main(String[] args) {
       Animal dog =  new Animal(){
            @Override
            void run(){
                System.out.println("dog~~~");
            }
        };
       dog.run();

       //lambda表达式不能简化全部匿名内部类的写法
        //只能简化 函数式接口 的匿名内部类
        //函数式接口: 1、接口   2、仅有一个抽象方法
        Swimming dogSwim = ()->{
            System.out.println("🐕🏊‍🏊‍🏊‍🏊‍");
        };
        /*
        * 等价于
        * new Swimming(){
        *   @Override
        *   void swim(){
        *       System.out.println("🐕🏊‍🏊‍🏊‍🏊‍");
        *   }
        * }
        * */

        dogSwim.swim();
    }
}

abstract class Animal{
    abstract void run();
}

@FunctionalInterface
interface Swimming{
    String name = "da";
    void swim();
}

注意

  • 只能简化函数式接口的匿名内部类
    • 有且仅有一个抽象方法的接口

省略规则

  • 参数类型可以省略不写
  • 只有一个参数,在上面的基础上 小括号也可以省略
  • 方法体只有一行代码,花括号、分号、return都要去掉

方法引用

进一步简化lambda表达式

标志性符号::

静态方法引用

场景:如果某个lambda表达式仅仅调用一个静态方法,并且前后参数的形式一致 那么可以静态方法引用

        /***
         * 以下写法都是等价的
         */
//          Arrays.sort(yStudents, new Comparator<YStudent>() {
//              @Override
//              public int compare(YStudent o1, YStudent o2) {
//                  return o1.getAge()-o2.getAge();
//              }
//          });
//        Arrays.sort(yStudents, (o1, o2) -> o1.getAge()-o2.getAge());
//        Arrays.sort(yStudents,((o1, o2) -> CompareByDate.CompareByAge(o1,o2)));
        Arrays.sort(yStudents,CompareByDate::CompareByAge);
public class CompareByDate {
    public static int CompareByAge(YStudent o1,YStudent o2){
        return o1.getAge()-o2.getAge();
    }
}

实例方法引用

场景:如果某个lambda表达式仅仅调用一个实例方法,并且前后参数的形式一致 那么可以实例方法引用

        /***
         * 以下写法都是等价的
         */
//          Arrays.sort(yStudents, new Comparator<YStudent>() {
//              @Override
//              public int compare(YStudent o1, YStudent o2) {
//                  return o2.getAge()-o1.getAge();
//              }
//          });
//        Arrays.sort(yStudents, (o1, o2) -> o2.getAge()-o1.getAge());
        CompareByDate compareByDate = new CompareByDate();
//        Arrays.sort(yStudents,((o1, o2) -> compareByDate.compareByAgeDesc(o1,o2)));
        Arrays.sort(yStudents,compareByDate::compareByAgeDesc);
package API;

public class CompareByDate {
   public int compareByAgeDesc(YStudent o1,YStudent o2){
       return o2.getAge()-o1.getAge();
   }
}

特定类型的方法引用

场景:如果某个lambda表达式仅仅调用一个实例方法,并且前面参数列表的第一个参数作为方法的主调,后面的所有参数作为该实例方法的参数传入(比如传入 o1 o2 o1.xxx(o2)),那么可以使用特定类型的方法引用

import java.sql.Array;
import java.util.Arrays;
import java.util.Comparator;

public class Test1 {
    public static void main(String[] args) {
        String[] names = {"angela","body","cc","Andy","Bob","Alice","Yb0os1"};
        //默认是按照ASCII码排序 也即是先大写 后小写
        Arrays.sort(names);
        for (String name : names) {
            System.out.println(name);
        }

        System.out.println("------------------------");

        /***
         * 目标:忽略大小写排序
         */
        /*Arrays.sort(names, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareToIgnoreCase(o2);
            }
        });*/
//        Arrays.sort(names, (o1, o2) -> o1.compareToIgnoreCase(o2));
        Arrays.sort(names,String::compareToIgnoreCase);

        for (String name : names) {
            System.out.println(name);
        }
    }
}

构造器引用

场景:如果某个lambda表达式里只是在创建对象,前后参数情况一致,那么就可以调用构造器引用

public class Test2 {
    public static void main(String[] args) {
        /*CreatCar bmw = new CreatCar() {
            @Override
            public Car creat(String name, double price) {
                return new Car(name,price);
            }
        };*/
//        CreatCar bmw = (name, price) ->new Car(name, price);

       CreatCar cc = Car::new;
       cc.creat("BMW",49.6);
       System.out.println(cc);
    }
}

interface CreatCar{
    Car creat(String name,double price);
}
class Car{
    private String name;
    private double price;

    public Car() {
    }

    public Car(String name, double price) {
        this.name = name;
        this.price = price;
    }
}

Stream流

方便操作集合/数据的一个手段

**注意:**流只能收集一次

简单使用

package _Stream;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class demo {
    public static void main(String[] args) {
        List<String>names = new ArrayList<>();
        Collections.addAll(names,"张三丰","周芷若","张无忌","赵敏","张三");
        System.out.println(names);
        //过滤出姓张的

        List<String> startZhang = names.stream().filter(s -> s.startsWith("张"))
                .filter(s -> s.length() == 3).collect(Collectors.toList());
        System.out.println(startZhang);
    }
}

使用步骤

在这里插入图片描述

常用方法

获取Stream流

在这里插入图片描述

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class Demo1 {
    public static void main(String[] args) {
        //List Set都是stream
        List<String> names = new ArrayList<>();
        Collections.addAll(names,"张三丰","周芷若","张无忌","赵敏","张三");
        Stream<String> stream = names.stream();

        //Map获取Stream 分开处理或者Entry
        Map<String,Double>map = new HashMap<>();
        map.put("hello",10.0);
        Set<Map.Entry<String, Double>> kvs = map.entrySet();
        kvs.stream().filter(s->s.getKey().contains("l")).forEach(s-> System.out.println(s.getKey()+" "+s.getValue()));

        //数组获取Stream
        Integer[] scores = {1,2,3,4,5,6,7,8,9};
        Arrays.stream(scores).filter(s->s>5).forEach(s-> System.out.println(s));

        Stream.of(scores).filter(s->s<5).forEach(s-> System.out.println(s));
    }
}
中间方法

调用完成后返回Steam流对象,所以支持链式编程

在这里插入图片描述

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Demo3 {
    public static void main(String[] args) {
        List<Double>scores = new ArrayList<>();
        Collections.addAll(scores,81.5,71.1,90.0,99.5,100.0,21.5,60.5);
        //找出成绩大于60小于90分 升序输出 filter sorted
        scores.stream().filter(s->s>60&&s<90).sorted().forEach(s-> System.out.println(s));


        List<Stu>stus = new ArrayList<>();
        stus.add(new Stu("妲己",19));
        stus.add(new Stu("牛魔王",51));
        stus.add(new Stu("西施",25));
        stus.add(new Stu("西施",25));
        stus.add(new Stu("貂蝉",21));
        stus.add(new Stu("吴",55));
        stus.add(new Stu("孙悟空",999));
        stus.add(new Stu("王昭君",20));
        stus.add(new Stu("猪八戒",888));
        stus.add(new Stu("沙和尚",777));

        //年龄大于18小于30 降序输出 sorted
        stus.stream().filter(s->s.getAge()>18&&s.getAge()<30).sorted((o1,o2)->o2.getAge()-o1.getAge()).forEach(s-> System.out.println(s.getName()+"-"+s.getAge()));

        //年龄最大的三个人 limit
        stus.stream().sorted((o1,o2)->o2.getAge()-o1.getAge()).limit(3).forEach(s-> System.out.println(s.getName()+"-"+s.getAge()));

        //年龄最小的2个人
        stus.stream().sorted(Comparator.comparingInt(Stu::getAge)).limit(2).forEach(s-> System.out.println(s.getName()+"-"+s.getAge()));

        //年龄大于18 小于30  去除重复名字
        //distinct基于equals 和 hashCode比较的
        stus.stream().filter(s->s.getAge()>18&&s.getAge()<30).map(Stu::getName).distinct().forEach(System.out::println);
    }
}

class Stu{
    private String name;
    private int age;

    public Stu(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
终结方法

调用完成后不会返回Stream对象

在这里插入图片描述

收集Stream

在这里插入图片描述

正则表达式

作用

  • 校验数据格式是否合法
  • 在一段文本查找满足要求的内容

在这里插入图片描述

注意

  • []、与定义字符只能一次匹配一个
  • ^是取反
  • (?i)是忽略大小写
(?i)abc  ABC Abc ABc abc等等都可以匹配

应用

检验电话、邮箱、时间

public class Test1 {
    public static void main(String[] args) {
        String q1 = "15646816365";
        String q2 = "455dada";
        System.out.println(checkQQ(q1));
        System.out.println(checkQQ(q2));
        System.out.println("--------------");
        //使用正则表达式
        System.out.println("对QQ号码的检查");
        System.out.println(checkQQRegex(q1));
        System.out.println(checkQQRegex(q2));
        System.out.println("对电话|座机号码的检查");
        String tel1 = "012-34567891";
        String tel2 = "13563075567";
        String tel3 = "1006307556a";
        System.out.println(checkTel(tel1));
        System.out.println(checkTel(tel2));
        System.out.println(checkTel(tel3));
        System.out.println("对邮箱的检查");
        String email1 = "Lenovo@163.com.";
        String email2 = "Lenovo@163.com.cn";
        String email3 = "L@163.com";
        System.out.println(checkEmail(email1));
        System.out.println(checkEmail(email2));
        System.out.println(checkEmail(email3));
        System.out.println("对时间的检查");
        String time1 = "0:10:10";
        String time2 = "12:60:00";
        String time3 = "1:02:2";
        System.out.println(checkTime(time1));
        System.out.println(checkTime(time2));
        System.out.println(checkTime(time3));
    }

    private static boolean checkQQ(String qq){
        /**
         * 校验QQ号码是否正确 要求全部是数字 长度是6-20 不能以0开头
         */
        int length = qq.length();
        if (length<6||length>20||qq==null||qq.startsWith("0"))return false;
        for (int i = 0; i < length; i++)
            if (qq.charAt(i)<'0'||qq.charAt(i)>'9')return false;

        return true;
    }
    private static boolean checkQQRegex(String qq){
        return qq!=null&&qq.matches("[1-9]\\d{5,19}");
    }
    private static boolean checkTel(String tel){
        return tel!=null&&tel.matches("(1[3-9]\\d{9})|(0\\d{2,4}-?[1-9]\\d{4,19})");
    }
    private static boolean checkEmail(String email){
        return email!=null&&email.matches("\\w{2,}@\\w{2,10}(\\.\\w{2,10}){1,2}");
    }
    private static boolean checkTime(String time){
        return time!=null&&time.matches("([0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])");
    }
}

查找信息

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Test2 {
    public static void main(String[] args) {
        String data  = """
                来yb0os1学习java
                电话:18666888882,15536588918
                邮箱:yb0os1@ityb0os1.com,2536522@OO.com.cn
                座机电话:0125-2585461265,0562-46516564
                热线电话:400-618-9090,400-618-4000,4006189090,4006184000
                """;
        //定义爬取规则
        String regex = "(1[3-9]\\d{9})|(0\\d{2,7}-?[1-9]\\d{4,19})|\\w{2,}@\\w{2,10}(\\.\\w{2,10}){1,2}|(400-?\\d{3,7}-?\\d{3,7})";
        //把正则表达式封装成一个Pattern对象
        Pattern p = Pattern.compile(regex);
        //通过pattern对象取获取查找内容的匹配器对象
        Matcher matcher = p.matcher(data);
        //循环爬取信息
        while (matcher.find()){//找到一个就返回true
            System.out.println(matcher.group());
        }

    }
}

搜索替换、分割内容

在这里插入图片描述

import java.util.Arrays;

public class Test3 {
    public static void main(String[] args) {
        //需求1:把 古力娜扎6565465dasda迪丽热巴dadsa4156465马儿扎哈231231j卡尔巴哈 的非中文替换为-
        String s1 = "古力娜扎6565465dasda迪丽热巴dadsa4156465马儿扎哈231231j卡尔巴哈";
        System.out.println(s1.replaceAll("\\w+","-"));

        //需求2:我我我我我我喜喜欢JJJJJJJJavvvaaaa! 优化 我喜欢Java!
        String s2="我我我我我我喜喜欢JJJJJJJJavvvaaaa!";
        /**
         * (.) 一组
         * \\1 为这个组声明一个组号
         * + 必须是重复的
         * $1 获取第1组重复的字 只有一个
         */
        System.out.println(s2.replaceAll("(.)\\1+","$1"));

        //需求3:把 古力娜扎6565465dasda迪丽热巴dadsa4156465马儿扎哈231231j卡尔巴哈 分割为一个数组
        String s3="古力娜扎6565465dasda迪丽热巴dadsa4156465马儿扎哈231231j卡尔巴哈";
        String[] ss = s3.split("\\w+");
        System.out.println(Arrays.toString(ss));
    }
}

基本简单练习

买飞机票

public class BugAeroplane {
    public static void main(String[] args) {
        String type = "头等舱";
        int month = 5;double price = 1000;
        buy(type, price, month);
    }

    public static void buy(String tool, double value, int month) {
        if (month>=5&&month<=10){
            if (tool.equals("头等舱"))
                value *= 0.9;
            else if (tool.equals("经济舱"))
                value *= 0.85;
        }else {
            if (tool.equals("头等舱"))
                value *= 0.7;
            else if (tool.equals("经济舱"))
                value *= 0.65;
        }
        System.out.println(month + "月份" + tool + "机票的价格为" + value);
    }
}

开发验证码

在这里插入图片描述

import java.util.Random;

public class YanZhengMa {
    public static void main(String[] args) {
        String code = createCode(4);
        System.out.println(code);
    }
    public static String createCode(int n){
        Random r = new Random();
        String code = "";
        for (int i = 0; i < n; i++) {
            int type = r.nextInt(3);
            switch (type){
                case 0:
                    //数字
                    code+=r.nextInt(10);
                    break;
                case 1:
                    //大写字母
                    code+=(char)(r.nextInt(26)+65);
                    break;
                case 2:
                    //小写字母
                    code+=(char)(r.nextInt(26)+97);
                    break;
            }
        }
        return code;
    }
}

评委打分

在这里插入图片描述

import java.util.Scanner;

public class GetScore {
    public static void main(String[] args) {
        System.out.println(getSocre(6));
    }

    public static double getSocre(int n) {
        Scanner sc = new Scanner(System.in);
        double finalScore = 0, maxScore = 0, minScore = 100;
        for (int i = 0; i < n; i++) {
            System.out.println("请您录入第"+(i+1)+"个评委的分数");
            double score = sc.nextDouble();
            if(score<0||score>100){
                System.out.println("不符合");
                return -1;
            }
            finalScore+=score;
            maxScore = score>maxScore?score:maxScore;
            minScore = score<minScore?score:minScore;
        }
        finalScore = (finalScore-maxScore-minScore)/(n-2);
        return finalScore;
    }
}

数字加密

在这里插入图片描述

public class Crypt {
    public static void main(String[] args) {
        System.out.println(encrypt(1983));
        System.out.println(decrypt(8346));
    }
    public static int encrypt(int password){
        int result = 0;
        while (password>0){
            int now = password%10;
            result =result*10+(now+5)%10;
            password/=10;
        }
        return result;
    }
    public static int decrypt(int password){
        int result = 0;
        while (password>0){
            int now = password%10-5;
            now = now>0?now:now+10;
            result = result*10 + now;
            password/=10;
        }
        return result;
    }
}

抢红包

在这里插入图片描述

package com.yb0os1.demo;
import java.util.Random;

public class QiangHongBao {
    public static void main(String[] args) {
        int[] moneys = {9,90,999,1000,5648};
        start(moneys);
    }
    
    public static void start(int []moneys){
        Random r = new Random();
        for (int i = 0; i < moneys.length; i++) {
            int j = r.nextInt(moneys.length);
            int tmp = moneys[i];
            moneys[i]= moneys[j];
            moneys[j] = tmp;
            
            /*if(i==j)continue;
            moneys[i] = moneys[i]+moneys[j];
            moneys[j]=moneys[i]-moneys[j];
            moneys[i] = moneys[i]-moneys[j];*/
        }
        System.out.println("红包顺序:");
        for (int money : moneys) {
            System.out.println(money);
        }
    }
}

模拟双色球

在这里插入图片描述

import java.util.Random;
import java.util.Scanner;

public class DualColouredBall {
    public static void main(String[] args) {
        int[] numbers = userSelectNumbers();
        int[] result = systemSelectNumbers();
        print("用户选择",numbers);
        print("奖品",result);
        isPrice(numbers,result);
    }

    public static int[] userSelectNumbers() {
        int[] numbers = new int[7];
        Scanner sc = new Scanner(System.in);
        //红球
        for (int i = 0; i < numbers.length - 1; i++) {
            System.out.println("请输入红球号码(1-33之内且不能重复):");
            while (true) {
                int number = sc.nextInt();
                if (number < 1 || number > 33)
                    System.out.println("输入不合理,请重新输入");
                else if (exist(numbers, number))
                    System.out.println("重复输入,请重新输入");
                else {
                    numbers[i] = number;
                    break;
                }
            }
        }
        //蓝球
        System.out.println("请输入蓝球号码(1-16之内):");
        while (true) {
            int number = sc.nextInt();
            if (number > 16 || number < 1) {
                System.out.println("输入不合理,请重新输入");
            } else {
                numbers[numbers.length - 1] = number;
                break;
            }
        }
        return numbers;
    }

    public static int[] systemSelectNumbers() {
        int[] numbers = new int[7];
        Random r = new Random();

        for (int i = 0; i < numbers.length - 1; i++) {
            while (true) {
                int number = r.nextInt(33) + 1;
                if (!exist(numbers, number)) {
                    numbers[i] = number;
                    break;
                }
            }
        }
        int number = r.nextInt(16) + 1;
        numbers[numbers.length - 1] = number;
        return numbers;
    }

    public static void isPrice(int[] numbers, int[] result) {
        int redCount = 0;
        int nLen = numbers.length, rLen = result.length;
        int blueCount = numbers[nLen - 1] == result[rLen - 1] ? 1 : 0;
        for (int i = 0; i < rLen - 1; i++) {
            for (int j = 0; j < nLen - 1; j++) {
                if (numbers[j]==result[i])
                    redCount++;
            }
        }
        System.out.println("中"+redCount+"+"+blueCount);
    }

    public static void print(String name,int[]arr){
        System.out.print(name+":");
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i]);
            if(!(i==arr.length-1)) System.out.print(",");
        }
        System.out.println();
    }
    public static boolean exist(int[] numbers, int number) {
        for (int n : numbers) {
            if (n == number)
                return true;
        }
        return false;
    }
}

简单的ATM系统

Test.java

package ATMsystem;
public class Test {
    public static void main(String[] args) {
        ATM test = new ATM();
        test.start();
    }
}

Account.java

package ATMsystem;
//账户类
public class Account {
    private String id;
    private String username;
    private char sex;
    private double balance;
    private String password;
    private double limit;

    public Account() {
    }

    public Account(String id, String username, char sex, double balance, String password, double limit) {
        this.id = id;
        this.username = username;
        this.sex = sex;
        this.balance = balance;
        this.password = password;
        this.limit = limit;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public char getSex() {
        return sex;
    }

    public void setSex(char sex) {
        this.sex = sex;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public double getLimit() {
        return limit;
    }

    public void setLimit(double limit) {
        this.limit = limit;
    }
}

ATM.java

package ATMsystem;

import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Random;
import java.util.Scanner;

//对账户进行处理
public class ATM {
    private ArrayList<Account> accounts = new ArrayList<>();

    //开始界面
    public void start() {
        System.out.println("===欢迎进入yb0os1的银行系统==");
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("1、用户登录");
            System.out.println("2、用户开户");
            System.out.println("3、退出系统");
            System.out.print("请输入:");
            String command = sc.next();
            switch (command) {
                case "1":
                    login();
                    break;
                case "2":
                    createAcconut();
                    break;
                case "3":
                    System.out.println("退出系统成功");
                    return;
                default:
                    System.out.println("输入有误");
                    break;
            }
        }
    }

    //登录之后的
    private void loginAfter(Account ac) {
        Scanner sc = new Scanner(System.in);
        System.out.println("===欢迎您尊敬的"+ac.getUsername()+"===");
        while (true) {
            System.out.println("===可以办理以下业务===");
            System.out.println("1、查询账户");
            System.out.println("2、存款");
            System.out.println("3、取款");
            System.out.println("4、转账");
            System.out.println("5、修改密码");
            System.out.println("6、退出");
            System.out.println("7、注销账户");
            System.out.print("请选择:");
            String command = sc.next();
            switch (command){
                case "1":
                    viewUser(ac.getId(),ac.getUsername(),ac.getSex(),ac.getBalance(),ac.getLimit());
                    break;
                case "2":
                    storageMoney(ac);
                    break;
                case "3":
                    withdrawMoney(ac);
                    break;
                case "4":
                    Transfer(ac);
                    break;
                case "5":
                    changePass(ac);
                    break;
                case "6":
                    return;
                case "7":
                    deleteAccount(ac);
                    return;
                default:
                    System.out.println("输入有误 请重新输入");
                    break;
            }
        }
    }

    private void deleteAccount(Account ac) {
        accounts.remove(ac);
        System.out.println("删除成功");
    }

    private void changePass(Account ac) {
        Scanner sc= new Scanner(System.in);

        while (true) {
            System.out.println("请输入原密码");
            String oldPassword = sc.next();
            if (!ac.getPassword().equals(oldPassword)){
                System.out.println("原密码输入错误,请重新输入");
            }
            System.out.println("请输入新密码");
            String newPassword = sc.next();
            if (ac.getPassword().equals(newPassword)){
                System.out.println("新密码和原密码相同,请重新输入");
            }
            ac.setPassword(newPassword);
            System.out.println("修改密码成功"+newPassword);
            return;
        }
    }

    private void viewUser(String id,String username,char sex,double balance,double limit){
    System.out.println("===个人信息===");
    System.out.println("用户id:"+id);
    System.out.println("用户名:"+username);
    System.out.println("性别:"+sex);
    System.out.println("余额:"+balance);
    System.out.println("每次最大取得金额:"+limit);
    System.out.println("==========");
}
    private void storageMoney(Account ac){
        Scanner sc=new Scanner(System.in);

        System.out.println("请输入存放的金额");
        double money = sc.nextDouble();
        while (money<=0){
            System.out.println("输入有误 请重新输入");
            money = sc.nextDouble();
        }
        ac.setBalance(ac.getBalance()+money);
        System.out.println(ac.getUsername()+",您现在余额为:"+ac.getBalance()+"元");
    }
    private void withdrawMoney(Account ac){
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入取走的金额");
        double money = sc.nextDouble();
        while (money<=0||money>ac.getBalance()){
            System.out.println("输入有误 请重新输入");
            money = sc.nextDouble();
        }
        ac.setBalance(ac.getBalance()-money);
        System.out.println(ac.getUsername()+",您取走"+money+"元,"+"现在余额为:"+ac.getBalance()+"元");
    }
    private void Transfer(Account ac){
        if (accounts.size()<2){
            System.out.println("账户不足两个,无法进行转账");
            return;
        }
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入被转帐人的id");
        String id = sc.next();
        while (isContain(id)==-1||ac.getId().equals(id)){
            System.out.println("输入有误,请重新输入被转账人id");
            id = sc.next();
        }
        int index = isContain(id);
        Account ca = accounts.get(index);
        System.out.println("请输入转账金额");
        double money = sc.nextDouble();
        while (money>ac.getBalance()||money<=0){
            System.out.println("输入有误,请重新输入转账金额");
            money = sc.nextDouble();
        }
        ac.setBalance(ac.getBalance()-money);
        ca.setBalance(ca.getBalance()+money);
        System.out.println(ac.getUsername()+"的余额为:"+ac.getBalance());
        System.out.println(ca.getUsername()+"的余额为:"+ca.getBalance());
    }
    //用户登录
    private void login(){
        if(accounts.isEmpty()){
            System.out.println("当前没有账户,请先开户");
            return;
        }
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入用户id");
        String id = sc.next();
        int index = isContain(id);
        while (index==-1){
            System.out.println("没有该账户,请重新输入");
            id = sc.next();
            index= isContain(id);
        }
        System.out.println("请输入密码");
        String password = sc.next();
        while (!accounts.get(index).getPassword().equals(password)){
            System.out.println("密码错误,请重新输入");
            password = sc.next();
        }
        System.out.println("登录成功");
        loginAfter(accounts.get(index));
    }
    //用户创建
    private void createAcconut() {
        Scanner sc = new Scanner(System.in);

        System.out.println("请输入用户名称");
        String name = sc.next();
        while (name.length() < 5 || name.length() > 20) {
            System.out.println("输入的名字过长或者过短 请重新输入");
            name = sc.next();
        }
        System.out.println("请输入用户性别");
        char sex = sc.next().toCharArray()[0];
        while (!(sex == '男' || sex == '女')) {
            System.out.println("性别有误 请重新输入");
            sex = sc.next().toCharArray()[0];
        }
        System.out.println("请输入密码");
        String password1 = sc.next();
        System.out.println("请确定输入密码");
        String password2 = sc.next();
        while (!password1.equals(password2)) {
            System.out.println("两次输入不一致 请重新输入");
            password2 = sc.next();
        }
        String id = generateId();
        while (isContain(id)!=-1){
            id = generateId();
        }
        System.out.println("请输入每次取钱的最大值");

        double limit = sc.nextDouble();
        while (limit<=0){
            System.out.println("输入有误 请重新输入");
            limit = sc.nextDouble();
        }
        accounts.add(new Account(id,name,sex,0,password2,limit));
        System.out.println("用户创建成功,您的id为"+id);
    }

    private String generateId() {
        Random r = new Random();
        String res = "";
        for (int i = 0; i < 8; i++) {
            res += (r.nextInt(10));
        }
        return res;
    }

    private int isContain(String id){
        for (int i =0;i<accounts.size();++i) {
            if(accounts.get(i).getId().equals(id)){
                return i;
            }
        }
        return -1;
    }
}
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Demo3 {
    public static void main(String[] args) {
        List<Double>scores = new ArrayList<>();
        Collections.addAll(scores,81.5,71.1,90.0,99.5,100.0,21.5,60.5);
        //找出成绩大于60小于90分 升序输出 filter sorted
        scores.stream().filter(s->s>60&&s<90).sorted().forEach(s-> System.out.println(s));


        List<Stu>stus = new ArrayList<>();
        stus.add(new Stu("妲己",19));
        stus.add(new Stu("牛魔王",51));
        stus.add(new Stu("西施",25));
        stus.add(new Stu("西施",25));
        stus.add(new Stu("貂蝉",21));
        stus.add(new Stu("吴",55));
        stus.add(new Stu("孙悟空",999));
        stus.add(new Stu("王昭君",20));
        stus.add(new Stu("猪八戒",888));
        stus.add(new Stu("沙和尚",777));

        //年龄大于18小于30 降序输出 sorted
        stus.stream().filter(s->s.getAge()>18&&s.getAge()<30).sorted((o1,o2)->o2.getAge()-o1.getAge()).forEach(s-> System.out.println(s.getName()+"-"+s.getAge()));

        //年龄最大的三个人 limit
        stus.stream().sorted((o1,o2)->o2.getAge()-o1.getAge()).limit(3).forEach(s-> System.out.println(s.getName()+"-"+s.getAge()));

        //年龄最小的2个人
        stus.stream().sorted(Comparator.comparingInt(Stu::getAge)).limit(2).forEach(s-> System.out.println(s.getName()+"-"+s.getAge()));

        //年龄大于18 小于30  去除重复名字
        //distinct基于equals 和 hashCode比较的
        stus.stream().filter(s->s.getAge()>18&&s.getAge()<30).map(Stu::getName).distinct().forEach(System.out::println);
    }
}

class Stu{
    private String name;
    private int age;

    public Stu(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值