Java学习笔记

枚举
1)枚举对应英文(enumeration,简写enum)
2)枚举是一组常量的集合。
3)可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。

枚举的二种实现方式
1)自定义类实现枚举
2)使用enum关键字实现枚举

自定义类实现枚举-应用案例
1.不需要提供setXxx方法,因为枚举对象值通常为只读.
2.对枚举对象/属性使用final + static共同修饰,实现底层优化.
3.枚举对象名通常使用全部大写,常量的命名规范.
4.枚举对象根据需要,也可以有多个属性

小结:进行自定义类实现枚举,有如下特点:
1)构造器私有化
2)本类内部创建一组对象门
3)对外暴露对象(通过为对象添加public final static修饰符)
4)可以提供get方法,但是不要提供set

package com.dxl.staticpar;

public class Enumweration {
    public static void main(String[] args) {
        System.out.println(Season.AUTUMN);
    }
}

class Season{
    private String name;
    private String desc;

    public final static Season SPRING = new Season("春天","温暖");
    public final static Season WINTER = new Season("冬天","寒冷");
    public final static Season AUTUMN = new Season("秋天","凉爽");
    public final static Season SUNMMER = new Season("夏天","炎热");

    //    1.将构造器私有化
//    2.去掉set方法,防止属性被修改
//    3.在内部创建固定的值
//    4.优化:在加入一个final关键字
    private Season(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

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

使用关键字enum来实现枚举类

package com.dxl.staticpar;

public class Enumweration {
    public static void main(String[] args) {
        System.out.println(Season2.AUTUMN);
    }
}

enum Season2{

//    public final static Season SPRING = new Season("春天","温暖");
//    public final static Season WINTER = new Season("冬天","寒冷");
//    public final static Season AUTUMN = new Season("秋天","凉爽");
//    public final static Season SUNMMER = new Season("夏天","炎热");

//    如果使用enum来实现枚举类
//    1.使用关键字 enum 替代 class
//    2.原来的 public final static Season SPRING = new Season("春天","温暖");
//    使用  SPRING("春天","温暖");  替代
//    3.如果有多个常量,用逗号间隔
//    4.如果使用enum 来实现枚举,要求将定义常量对象写在最前面。

    SPRING("春天","温暖"), WINTER("冬天","寒冷"),
    AUTUMN("秋天","凉爽"), SUNMMER("夏天","炎热");
    private String name;
    private String desc;//描述

    //    1.将构造器私有化
//    2.去掉set方法,防止属性被修改
//    3.在内部创建固定的值
//    4.优化:在加入一个final关键字
    private Season2(String name, String desc) {
        this.name = name;
        this.desc = desc;
    }

    public String getName() {
        return name;
    }

    public String getDesc() {
        return desc;
    }

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

enum关键字实现枚举
enum关键字实现枚举注意事项
1.当我们使用enum关键字开发一个枚举类时,默认会继承Enum类[如何证明]
2.传统的 public static final Season2 SPRING = new Season2(春天",“温暖“”);简化成 SPRING(“春天”,“温暖”),这里必须知道,它调用的是哪个构造器.
3.如果使用无参构造器创建枚举对象,则实参列表和小括号都可以省略
4.当有多个枚举对象时,使用,间隔,最后有一个分号结尾
5.枚举对象必须放在枚举类的行首.
在这里插入图片描述在这里插入图片描述
enum常用方法说明
说明:使用关键字enum时,会隐式继承Enum类,这样我们就可以使用Enum类相关的方法。
public abstract class Enum<E extends Enum>
implements Comparable, Serializable {
}
在这里插入图片描述
1.toString:Enum类已经重写过了,返回的是当前对象名.子类可以重写该方法,用于返回对象的属性信息
2. name:返回当前对象名(常量名),子类中不能重写
3. ordinal:返回当前对象的位置号,默认从0开始
4. values:返回当前枚举类中所有的常量
5. valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!
6. compareTo:比较两个枚举常量,比较的就是位置号!

package com.dxl.staticpar;

public class EnumMethod {
    public static void main(String[] args) {
        Season2 autumn = Season2.AUTUMN;
        System.out.println(autumn.name());
        System.out.println(autumn.ordinal());//位置
        Season2[] values = Season2.values();//返回一个数组,Season2[],含有定义的所有枚举对象
        for (Season2 season : values){//增强for循环,遍历取出枚举数组
            System.out.println(season);
        }

//        valueOf  先根据名称去查找,找到就返回,没找到就报错
        Season2 autumn1 = Season2.valueOf("AUTUMN");
        System.out.println("autumn1 = " + autumn1);

//        比较
        /*
        public final int compareTo(E o){
            return self.ordinal - other.ordinal;
            }
        Season2.AUTUMN的编号[2- Season2.SUMMER的编号[3]
         */
        System.out.println(Season2.AUTUMN.compareTo(Season2.SUNMMER));

//        int[] nums = {1,5,6};
//        System.out.println("=============普通for循环============");
//        for (int i = 0;i < nums.length; i ++){
//            System.out.println(nums[i]);
//        }
//        System.out.println("=============增强for循环=============");
//        for (int i : nums){//依次从nums数组中取值付给i,没有值后就退出循环
//            System.out.println("i = " + i);
//        }

    }
}

案例:

package com.dxl.staticpar;

public class Enumweration {
    public static void main(String[] args){
        Week[] weeks = Week.values();
        for (Week i : weeks){
            System.out.println(i);
        }
    }
}

enum Week{
    MONDAY("星期一"),TUESDAY("星期二"), WEDNESDAY("星期三"),THURSDAY("星期四"),
    FRIDAY("星期五"),SATURDAY("星期六"), SUNDAY("星期日");
    private String name;

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

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }
}

enum实现接口
1)使用enum关键字后,就不能再继承其它类了,因为enum会隐式继承Enum,而Java是单继承机制。
2)枚举类和普通类一样,可以实现接口,如下形式。
enum 类名 implements 接口1,接口2{ }

package com.dxl.staticpar;

public class Enumweration {
    public static void main(String[] args) {
        Music.CLASSMUSIC.playing();
    }
}

class A{

}

//enum Season extends A {//错误
//
//}

interface IPlaying{
    public void playing();
}

enum Music implements IPlaying{
    CLASSMUSIC;

    @Override
    public void playing() {
        System.out.println("播放好听的音乐!");
    }
}

注解的理解
1)注解(Annotation)也被称为元数据(Metadata),用于修饰解释包、类、方法、属性、构造器、局部变量等数据信息。
2)和注释一样,注解不影响程序逻辑,但注解可以被编译或运行,相当于嵌入在代码中的补充信息。
3)在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在JavaEE中注解占据了更重要的角色,例如用来配置应用程序的任何切面,代替java EE旧版中所遗留的繁冗代码和XML配置等。

基本的Annotation介绍
使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用。用于修饰它支持的程序元素

三个基本的Annotation:
1)@Override:限定某个方法,是重写父类方法,该注解只能用于方法2)@Deprecated:用于表示某个程序元素(类,方法等)已过时
3)@SuppressWarnings:抑制编译器警告

补充说明:@interface的说明
interface不是interface,是注解类是jdk5.0之后加入的
在这里插入图片描述
Override使用说明
1.@Override表示指定重写父类的方法(从编译层面验证),如果父类没有fly方法,则会报错
2.如果不写@Override注解,而父类仍有public void fly(){},仍然构成重写3.@Override只能修饰方法,不能修饰其它类,包,属性等等
4.查看@Override注解源码为@Target(ElementType.METHOD),说明只能修饰方法
5.@Target是修饰注解的注解,称为元注解

Deprecated的说明
1.用于表示某个程序元素(类,方法等)已过时
2.可以修饰方法,类,字段,包,参数等等
3.@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE,METHOD,PACKAGE,PARAMETER, TYPE))
4.@Deprecated的作用可以做到新旧版本的兼容和过渡

package com.dxl.staticpar;

public class Deprecated_ {
    public static void main(String[] args) {
        A a = new A();

    }
}

@Deprecated //类已过时,但是过时不代表不能用;即不推荐使用,但还是可以使用
class A {
    public int n1 = 10;
    public void hi(){

    }
}

基本的 Annotation应用案例
@SuppressWarnings注解的案例

  1. unchecked是忽略没有检查的警告
  2. rawtypes是忽略没有指定泛型的警告(传参时没有指定泛型的警告错误)
    3)unused是忽略没有使用某个变量的警告错误
  3. @SuppressWarnings 可以修饰的程序元素为,查看@Target
    5)生成@SupperssWarnings时,不用背,直接点击左侧的黄色提示,就
    可以选择(注意可以指定生成的位置)
package com.dxl.staticpar;

import java.util.ArrayList;

@SuppressWarnings({"all"})//大括号中写上需要抑制的警告类型
public class SuppressWarnings_ {
    public static void main(String[] args) {

        ArrayList arrayList = new ArrayList();
        arrayList.add("jack");
        arrayList.add("tom");
        arrayList.add("mary");
        int i;
        System.out.println(arrayList.get(1));
    }
}

元注解的基本介绍
JDK的元Annotation 用于修饰其他Annotation
元注解:本身作用不大
元注解的种类(使用不多,了解,不用深入研究)

  1. Retention//指定注解的作用范围,三种SOURCE,CLASS,RUNTIME
  2. Target//指定注解可以在哪些地方使用
  3. Documented//指定该注解是否会在javadoc体现
  4. Inherited //子类会继承父类注解

Retention注解
说明
只能用于修饰一个 Annotation定义,用于指定该 Annotation可以保留多长时间,@Rentention包含一个 RetentionPolicy类型的成员变量,使用@Rentention时必须为该value成员变量指定值:
@Retention的三种值

  1. RetentionPolicy.SOURCE:编译器使用后,直接丢弃这种策略的注释
  2. RetentionPolicy.CLASS:编译器将把注释记录在class文件中.当运行Java程序时,JVM不会保留注解。这是默认值
  3. RetentionPolicy.RUNTIME:编译器将把注解记录在class文件中.当运行
    Java程序时,JVM会保留注解.程序可以通过反射获取该注解
    在这里插入图片描述
    @Target 基本说明
    用于修饰Annotation定义,用于指定被修饰的 Annotation能用于修饰哪些程序元素.@Target也包含一个名为value的成员变量。
    在这里插入图片描述
    @Documented 基本说明
    @Documented:用于指定被该元 Annotation修饰的Annotation类将被javadoc工具提取成文档,即在生成文档时,可以看到该注解。
    说明:定义为Documented的注解必须设置Retention值为RUNTIME。

@Inherited注解
被它修饰的Annotation将具有继承性.如果某个类使用了被@Inherited修饰的Annotation,则其子类将自动具有该注解
说明:实际应用中,使用较少,了解即可。

package com.dxl.staticpar;

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

    }
}

class Frock{
    private static int currentNum = 10000;
    private int serialNUmber;

    public Frock(){
        serialNUmber = getNextNum();
    }

    public static int getNextNum(){
        currentNum +=100;
        return currentNum;
    }

    public int getSerialNUmber() {
        return serialNUmber;
    }
}

class TestFrock{
    public static void main(String[] args) {
        System.out.println(Frock.getNextNum());
        System.out.println(Frock.getNextNum());

        Frock frock = new Frock();
        Frock frock1 = new Frock();
        Frock frock2 = new Frock();

        System.out.println(frock.getSerialNUmber());
        System.out.println(frock1.getSerialNUmber());
        System.out.println(frock2.getSerialNUmber());
    }
}
package com.dxl.staticpar;

public class Animal {
    public static void main(String[] args) {
        Animals animals = new Cat();
        Animals animals1 = new Dog();
        animals.shout();
        animals1.shout();
    }
}

abstract class Animals{
    public abstract void shout();
}

class Cat extends Animals{

    @Override
    public void shout() {
        System.out.println("猫会喵喵叫=====");
    }
}

class Dog extends Animals{

    @Override
    public void shout() {
        System.out.println("狗会汪汪叫=======");
    }
}
package com.dxl.staticpar;

public class HomeWork {
    public static void main(String[] args) {
        cellPhone cellPhone = new cellPhone();
        cellPhone.testWork(new ICalculate() {
            @Override
            public double work(double n1, double n2) {
                return n1 + n2;
            }
        },12,56);
    }
}

interface ICalculate{
    public double work(double n1, double n2);
}

class cellPhone{
    public void testWork(ICalculate iCalculate,double n1,double n2){
        double result = iCalculate.work(n1,n2);
        System.out.println("计算后的结果是: " + result);
    }

}
package com.dxl.staticpar;

public class HomeWork {
    public static void main(String[] args) {
        A a = new A();
        a.f1();
    }
}

class A{
    private String name = "hello";

    public void f1(){
        class B{
            private String name = "hjj";
            private final String NAME = "yiyi";
            public void show(){
                System.out.println("NAME= " + NAME + " name = " + name + " 外部类哒name = " + A.this.name);
            }
        }
        B b = new B();
        b.show();
    }

}

案例:

package com.dxl.staticpar;

public interface Vehicles {
    public void work();
}

package com.dxl.staticpar;

public class Horse implements Vehicles{

    @Override
    public void work() {
        System.out.println("使用马作为交通工具===========");
    }
}

package com.dxl.staticpar;

public class Boat implements Vehicles{
    @Override
    public void work() {
        System.out.println("过河的时候使用小船===========");
    }
}

package com.dxl.staticpar;

public class Plane implements Vehicles{
    @Override
    public void work() {
        System.out.println("过火焰山使用飞机=========");
    }
}

package com.dxl.staticpar;

public class VechiclesFactory {
    private static Horse horse = new Horse();

    private VechiclesFactory() {
    }

    public static Horse getHorse(){
//        马儿始终是同一匹马,使用饿汉式模式
//        return new Horse();
        return horse;
    }

    public static Boat getBoat(){
        return new Boat();
    }

    public static Plane getPlane(){
        return new Plane();
    }
}

package com.dxl.staticpar;

public class Person {
    private String name;
    private Vehicles vehicles;

    public Person(String name, Vehicles vehicles) {
        this.name = name;
        this.vehicles = vehicles;
    }

    public void passRiver(){
//        Boat boat = VechiclesFactory.getBoat();
//        boat.work();

        if (!(vehicles instanceof Boat)){
            vehicles = VechiclesFactory.getBoat();
        }
        vehicles.work();
    }

    public void common(){
        if (!(vehicles instanceof Horse)) {
//            多态,向上转型
            vehicles = VechiclesFactory.getHorse();
        }
        vehicles.work();
    }
    public void passMountain(){
        if (!(vehicles instanceof Plane)){
            vehicles = VechiclesFactory.getPlane();
        }
        vehicles.work();
    }
}

package com.dxl.staticpar;

public class HomeWork {
    public static void main(String[] args) {
        Person person = new Person("唐僧", new Horse());
        person.common();
        person.passRiver();
        person.passMountain();
    }
}

成员内部类

package com.dxl.staticpar;

public class Homwork {
    public static void main(String[] args) {
        Car car = new Car(60);
        car.getAir().flow();
    }
}

class Car{
    private double temperature;

    public Car(double temperature) {
        this.temperature = temperature;
    }

    class Air{
        public void flow(){
            if (temperature > 40){
                System.out.println("温度大于40,空调吹冷气!");
            }else if (temperature < 0){
                System.out.println("温度小于0,空调吹暖气!");
            }else{
                System.out.println("正常温度,关闭空调!");
            }
        }
    }

    public Air getAir(){
        return new Air();
    }
}
package com.dxl.staticpar;

public class HomeWork {
    public static void main(String[] args) {
        Color black =Color.BLACK;
        black.show();
//switch后放入枚举对象,在case后放入枚举对象就行
        switch (black){
            case BLACK:
                System.out.println("匹配到黑色!");
                break;
            case RED:
                System.out.println("匹配到红色");
                break;
            case BLUE:
                System.out.println("匹配到蓝色");
                break;
            case GREEN:
                System.out.println("匹配到绿色");
                break;
            case YELLOW:
                System.out.println("匹配到黄色");
                break;
            default:
                System.out.println("没有匹配到颜色");
        }
    }
}
interface IMYInterface{
    public void show();
}

enum Color implements IMYInterface{
    RED(255,0,0),
    BLUE(0,0,255),
    BLACK(0,0,0),
    YELLOW(255,255,0),
    GREEN(0,255,0);

    private int redValue;
    private int greenValue;
    private int blueValue;

    Color(int redValue, int greenValue, int blueValue) {
        this.redValue = redValue;
        this.greenValue = greenValue;
        this.blueValue = blueValue;
    }

    @Override
    public void show() {
        System.out.println("属性值为 " + redValue + "," + greenValue + "," + blueValue);
    }
}

异常处理机制:

package com.dxl.staticpar;

import java.lang.Exception;

public class Exception01 {
    public static void main(String[] args) {
        int num2 = 0;
        int num1 = 23;
        try {
            int res = num1 / num2;
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("程序继续执行!");
    }
}

异常介绍。
●基本概念
Java语言中,将程序执行中发生的不正常情况称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)
执行过程中所发生的异常事件可分为两类

  1. Error(错误):Java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError[栈溢出]和OOM(out of
    memory).Error是严重错误,程序会崩溃。
  2. Exception:其它因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等等,Exception 分为两大类:运行时异常和编译时异常门。
    在这里插入图片描述
    类的异常体系图
    在这里插入图片描述
    异常体系图一览
    异常体系图的小结
    1.异常分为两大类,运行时异常和编译时异常
    2.运行时异常,编译器不要求强制处置的异常。一般是指编程时的
    程序员应该避免其出现的异常。Java.lang.RununeExcepio都是运行时异常
    3.对于运行时异常,可以不作处理,因为这类异常很普遍,若全处理会对程序的可读性和运行效率产生影响
    4.编译时异常,是编译器要求必须处置的异常。

常见的运行时异常
●常见的运行时异常包括

  1. NullPointerException空指针异常
  2. ArithmeticException数学运算异常
  3. ArraylndexOutOfBoundsException数组下标越界异常
  4. ClassCastException类型转换异常
  5. NumberFormatException数字格式不正确异常

编译异常
介绍
编译异常是指在编译期间,就必须处理的异常,否则代码不能通过编译。
常见的编译异常
SQLException//操作数据库时,查询表可能发生异常
IOException//操作文件时,发生的异常
FileNotFoundException //当操作一个不存在的文件时,发生异常
ClassNotFoundException//加载类,而该类不存在时,异常
EOFException/操作文件,到文件未尾,发生异常
lllegalArguementException//参数异常

异常处理
●基本介绍
异常处理就是当异常发生时,对异常处理的方式。
●异常处理的方式

  1. try-catch-finally
    程序员在代码中捕获发生的异常,自行处理
  2. throws
    将发生的异常抛出,交给调用者(方法)来处理,最顶级的处理者就是JVM
    在这里插入图片描述在这里插入图片描述
    package com.dxl.staticpar;

public class Exception02 {
public static void main(String[] args) {
try {
String name = null;
System.out.println(name.length());
} catch (Exception e) {
e.printStackTrace();
}
}
}

try-catch异常处理
try-catch方式处理异常说明
1)Java提供try和catch块来处理异常。try块用于包含可能出错的代码。catch块用于处理try块中发生的异常。可以根据需要在程序中有多个try…catch块。
2)基本语法
try {
//可疑代码
1/将异常生成对应的异常对象,传递给catch块}
catch(异常){
//对异常的处理}
1/如果没有finally,语法可以通过

1)如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch块.
2)如果异常没有发生,则顺序执行try的代码块,不会进入到catch.
3)如果希望不管是否发生异常,都执行某段代码(比如关闭连接,释放资源等)则使用如下代码- finally {}
4)可以有多个catch语句,捕获不同的异常(进行不同的业务处里),要求父类异常在后,子类异常在前,比如(Exception在后,NullPointerException在前),如果发生异常,只会匹配一个catch。

package com.dxl.staticpar;

public class Exception02 {
    public static void main(String[] args) {
        try {
            Person person = new Person();
            person = null;
            System.out.println(person.getName());
            int n1 = 10;
            int n2 = 0;
            int res = n1/n2;
        }catch (NullPointerException e){
            System.out.println(e.getMessage());
        }catch (ArithmeticException e){
            System.out.println(e.getMessage());
        }
        catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
        }
    }
}

class Person{
    private String name = "jaxk";

    public String getName() {
        return name;
    }

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

5)可以进行try-finally 配合使用,这种用法相当于没有捕获异常,因此程序会直接崩掉。应用场景,执行某段代码,不管是否发生异常,都要执行某个操作。
try {
//代码…}
finallyi1/总是执行}

try-catch异常处理
try-catch-finally执行顺序小结
1)如果没有出现异常,则执行try块中所有语句,不执行catch块中语句,如果有finally,最后还需要执行finally里面的语句
2)如果出现异常,则try块中异常发生后,try块剩下的语句不再执行。将执行catch块中的语句,如果有finally,最后还需要执行finally里面的语句!

package com.dxl.staticpar;

import java.util.Scanner;

public class Exception02 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int num = 0;
        String inputStr = "";
        while(true){
            System.out.println("请输入一个整数:");
            inputStr = scanner.next();
            try {
                num = Integer.parseInt(inputStr);
                break;
            } catch (NumberFormatException e) {
                System.out.println("你输入的不是一个整数!");
            }
        }
        System.out.println("输入的值是 num = " + num);
    }
}

throws异常处理
基本介绍
1)如果一个方法((中的语句执行时)可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。
2)在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异
常类型可以是方法中产生的异常类型,也可以是它的父类。

public void f2() throws FileNotFoundException,NullPointerException, ArithmeticException i
//创建了一个文件流对象
//1.这里的异常是一个FileNotFoundException 编译异常//2.使用前面讲过的try-catch-finally
//3.使用throws ,抛出异常,让调用f2方法的调用者(方法)处理
/ /4. throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类//5. throws 关键字后也可以是异常列表,即可以抛出多个异潮|
FileInputStream fis = new FileInputStream(“d: //aa.txt”);
}

throwS异常处理
·注意事项和使用细节
1)对于编译异常,程序中必须处理,比如try-catch 或者throws
2)对于运行时异常,程序中如果没有处理,默认就是throws的方式处理[举例]
3)子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型4)在throws 过程中,如果有方法 try-catch,就相当于处理异常,就可以不必
throws

public static void f4() {
//1.在f4()中调用方法f5()是OK/ /2.原因是f5()抛出的是运行异常
//3.而java中,并不要求程序员显示处理,因为有默认处理机制f5O);
}
public static void f5() throws ArithmeticException {
}

自定义异常
●基本概念
当程序中出现了某些“错误”,但该错误信息并没有在Throwable子类中描述处理,这个时候可以自己设计异常类,用于描述该错误信息。

自定义异常的步骤
1)定义类:自定义异常类名(程序员自己写)继承Exception或RuntimeException
2)如果继承Exception,属于编译异常
3)如果继承RuntimeException,属于运行异常(一般来说,继承RuntimeException)

package com.dxl.staticpar;

public class CustomException {
    public static void main(String[] args) {
        int age = 880;
        if (!(age <= 80 && age >= 18)){
            throw new AgeException("年龄需要在18-80");
        }
        System.out.println("你的年龄范围正确!");
    }
}

//自定义的异常
class AgeException extends RuntimeException{
    public AgeException(String message) {
        super(message);
    }
}

//1.一般情况下,我们白定义异常是继承RuntimeException
//2,即把自定义异常做成运行时异常,好处时,我们可以使用默认的处理机制
在这里插入图片描述
在这里插入图片描述

package com.dxl.staticpar;

public class CustomException {
    public static void main(String[] args) {
        try {
            if (args.length != 2){
                throw new ArrayIndexOutOfBoundsException("参数个数不对");
            }

            int n1 = Integer.parseInt(args[0]);
            int n2 = Integer.parseInt(args[1]);

            double res = cal(n1,n2);

            System.out.println("计算结果是 res = " + res);
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println(e.getMessage());
        }catch (NumberFormatException e){
            System.out.println("参数不是整数!");
        }catch (ArithmeticException e){
            System.out.println("出现除0的异常!");
        }

    }

    public static double cal(int n1, int n2){
        return n1/n2;
    }
}

在这里插入图片描述
包装类
·包装类的分类 Wrapper
1.针对八种基本数据类型相应的引用类型包装类
2.有了类的特点,就可以调用类中的方法。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
包装类
·包装类和基本数据的转换
演示包装类和基本数据类型的相互转换,这里以int和 Integer演示。

  1. jdk5前的手动装箱和拆箱方式,装箱:基本类型->包装类型,反之,拆箱
  2. jdk5 以后(含jdk5)的自动装箱和拆箱方式
    3)自动装箱底层调用的是valueOf方法,比如lnteger.valueOf()
package com.dxl.staticpar;

public class WrapType {
    public static void main(String[] args) {
//        jdk5以前
        int n1 = 100;
//        手动装箱
        Integer integer = new Integer(n1);
        Integer integer1 = Integer.valueOf(n1);
//    手动拆箱
        int i = integer.intValue();

//        jdk5以后自动装箱和拆箱
        int n2 = 200;
//        底层调用的valueOf方法
        Integer integer2 = n2;
        int n3 = integer2;
    }
}

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

package com.dxl.staticpar;

public class WrapperVSString {
    public static void main(String[] args) {
//        包装类==》String

        Integer i = 100;
//        方式1
        String str1 = i + "";

//        方式2
        String s = i.toString();

//        方式3
        String s1 = String.valueOf(i);

//    String==>包装类
//        方式1
        String str4 = "123456";
        Integer i1 = Integer.parseInt(str4);

//    方式2
        Integer integer = new Integer(str4);
        
    }
}

在这里插入图片描述
在这里插入图片描述
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
在这里插入图片描述
在这里插入图片描述
String类
String类的理解和创建对象

  1. String对象用于保存字符串,也就是一组字符序列
    2)字符串常量对象是用双引号括起的字符序列。例如:“你好"、“12.97”."boy"等。
    3)字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占杯个字节。
  2. String类较常用构造器(其它看手册):
    String s1 = new String0;1/
    String s2 = new String(String original);
    String s3 = new String(chara);
    String s4 = new String(char[] a,int startlndex,int count)·
    说明:
    在这里插入图片描述在这里插入图片描述
    在这里插入图片描述
package com.dxl.staticpar;

public class String_ {
    public static void main(String[] args) {
        String name = "jack";
        name = "fjj";
        final char[] value = {'a','b','c'};
        char[] v = {'f','l','e'};
        value[0] = 'l';
//        value = v;不可以,不能修改value的地址
    }
}

String类
两种创建String对象的区别
方式一:直接赋值 String s =“hhuu”;
方式二:调用构造器 String s2 = new String(“hhuu”);
1.方式一:先从常量池查看是否有"hhuu”数据空间,如果有,直接指向;如果
没有则重新创建,然后指向。S最终指向的是常量池的空间地址
2.方式二:先在堆中创建空间,里面维护了value属性,指向常量池的hsp空间。如果常量池没有"hhuu",重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. String是一个final类,代表不可变的字符序列
    2)字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的.
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    String类的常见方法
    ●说明
    String类是保存字符串常量的。每次更新都需要重新开辟空间,效率较低,因此java设计者还提供了StringBuilder和 StringBuffer来增强String的功能。并提高效率。
    StringBuilder 和StringBuffer]
    String s = new String(“”);
    for( int i = 0; i< 80000; i++){
    S+=“hello”;
    }

String类的常见方法
String类的常见方法应用实例1
equals //区分大小写,判断内容是否相等
equalslgnoreCase//忽略大小写的判断内容是否相等
length/获取字符的个数,字符串的长度
indexOf//获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回-1
lastIndexOf //获取字符在字符串中最后1次出现的索引,索引从0开始,如找不到,返回-1
substring //截取指定范围的子串
trim//去前后空格
charAt:获取某索引处的字符,注意不能使用Str[index]这种方式.
String str = "hello” ;
//str[0]不对
//str.charAt(O)=>h

package com.dxl.staticpar;

public class String_ {
    public static void main(String[] args) {
//       1.equals 区分大小写,比较内容是否相同
        String str1 = "hello";
       String str2 = "Hello";
        System.out.println(str1.equals(str2));
//        2.equalsIgnoreCase 忽略大小写判断内容是否相同
        String username = "john";
        if("john".equalsIgnoreCase(username)){
            System.out.println("Success");
        }else{
            System.out.println("Fail");
        }

//        3.length 获取字符的个数,字符串的长度
        System.out.println("呀呀呀".length());
// 4.index0f 获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到,返回-1
        String s1 = "hdfjjf$jfkk";
        int index = s1.indexOf('$');
        System.out.println(index);
        // 5.lastIndexOf 获取字符在字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1
        s1 = "jfdjhhfa@@@jjk@";
        index = s1.lastIndexOf('@');
        System.out.println(index);
//      6.substring截取指定范围的子串
        String name = "hello,张三";
        System.out.println(name.substring(6));
        System.out.println(name.substring(0,3));

    }
}

String类的常见方法
String类的常见方法应用实例2
第二组String相关的方法:
toUpperCase
toLowerCase
concat
replace 替换字符串中的字符
split分割字符串,对于某些分割字符,我们需要转义比如|等
compareTp //比较两个字符串的大小
toCharArray //转换成字符数组
format //格式字符串,%s字符串%c字符%d整型%.2f 浮点型

package com.dxl.staticpar;

public class String_ {
    public static void main(String[] args) {
//        1.toUpperCase 转换成大写
        String s = "hoLLo";
        System.out.println(s.toUpperCase() );
//  2.toLowerCase
        System.out.println(s.toLowerCase());
//        3.concat拼接字符串
        String s1 = "宝玉";
        s1 = s1.concat("林黛玉").concat("薛宝钗").concat("一起");
        System.out.println(s1);
//        4.replace 替换字符串中的字符
        s1 = "hahhahhyyuutey";
        String s11 = s1.replace('h','o');
        System.out.println(s11);
        System.out.println(s1);//本身s1是不会变的
//        5.split 分割字符串,对于某些分割字符,我们需要转移| \\等
        String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        String[] split = poem.split(",");
        poem = "E:\\aaa\\bbb";
//在对字符串进行分割时,如果有特殊字符,需要加入转义字符\
        split = poem.split("\\\\");
        for (int i = 0; i < split.length;i ++){
            System.out.println(split[i]);
        }
//        6.toCharArray 转成字符数组
        s = "happy";
        char[] chs = s.toCharArray();
        for (int i = 0 ; i < chs.length; i ++){
            System.out.println(chs[i]);
        }
//        7.compareTo 比较两个字符串的大小,如果前者大,则返回正数,后者大,则返回负数,如果相等,返回0
//        (1)如果长度相同,并且每个字符也相同,就返回0
//        (2)如果长度相同或者不相同,但是在进行比较时,可以区分大小
//        就返回 if (c1 != c2){
//            return c1 - c2;
//        }
//        (3)如果前面的部分都相同,就返回 str1.len - str2.len

        String a = "jchn";
        String b = "jack";
        System.out.println(a.compareTo(b));//'c' - 'a' = 2
//        8.format格式字符串
//        %S字符串%c字符%d整型%.2f 浮点型
        String name = "john";
        int age = 10;
        double score = 93.3/3;
        char gender = '男';
        String info = "我的名字:" + name + "年龄:" + age + "成绩:" + score + "性别: " + gender;
        info = String.format("我的名字:%s年龄:%d成绩:%.2f性别: %c",name,age,score,gender);
        System.out.println(info);
    }
}

StringButter类
●基本介绍·
StringBuffer01.java
java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删。很多方法与String相同,但StringBuffer是可变长度的。
String Buffer是一个容器。
//1.StringBuffer的直接父类是 AbstractStringBuilder
//2. StringBuffer实现了 Serializable,即StringBuffer的对象可以串行化
//3.在父类中 AbstractStringBuilder有属性 char[] value,不是final,该value 数组存放字符串内容,引出存放在堆中的
//4. StringBuffer是一个 final类,不能被继承
//5.因为StringBuffer字符内容是存在 char[] value,所有在变化(增加/删除)l/ 不用每次都更换地址(即不是每次创建新对象),所以效率高于String

String VS StringBuffer

  1. String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低//private final char value[];
  2. StringBuffer保存的是字符串变量,里面的值可以更改,每次
    StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高
    //char[] value;//这个放在堆.
    在这里插入图片描述
    在这里插入图片描述
    String和StringBuffer之间的相互转换
package com.dxl.staticpar;

public class StringBuffer01 {
    public static void main(String[] args) {
//        String转成StringBuffer
        String str = "hello tom";
//        方式一
//        返回的才是StringBuffer对象,对str本身没有影响
        StringBuffer stringBuffer = new StringBuffer(str);
//        方式二
        StringBuffer stringBuffer1 = new StringBuffer();
        stringBuffer1 = stringBuffer1.append(str);

//        StringBuffer ==》 String
        StringBuffer ainaini = new StringBuffer("ainaini");
//        方式一:使用提供的toString方法
        String s = ainaini.toString();
//        方式二:
        String s1 = new String(ainaini);
        

    }
}

StringBuffer类常见方法
1)增append
2)delete(start,end)
3)改replace(start,end,string)//将
start----end间的内容替换掉,不含end
4)查indexOf //查找子串在字符串第1
次出现的索引,如果找不到返回-1
5)插insert
6)获取长度length
在这里插入图片描述
在这里插入图片描述

package com.dxl.staticpar;

public class StringBuffer01 {
    public static void main(String[] args) {
        String price = "12345689.59";
        StringBuffer sb = new StringBuffer(price);
        for (int i = sb.lastIndexOf(".") - 3; i >0; i -= 3){
            sb = sb.insert(i, ",");
        }
        System.out.println(sb);
    }
}

StringBuilder类
基本介绍
1)一个可变的字符序列。此类提供一个与StringBuffer兼容的API,但不保证同
步。(StringBuilder不是线程安全的)该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer 要快。
2)在 StringBuilder上的主要操作是 append和insert方法,可重载这些方法,以接受任意类型的数据。
StringBuilder常用方法
StringBuilder 和 StringBuffer均代表可变的字符序列,方法是一样的,所以使用和StringBuffer一样.
1.StringBuilder是final,不能被继承
2.继承了AbstractStringBuilder,属性char[] value,内容存到value
3.实现了Serializable接口,序列化(所谓序列化即可以保存类型和数据本身)
在这里插入图片描述
String、StringBuffer 和StringBuilder的比较

  1. StringBuilder和 StringBuffer非常类似,均代表可变的字符序列,而且方法也一样
  2. String:不可变字符序列,效率低,但是复用率高。
  3. StringBuffer:可变字符序列、效率较高(增删)、线程安全,看源码4)StringBuilder:可变字符序列、效率最高、线程不安全
  4. String使用注意说明:
    string s=“a”; 1/创建了一个字符串
    s += “b”;//实际上原来的"a"字符串对象已经丢弃了,现在又产生了一个字符串s+“b”(也就是"ab”)。如果多次执行这些改变串内容的操作,会导致大量副本字符串对象存留在内存中,降低效率。如果这样的操作放到循环中,会极大影响程序的性能=>结论:如果我们对String做大量修改,不要使用String
package com.dxl.staticpar;

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

       long startTime = 0L;
       long endTime = 0L;
        StringBuffer stringBuffer = new StringBuffer("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间:" + (endTime - startTime));

        StringBuilder stringBuilder = new StringBuilder("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            stringBuilder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间:" + (endTime - startTime));

        String text = "";
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {
            text = text + i;
        }
        endTime = System.currentTimeMillis();
        System.out.println("String的执行时间:" + (endTime - startTime));

    }
}

效率:StringBuilder > StringBuffer > String
String、StringBuffer 和StringBuilder的选择
使用的原则
1.如果字符串存在大量的修改操作,一般使用 StringBuffer 或StringBuilder
2.如果字符串存在大量的修改操作,并在单线程的情况,使用 StringBuilder
3.如果字符串存在大量的修改操作,并在多线程的情况,使用 StringBuffer
4.如果我们字符串很少修改,被多个对象引用,使用String.比如配置信息等StringBuilder 的方法使用和 StringBuffer 一样,不再说.

Math类

●基本介绍
Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。
在这里插入图片描述
Arrays类
●Arrays类常见方法应用案例
Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)。1) toString返回数组的字符串形式
Arrays.toString(arr)
2) sort排序(自然排序和定制排序)Integer arr[l] ={1, -1,7,0,89];3) 3)binarySearch 通过二分搜索法进行查找,要求必须排好序
int index = Arrays.binarySearch(arr, 3);
4) copyOf 数组元素的复制
lnteger[] newArr = Arrays.copyOf(arr, arr.length);
5) fill 数组元素的填充
Integer[] num = new Integer[1{9,3,23;Arrays.fill(num, 99);
6) equals 比较两个数组元素内容是否完全一致boolean equals = Arrays.equals(arr, arr2);
7)asList 将一组值,转换成list
List asList = Arrays.asList(2,3,4.5.6,1);System.out.println(“asList=” + asList);

package com.dxl.staticpar;

import java.util.Arrays;
import java.util.Comparator;

public class StringBuffer01 {
    public static void main(String[] args) {
        Integer[] integers = {1,2,5};
//        for (int i = 0; i < integers.length; i++) {
//            System.out.println(integers[i]);
//        }
//        直接使用toString来显示数组信息
//        System.out.println(Arrays.toString(integers));
//          sort的使用
//1.可以直接使用冒泡排序,也可以直接使用Arrays提供的sort方法排序
// 2.因为数组是引用类型,所以通过sort排序后,会直接影响到实参arr
// 3. sort重载的,也可以通过传入一个接口 Comparator实现定制排序
        //4.调用定制排序时,传入两个参数〔1)排序的数组 arr
        //(2)实现了Comparator接口的匿名内部类,要求实现compare方法
//接口编程
        Integer arr[] = {1,-1,4,5,0,89};
//        Arrays.sort(arr);默认排序
//        定制排序
        Arrays.sort(arr, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer) o1;
                Integer i2 = (Integer) o2
                return i2 - i1;
            }
        });
        System.out.println("================");
        System.out.println(Arrays.toString(arr));
    }
}

package com.dxl.staticpar;

import java.util.Comparator;

public class StringBuffer01 {
    public static void main(String[] args) {
        int[] arr = {1, -1,2 ,8 ,36};
        bubble02(arr, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                int i1 = (Integer)o1;
                int i2 = (Integer)o2;
                return i2 - i1;
            }
        });
    }

    //        冒泡 + 定制
        public static void bubble02(int[] arr, Comparator c){
        int temp = 0;
            for (int i = 0; i < arr.length - 1; i++) {
                for (int j = 0; j < arr.length-1 - i; j++) {
                    if (c.compare(arr[j],arr[j + 1] )> 0){
                        temp = arr[j];
                        arr[j ] = arr[j+1];
                        arr[j + 1] = temp;
                    }
                }
            }
        }
}

package com.dxl.staticpar;

import java.util.Arrays;
import java.util.List;

public class StringBuffer01 {
    public static void main(String[] args) {
        int[] arr = {1, -1, 2, 8, 36};
//        二分查找要求数组是有序的
        //1.使用 binarySearch二叉查找
//2.要求该数组是有序的。如果该数组是无序的,不能使用binarySearch
//3.如果数组中不存在该元素,就返回return -(low + 1);
//  key not found.

        int index = Arrays.binarySearch(arr,1);
       System.out.println("index = "+index);

//       数组复制
        //1.从 arr数组中,拷贝 arr.length个元素到newArr数组中
        // 2.如果拷贝的长度> arr.length就在新数组的后面增加l null
        // 3.如果拷贝长度<0就抛出异常NegativeArraySizeException
        // 4。该方法的底层使用的是 System. arraycopy )

        int[] newArr =Arrays.copyOf(arr,arr.length + 1);
        System.out.println(Arrays.toString(newArr));

        //1.使用99去填充num数组,可以理解成是替换原理的元素
        Integer[] num = new Integer[]{8,9,5};
        Arrays.fill(num,99);
        System.out.println(Arrays.toString(num));

        //1.如果arr和 arr2数组的元素一样,则方法true;
        // 2.如果不是完全一样,就返回 false
        Integer[] arr2 = new Integer[]{5,8,9};
        Integer[] arr1 = new Integer[]{5,8,9};
        boolean equals = Arrays.equals(arr1, arr2);
        System.out.println( "equals=" +equals);

        //1. asList方法,会将〔2,3,4,5,6,1)数据转成一个List集合
        // 2.返回的 asList 编译类型 List(接口)
//3. asList运行类型java.util.Arrays#ArrayList,是Arrays类的
        //静态内部类 private static class ArrayList<E>
        // extends AbstractList<E>
        //implements RandomAccess, java.io.Serializable
List asList = Arrays.asList(2,3,4,5,6,1);
        System.out.println("asList=" + asList);
        System.out.println("asList的运行类型" +asList.getClass());


    }
}
package com.dxl.staticpar;

import java.util.Arrays;
import java.util.Comparator;

public class ArrayExercise {
    public static void main(String[] args) {
        Book[] books = new Book[4];
        books[0] = new Book("红楼梦",100);
        books[1] = new Book("金瓶梅新",90);
        books[2] = new Book("青年文摘20年",5);
        books[3] = new Book("java",20);

//        价格从小到大
//        Arrays.sort(books, new Comparator() {
//            @Override
//            public int compare(Object o1, Object o2) {
//                Book book1 = (Book)o1;
//                Book book2 = (Book) o2;
//                double priceVal = book2.getPrice() - book1.getPrice();
//                if (priceVal > 0){
//                    return -1;
//                }else if(priceVal < 0){
//                    return 1;
//                }else{
//                    return 0;
//                }
//            }
//        });

//书名长度排序
        Arrays.sort(books, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Book book1 = (Book)o1;
                Book book2 = (Book) o2;
                    return book1.getName().length() - book2.getName().length();
            }
        });

        System.out.println(Arrays.toString(books));
    }
}

class Book{
    private String name;
    private double price;

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

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

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

System类
System类常见方法和案例

  1. exit退出当前程序
  2. arraycopy :复制数组元素,比较适合底层调用,一般使用Arrays.copyOf完成复制数组.
    int[] src={1,2,3];
    int[ dest = new int[3];
    System.arraycopy(src, 0, dest, 0, 3);
  3. currentTimeMillens:返回当前时间距离1970-1-1的毫秒数4) gc:运行垃圾回收机制System.gc(;
    在这里插入图片描述
package com.dxl.staticpar;

import java.util.Arrays;

public class SystemEx {
    public static void main(String[] args) {
//        System.out.println("ok1");
//        System.exit(0);//0表示正常退出的值
//        System.out.println("ok2");

        int[] src = {1,2,5};
        int[] test = new int[3];
        System.arraycopy(src,0,test,0,src.length);
        System.out.println(test[0] +"" + test[1] + test[2]);
        System.out.println("test=" + Arrays.toString(test));

        System.out.println(System.currentTimeMillis());
        
    }
}

Biglnteger和BigDecimal类
Biglnteger和BigDecimal常见方法

  1. add 加
  2. subtract减
  3. multiply乘
  4. divide除
    Biglnteger和BigDecimal类
    Biglnteger和BigDecimal介绍
    应用场景:
  5. Biglnteger适合保存比较大的整型
  6. BigDecimal适合保存精度更高的浮点型(小数)
package com.dxl.staticpar;

import java.math.BigDecimal;
import java.math.BigInteger;

public class SystemEx {
    public static void main(String[] args) {
        BigInteger bigInteger = new BigInteger("145555555555551587456654");
        BigInteger bigInteger1 = new BigInteger("100");
        System.out.println(bigInteger);
        BigInteger add = bigInteger.add(bigInteger1);
        System.out.println(add);
//        减
        BigInteger substract = bigInteger.subtract(bigInteger1);
        System.out.println(substract);

        BigDecimal bigDecimal = new BigDecimal("48512.524785654478562145631278893652234557856622");
        BigDecimal bigDecimal1 = new BigDecimal("125.654");
        System.out.println(bigDecimal.add(bigDecimal1));
        System.out.println(bigDecimal.divide(bigDecimal1,BigDecimal.ROUND_CEILING));//除法可能抛异常,除不尽
    }
}

第一代日期类

  1. Date:精确到毫秒,代表特定的瞬间
  2. SimpleDateFormat:格式和解析日期的类
    SimpleDateFormat格式化和解析日期的具体类。它允许进行格式化(日期->文本)、解析(文本->日期)和规范化.
package com.dxl.staticpar;

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

public class SystemEx {
    public static void main(String[] args) throws ParseException {
        Date date = new Date();
        System.out.println("当前日期= " + date);
        Date date1 = new Date(1248766656);
        System.out.println(date1.getTime());

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
        String format = simpleDateFormat.format(date);
        System.out.println(format);

        String s = "2022年07月10日 05:19:12 星期日";
        Date parse = simpleDateFormat.parse(s);
        System.out.println(parse);
        System.out.println("parse=" + simpleDateFormat.format(parse));
    }
}

日期类。
第二代日期类
1)第二代日期类,主要就是Calendar类(日历)。
public abstract class Calendar extends Object implements Serializable,Cloneable, Comparable
2) Calendar类是一个抽象类,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR 等白历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。

package com.dxl.staticpar;

import java.util.Calendar;

public class SystemEx {
    public static void main(String[] args) {
        //1. Calendar是一个抽象类,并且构造器是private
        // 2.可以通过 getInstance()来获取实例
//3.提供大量的方法和字段提供给程序员
//4. calendar没有提供对应的格式化的类,因此需要程序员自己组合来输出
//5.如果我们需要按照24小时进制来获取时间,Calendar . HOUR '==改成=> Calendar.HOUR_OF_DAYl
        Calendar c = Calendar.getInstance();
        System.out.println(c);
        //2.获取日历对象的某个目历字段
        System.out.println("年:" +c.get(Calendar. YEAR));
//这里为什么要 +1,因为Calendar返回月时候,是按照0开始编号
        System.out.println("月:" + (c.get(Calendar. MONTH) +1));
        System.out.println("日:" +c.get(Calendar.DAY_OF_MONTH));
        System.out.println("小时:" +c.get(Calendar . HOUR));
        System.out.println("小时:" +c.get(Calendar . HOUR_OF_DAY));
        System.out.println("分钟:" +c.get(Calendar.MINUTE));
        System.out.println("秒:" +c.get(Calendar . SECOND));
        //Calender没有专门的格式化方法,所以需要程序员自己来组合显示
        System.out.println(c.get(Calendar.YEAR) + "年");
    }
}

日期类。
第三代日期类
前面两代日期类的不足分析
JDK 1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar也存在问题是:
1)可变性:像日期和时间这样的类应该是不可变的。
2)偏移性:Date中的年份是从1900开始的,而月份都从0开始。3)格式化:格式化只对Date有用,Calendar则不行。
4)此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)。

第三代日期类常见方法

  1. LocalDate(日期/年月日)、LocalTime(时间/时分秒)、LocalDateTime(日期时电/年月日时分秒)JDK8加入
    ·LocalDate只包含日期,可以获取日期字段
    LocalTime只包含时间,可以获取时间字段
    LocalDateTime包含日期+时间,可以获取日期和时间字段:
    LocalDateTime ldt = LocalDateTime.now(); //LocalDate.now();//LocalTime.now()
    System.out.println(ldt);
    ldt.getYear();ldt.getMonthValue();ldt.getMonth();ldt.getDayOfMonth();
    ldt.getHour();ldt.getMinute();ldt.getSecond();

  2. DateTimeFormatter格式日期类类似于SimpleDateFormat
    DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式);
    String str = dtf.format(日期对象);
    案例演示:
    LocalDateTime ldt = LocalDateTime.now0;
    //关于DateTimeFormatter 的各个格式参数,需要看jdk8的文档.
    DateTimeFormatter dtf = DateTimeFormatter. ofPattern(“yyy年MM月dd日HIHJT时mm分钟ss秒”);
    String strDate = dtf.format(ldt);

package com.dxl.staticpar;

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

public class LocalDate_ {
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.now(); //LocalDate.now();//LocalTime.now()
        System.out.println(ldt);
        System.out.println("年" + ldt.getYear());
        ldt.getMonthValue();
        ldt.getMonth();
        System.out.println("月" + ldt.getMonthValue());
        ldt.getDayOfMonth();
        ldt.getHour();
        ldt.getMinute();
        ldt.getSecond();

        LocalDate now = LocalDate.now();

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月");
        String format = dtf.format(ldt);
        System.out.println(format);
    }
}

  1. Instant时间戳类似于Date
    提供了一系列和Date类转换的方式lnstant—->Date:
    Date date = Date.from(instant);Date->lnstant:
    lnstant instant = date.tolnstant(;案例演示:
    lnstant now= Instant.nowO;System.out.println(now);Date date = Date.from(now);lnstant instant = date.tolnstant(;
package com.dxl.staticpar;

import java.time.Instant;
import java.util.Date;

public class LocalDate_ {
    public static void main(String[] args) {
//        时间戳   通过静态方法now()获取表示当前时间戳的对象
        Instant now = Instant.now();
        System.out.println(now);
        Date date = Date.from(now);//通过from方法转换成date
        Instant instant = date.toInstant();//通过date的toInstant() 可以把 date转成Instant对象
    }
}

4)第三代日期类更多方法- LocalDateTime类
MonthDay类:检查重复事件·是否是闰年
·增加日期的某个部分
·使用plus方法测试增加时间的某个部分
·使用minus方法测试查看一年前和一年后的日期
在这里插入图片描述
编程思想,写出对的情况然后取反

package com.dxl.staticpar;

public class Homework {
    public static void main(String[] args) {
       String str = "fekjfjkg";
        try {
            str = reverse(str,2,6);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return;
        }
        System.out.println(str);
    }

    public static String reverse(String str, int start, int end){
        if (!(str != null && start >= 0 && end <= str.length())){
            throw new RuntimeException("参数不正确");
        }

        char[] chars = str.toCharArray();
        char temp = ' ';
        for (int i = start, j = end; i < j; i++, j--) {
            temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
        }
        return new String(chars);
    }
}

package com.dxl.staticpar;

public class HomeWork {
    public static void main(String[] args) {
        String name = "jack";
        String pwd = "124452";
        String email = "jack@sohu.com";

        try {
            userRegist(name,pwd,email);
            System.out.println("恭喜你注册成功!");
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    public static void userRegist(String name,String pwd,String email){

        if (!(name != null && pwd != null && email != null)){
            throw new RuntimeException("恭喜你,注册成功!");
        }
        int userLength = name.length();
        if (!(userLength >= 2 && userLength <= 4)){
            throw  new RuntimeException("用户名长度为2或3或4");
        }

        if (!(pwd.length() == 6 && isDigital(pwd))){
            throw new RuntimeException("密码长度不对!");
        }

        int i = email.indexOf('@');
        int j = email.indexOf('.');
        if (!(i > 0 && j >i)){
            throw new RuntimeException("邮箱中包含@!");
        }

    }

    public static boolean isDigital(String str){
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] < '0' || chars[i] > '9'){
                return false;
            }
        }
        return true;
    }
}
package com.dxl.staticpar;

public class HomeWork {
    public static void main(String[] args) {
        String name = "Huan shun Ping";
        printName(name);
    }

    public static void printName(String str){
        if (str == null){
            System.out.println("str 不能为空");
            return;
        }

        String[] names = str.split(" ");
        if (!(names.length == 3)){
            System.out.println("输入的字符串格式不对!");
            return;
        }
        System.out.println(String.format("%s,%s .%c",names[2],names[0],names[1].toUpperCase().charAt(0)));
    }
}

在这里插入图片描述

package com.dxl.staticpar;

public class HomeWork {
    public static void main(String[] args){
        String str = "kjdfsjjgj PPJJ 154566";
        countStr(str);
    }

    public static void countStr(String str){
        if (str == null){
            System.out.println("输入不能为空!");
            return;
        }

        int strLen = str.length();
        int numCount = 0;
        int lowerCount = 0;
        int upperCount = 0;
        int otherCount = 0;
        for (int i =0; i < strLen; i++){
            if (str.charAt(i) >= '0' && str.charAt(i) <= '9'){
                numCount ++;
            }else if (str.charAt(i) >= 'a' && str.charAt(i) <= 'z'){
                lowerCount ++;
            }else if (str.charAt(i) >= 'A' && str.charAt(i) <= 'Z'){
                upperCount ++;
            }else{
                otherCount ++;
            }
        }
        System.out.println("数字有:" + numCount);
        System.out.println("小写字母有:" + lowerCount);
        System.out.println("大写字母有:" + upperCount);
        System.out.println("其他字符有:" + otherCount);
    }
}

集合的理解和好处
前面我们保存多个数据使用的是数组,那么数组有不足的地方。
●数组
1)长度开始时必须指定,而且一旦指定,不能更改
2)保存的必须为同一类型的元素
3)使用数组进行增加元素
Person[] pers = new Person[1];
pers[0]=new Person();
//增加新的Person对象?
Person[] pers2 = new Person[pers.length+1];//新创建数组
for(){}//拷贝pers数组的元素到pers2
pers2[pers2.length-1]=new Person()😕/添加新的对象

●集合
1)可以动态保存任意多个对象,使用比较方便!
2)提供了一系列方便的操作对象的方法:add、remove、set、 get等
3)使用集合添加删除新元素的示意代码-简洁了

集合的框架体系
Java的集合类很多,主要分为两大类,如图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
//1.集合主要是两组(单列集合,双列集合)
//2. Collection接口有两个重要的子接口 List Set,他们的实现子类都是单列集合
//3. Map接口的实现子类是双列集合,存放的 K-V

Collection接口和常用方法
●Collection接口实现类的特点
public interface Collection extends Iterable
1)collection实现子类可以存放多个元素,每个元素可以是Object
2)有些Collection的实现类,可以存放重复的元素,有些不可以
3)有些Collection的实现类,有些是有序的(List),有些不是有序(Set)
4) Collection接口没有直接的实现子类,是通过它的子接口Set 和 List来实现的

Collection接口常用方法,以实现子类ArrayList

  1. add:添加单个元素
    2)remove:删除指定元素
  2. contains:查找元素是否存在
  3. size:获取元素个数
  4. isEmpty:判断是否为空
  5. clear:清空
  6. addAll:添加多个元素
  7. containsAll:查找多个元素是否都存在
  8. removeAll:删除多个元素
package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.HashMap;

public class Collwction_ {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add("jack");
        arrayList.add("ton");
        arrayList.add(true);
        System.out.println("list= " + arrayList);
        arrayList.remove(0);
        System.out.println("list = " + arrayList);
        arrayList.remove(true);
        System.out.println("list= " + arrayList);
//        contains:查找元素是否存在
        System.out.println(arrayList.contains("jack"));
//        size:获取元素个数
        System.out.println(arrayList.size());
        System.out.println(arrayList.isEmpty());
        arrayList.clear();
        System.out.println("list = " + arrayList);
        ArrayList list = new ArrayList();
        list.add("红楼梦");
        list.add("三国演义");
        arrayList.addAll(list);
        System.out.println("arrayList = " + arrayList);
        arrayList.add("聊斋志异");
        arrayList.removeAll(list);
        System.out.println("arrayList = " + arrayList);

        HashMap hashMap  = new HashMap();
        hashMap.put("N01","北京");
    }
}

Collection接口和常用方法
Collection接口遍历元素方式1-使用lterator(送代器)基本介绍
在这里插入图片描述

  1. Iterator对象称为迭代器,主要用于遍历Collection集合中的元素。
    2)所有实现了Collection接口的集合类都有一个iterator()方法,用以返回
    一个实现了lterator接口的对象,即可以返回一个迭代器。
  2. Iterator的结构.[图:]
  3. Iterator仅用于遍历集合,lterator本身并不存放对象。

迭代器的执行原理
lterator iterator = coll.iterator(0);1/得到一个集合的迭代器
//hasNext()判断是否还有下一个元素while(iterator.hasNext()){
/next(:①指针下移②将下移以后集合位置上的元素返回
System.out.println(iterator.next));}

package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Collwction_ {
    public static void main(String[] args) {
        @SuppressWarnings({"all"})
        Collection col = new ArrayList();

        col.add(new Book("红楼梦","曹雪芹",6.54));
        col.add(new Book("小李飞刀","古龙",23.2));
        col.add(new Book("红楼梦","曹雪晴",15.3));

        Iterator iterator = col.iterator();
        while(iterator.hasNext()){
            Object next = iterator.next();
            System.out.println("next= " + next);
        }

//        迭代器第二次重置
        Iterator iterator1 = col.iterator();
        while (iterator1.hasNext()) {
            Object next = iterator1.next();
            System.out.println("next= " + next);
        }
    }
}
class Book{
    private String name;
    private String author;
    private double price;

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

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }
}

Collection接口和常用方法
Collection接口遍历对象方式2-for循环增强.
增强for循环,可以代替iterator迭代器,特点:增强for就是简化版的iterator,本质一样。只能用于遮历集合或数组。
基本语法
for(元素类型元素名:集合名或数组名){
访问元素
}
在这里插入图片描述

package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.Collection;

public class Collwction_ {
    public static void main(String[] args) {
        @SuppressWarnings({"all"})
        Collection col = new ArrayList();

        col.add(new Book("红楼梦","曹雪芹",6.54));
        col.add(new Book("小李飞刀","古龙",23.2));
        col.add(new Book("红楼梦","曹雪晴",15.3));

//        增强for循环
        for (Object book:col){
            System.out.println("book= " +book);
        }

        //1.使用增强for,在Collection集合
        // 2.增强for,底层仍然是迭代器
        //3.增强for可以理解成简化版的迭代器
        int[] nums = {1,8,5,10};
        for (int i: nums){
            System.out.println("i = " + i);
        }

    }
}
class Book{
    private String name;
    private String author;
    private double price;

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

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + author + '\'' +
                ", price=" + price +
                '}';
    }
} 
package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class Collwction_ {
    @SuppressWarnings({"all"})
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new Dog("小黑",5));
        list.add(new Dog("小红",3));
        list.add(new Dog("小明",6));

        for (Object dog:list){
            System.out.println("dog = " + dog);
        }

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("dog = " + next);
        }
    }
}

class Dog{
    private String name;
    private int age;

    public Dog(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 String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

List接口和常用方法
List接口基本介绍
List接口是 Collection 接口的子接口

  1. List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复
  2. List集合中的每个元素都有其对应的顺序索引,即支持索引。
  3. List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
    4)JDK API中List接口的实现类有:
    常用的有:ArrayList、LinkedList和Vector。
package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings({"all"})
public class List_ {
    public static void main(String[] args) {
        //1.List集合类中元素有序(即添加顺序和取出顺序一致)、且可重复
        List list = new ArrayList();
        list.add("jack");
        list.add("tom");
        list.add("jjhh");
        list.add("mary");
        System.out.println("list = " + list);
        //2. List集合中的每个元素都有其对应的顺序索引,即支持索引
//        0bject get(int index):获取指定index位置的元素
        System.out.println(list.get(2));
        list.add(1,"jjdhe");
        System.out.println("list = " + list);

        List list1 = new ArrayList();
        list1.add("张三丰");
        list1.add("韩语");
        list.addAll(1,list1);
        System.out.println("list= " + list);
//        int index0f(0bject obj):返回obj在集合中首次出现的位置
        System.out.println(list.indexOf("tom"));

//        int lastIndexOf(0bject obj):返回obj在当前集合中末次出现的位置
        System.out.println(list.lastIndexOf("tom"));
//        0bject remove(int index):移除指定index位置的元素,并返回此元素
        list.remove(0);
        System.out.println("list = " + list);
//        Object set(int index,0bject ele):设置指定index位置的元素为ele ,相当于是替换。
        list.set(1, "玛丽");
        System.out.println("list = " + list);
//        List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
        List list2 = list.subList(0,2);
        System.out.println("list2 = " + list2);
    }
}

在这里插入图片描述

package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@SuppressWarnings({"all"})
public class List_ {
    public static void main(String[] args) {
        List list = new ArrayList();
        for (int i = 0; i < 12; i ++){
            list.add("hello " + i);
        }
        System.out.println("list = " + list);

        list.add(1,"jdjhd");
        System.out.println("list = " + list);

        System.out.println("第五个元素 = " + list.get(4));

        list.remove(5);
        System.out.println("list = " + list);

        list.set(6,"三国演义");
        System.out.println("list = " + list);

        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("list = " + list);
        }
    }
}

package com.dxl.staticpar;

import java.util.LinkedList;
import java.util.List;

@SuppressWarnings({"all"})
public class List_ {
    public static void main(String[] args) {
//        List list = new ArrayList();
//        List list = new Vector();
        List list = new LinkedList();
        list.add(new Book("红楼梦","曹雪芹",45.6));
        list.add(new Book("西游记","吴承恩",12.3));
        list.add(new Book("三国演义","罗贯中",15.6));
        list.add(new Book("水浒传","施耐庵",45.78));

        for(Object o: list){
            System.out.println(o);
        }

//        冒泡排序
        sort(list);
        System.out.println("=====排序后====");
        for (Object o : list){
            System.out.println(o);
        }

    }

    //        对集合进行排序
    public static void sort(List list){

        for (int i = 0; i < list.size() - 1; i ++ ){
            for (int j = 0; j < list.size() - 1 - i; j ++){
                Book book1 = (Book) list.get(j);
                Book book2 = (Book) list.get(j + 1);
                if (book1.getPrice() > book2.getPrice()){
                    list.set(j, book2);
                    list.set(j+1,book1);
                }
            }
        }
    }
}

class Book{
    private String name;
    private String author;
    private double price;

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

    public String getName() {
        return name;
    }

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

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "名称:" + name + '\t' +
                "作者:" + author + '\t' +
                "价格:" + price;
    }
}

1)permits all elements, including null ,ArrayList可以加入nulL,并且多个
2) ArrayList是由数组来实现数据存储的
3)ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高),在多线程情况下,不建议使用ArrayList

package com.dxl.staticpar;

import java.util.ArrayList;

public class ArrayListDetail {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(null);
        arrayList.add("jack");
        System.out.println(arrayList);//[null, jack]
    }
}

ArrayList底层结构和源码分析

  1. ArrayList中维护了一个Object类型的数组elementData.
    transient Object[] elementData;
    transient表示瞬间的,短暂的,该属性不会被序列化
    2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。
    3)如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
    在这里插入图片描述
package com.dxl.staticpar;

import java.util.ArrayList;

public class ArrayListDetail {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();

        for (int i = 0; i <= 10; i++) {
            arrayList.add(i);
        }

        for (int i = 10; i <= 20; i++) {
            arrayList.add(i);
        }

        arrayList.add(null);
        arrayList.add("jack");
        System.out.println(arrayList);//[null, jack]
    }
}

在这里插入图片描述
Vector底层结构和源码剖析
Vector的基本介绍

  1. Vector类的定义说明
    在这里插入图片描述
  2. Vector底层也是一个对象数组protected Object[] elementData;
  3. Vector 是线程同步的,即线程安全, Vector类的操作方法带有synchronized
    在这里插入图片描述
    4)在开发中,需要线程同步安全时,考虑使用Vector
    在这里插入图片描述
    inkedList底层结构
    LinkedList的全面说明
    1)LinkedList底层实现了双向链表和双端队列特点
    2)可以添加任意元素(元素可以重复),包括null
    3)线程不安全,没有实现同步

LinkedList氐层结构
LinkedList的底层操作机制

  1. LinkedList底层维护了一个双向链专
  2. LinkedList中维护了两个属性first和last分别指向首节点和尾节点
    3)每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表
    4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高。
package com.dxl.staticpar;

public class LinkList_ {
    public static void main(String[] args) {
        Node jack = new Node("jack");
        Node tom = new Node("tom");
        Node jhfe = new Node("jhfe");

        //连接三个节点,行成双向列表;
        jack.next = tom;
        tom.next = jhfe;
        jhfe.pre = tom;
        tom.pre = jack;

        Node first = jack;//第一个节点,头结点
        Node last = jhfe;//最后一个节点,尾结点

        //从头到尾进行遍历
        while (true){
            if (first == null){
                break;
            }
             System.out.println(first);
            first = first.next;
        }

        //从尾到头的遍历
        while (true){
            if (last == null){
                break;
            }
            System.out.println(last);
            last = last.pre;
        }

//        添加一个Node节点
        Node smith = new Node("Smith");
        tom.next = smith;
        smith.next = jhfe;
        jhfe.pre = smith;
        smith.pre = tom;

        first = jack;
        while (true){
            if (first == null){
                break;
            }
            System.out.println(first);
            first = first.next;
        }
    }
}

//定义一个Node类,Node对象,表示双向链表的一个节点
class Node{
    public Object item;//正在存放数据
    public Node next;//后一个节点
    public Node pre;//前一个节点
    public Node(Object name){
        this.item = name;
    }

    @Override
    public String toString() {
        return "Node name = " + item ;
    }
}

删除
在这里插入图片描述

package com.dxl.staticpar;

import java.util.Iterator;
import java.util.LinkedList;

public class LinkList_ {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList();
        linkedList.add(5);
        linkedList.add(1);
        linkedList.add(7);
        System.out.println("linkedList= " + linkedList);

        linkedList.remove();//默认拿掉第一个
        System.out.println("linkedList=" + linkedList);

        linkedList.set(1,22222);
        System.out.println("linkedList = " + linkedList);

        Object o = linkedList.get(1);//获取双向链表的第2个对象
        System.out.println(o);

        //LinkedList实现了list接口,可以用迭代器遍历
        Iterator iterator = linkedList.iterator();
        while (iterator.hasNext()){
            Object next = iterator.next();
            System.out.println("next = " + next);
        }

        for(Object o1 : linkedList){
            System.out.println("linke = " + o1);
        }

        for (int i = 0; i < linkedList.size(); i ++){
            System.out.println(linkedList.get(i));
        }
    }
}


在这里插入图片描述
如何选择ArrayList和LinkedList:
1)如果我们改查的操作多,选择ArrayList
2)如果我们增删的操作多,选择LinkedList
3)一般来说,在程序中,80%-90%都是查询,因此大部分情况下会选择ArrayList4)在一个项目中,根据业务灵活选择,也可能这样,一个模块使用的是ArrayList,另外一个模块是LinkedList.

Set接口和常用方法
Set接口基本介绍
1)无家(添加和取出的顺序不一致),没有索引
2)不允许重复元素,所以最多包含一个null
3)JDK API中Set接口的实现类有:

package com.dxl.staticpar;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetMethod {
    public static void main(String[] args) {
        //2. set接口的实现类的对象(Set接口对象),不能存放重复的元素,可以添加一个nul
        //3. set接口对象存放数据是无序(即添加的顺序和取出的顺序不一致”)
        //4.注意:取出的顺序的顺序虽然不是添加的顺序,但是他的固定.
        Set set = new HashSet();
        set.add("john");
        set.add("yuyu");
        set.add("john");
        set.add("jack");
        set.add(null);
        set.add(null);

        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            Object next =  iterator.next();
            System.out.println("next = " + next);
        }

        for (Object o: set){
            System.out.println("set = " + o);
        }
    }
}

Set接口的常用方法
和List接口一样, Set接口也是Collection的子接口,因此,常用方法和Collection接口一样.
Set接口的遍历方式
同Collection的遍历方式一样,因为Set接口是Collection接口的子接口。
1.可以使用迭代器
2增强for
3.不能使用索引的方式来获取.

Set接口实现类-HashSet
HashSet的全面说明

  1. HashSet实现了Set接口
  2. HashSet实际上是HashMap。
    3)可以存放null值,但是只能有一个null
  3. HashSet不保证元素是有序的,取决于hash后,再确定索引的结果.
    5)不能有重复元素/对象.在前面Set 接口使用已经讲过
package com.dxl.staticpar;

import java.util.HashSet;
import java.util.Set;

public class SetMethod {
    public static void main(String[] args) {
        Set hashSet = new HashSet();
        hashSet.add(null);
        hashSet.add(null);
        System.out.println("hashSet = " + hashSet);

    }
}

Set接口实现类-HashSet
HashSet底层机制说明

分析HashSet底层是HashMap, HashMap底层是(数组+链表+红黑树)

package com.dxl.staticpar;

import java.util.HashSet;

@SuppressWarnings({"all"})
public class SetMethod {
    public static void main(String[] args) {
        //1.在执行add方法后,会返回一个boolean值
        // 2.如果添加成功,返回 true,否则返回false
        // 3.可以通过remove指定删除哪个对象

        HashSet set = new HashSet();
        System.out.println(set.add("john"));
        System.out.println(set.add("lucy"));
        System.out.println(set.add("john"));
        System.out.println(set.add("Rose"));
        set.remove("john");
        System.out.println("set = " + set);

        set = new HashSet();
        System.out.println("set = " + set);
        set.add("lucy");
        set.add("lucy");
        set.add(new Dog("tom"));
        set.add(new Dog("tom"));
        System.out.println("set = " + set);
    }
}

class Dog{
    private String name;

    public Dog(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}
package com.dxl.staticpar;

public class HashSet_ {
    public static void main(String[] args) {
        Node[] table = new Node[16];
        System.out.println("table = " + table);

        Node john = new Node("John", null);

        table[2] = john;
        Node jack = new Node("jack", null);
        john.next = jack;
        System.out.println("table = " + table);
    }
}

class Node{
    Object item;
    Node next;

    public Node(Object item, Node next) {
        this.item = item;
        this.next = next;
    }

    @Override
    public String toString() {
        return "Node{" +
                "item=" + item +
                ", next=" + next +
                '}';
    }
}

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

package com.dxl.staticpar;

import java.util.HashSet;
import java.util.Objects;

public class HashSet_ {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add(new Employee("milan", 45));
        hashSet.add(new Employee("smith",56));
        hashSet.add(new Employee("milan",45));

        System.out.println("hashSet = " + hashSet);
    }
}

class Employee{
    private String name;
    private  int age;

    public Employee(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 String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee employee = (Employee) o;
        return getAge() == employee.getAge() && Objects.equals(getName(), employee.getName());
    }

    @Override
    public int hashCode() {
        return Objects.hash(getName(), getAge());
    }
}

Set接口实现类-LinkedHashSet
LinkedHashSet的全面说明
1)LinkedHashSet是HashSet的子类
2) LinkedHashSet底层是一个 LinkedHashMap,底层维护了一个数组+双
向链表
3)LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使
用链表维护元素的次序(图),这使得元素看起来是以插入顺序保存的.
4)LinkedHashSet不允许添重复元素
在这里插入图片描述

package com.dxl.staticpar;

import java.util.LinkedHashSet;
import java.util.Set;

public class HashSet_ {
    public static void main(String[] args) {
        Set set = new LinkedHashSet();
        set.add(new String("AA"));
        set.add(423);
        set.add(423);
        set.add(new Custom("刘",45678));
        set.add(489);
        set.add("shh");

        System.out.println("set = " + set);

        //1.LinkedHashSet 加入顺序和取出元素/数据的顺序一致
//2. LinkedHashSet底层维护的是一个LinkedHashMap(是HashMap的子类)
// 3. LinkedHashSet底层结构〔数组table+双向链表)
//4.添加第一次时,直接将数组table扩容到16,存放的结点类型是 LinkedHashMapSEntry
//5.数组是 HashMap$Node[]存放的元素/数据是 LinkedHashMap$Entry类型
/*
继承关系是静态内部类
        static class EntryK,v> extends HashMap.Node<K, V> {
            Entry<K,V> before,after;
            Entry(int hash,K key, V value,Node<K, V> next) {
                super(hash,key, value,next);
            }
        }
*/
    }
}
class Custom{
    private String name;
    private int no;

    public Custom(String name, int no) {
        this.name = name;
        this.no = no;
    }

    public String getName() {
        return name;
    }

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

    public int getNo() {
        return no;
    }

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

    public void setNo(int no) {
        this.no = no;
    }
}

Map接口和常用方法
Map接口实现类的特点
注意:这里讲的是JDK8的Map接口特点
1)Map与Collection并列存在。用于保存具有映射关系的数据:Key-Value
2) Map 中的key和 value可以是任何引用类型的数据,会封装到HashMap$Node对象中
3) Map中的key 不允许重复,原因和HashSet一样,前面分析过源码.
4) Map中的value可以重复
5) Map 的key可以为null, value也可以为null,注意key为null, 只能有一个,
value为null ,可以多个.
6)常用String类作为Map的key
7) key 和 value之间存在单向一对一关系,即通过指定的key 总能找到对应的value

package com.dxl.staticpar;

import java.util.HashMap;
import java.util.Map;

public class Map_ {
    public static void main(String[] args) {
       Map map = new HashMap();
       map.put("12","哈加");
       map.put("13","sh");
       map.put("12","eh");
       map.put(null,null);
       map.put(null,"adb");
       map.put("jfke",null);
       map.put("hye",null);
       map.put(1,"zhaj"); 
       map.put(new Object(),"jfke");

       System.out.println(map.get("12"));

       System.out.println("map = " + map);
    }
}

  1. Map存放数据的key-value示意图,一对k-v是放在一个Node中的,有因为Node实现了Entry 接口,有些书上也说一对k-v就是一个Entry
package com.dxl.staticpar;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class Map_ {
    public static void main(String[] args) {
       Map map = new HashMap();
       map.put("12","哈加");
       map.put("13","sh");
        //1.k-v最后是 HashMap$Node node = newNode(hash, key,value,null)
        // 2.k-v为了方便程序员的遍历,还会创建 EntrySet集合,该集合存放的元素的类型 Entry,而一个Entry
        // 对象就有k,v EntrySet<Entry<K,V>>即: transient Set<Hap. Entry<K,V>> entrySet;
        //3. entrySet 中,定义的类型是Map.Entry ,但是实际上存放的还是 HashMap$Node
        // 这时因为static class Node<K,V> implements Map.Entry<K, V>
//4.当把 HashMap$Node 对象存放到 entrySet 就方便我们的遍历,因为 Map.Entry 提供了重要方法
// K getKey(); v getValue();
        Set set = map.entrySet();
        System.out.println(set.getClass());
        for (Object obj : set){
            // System.out.println(obj.getClass();
            // HashMap$Node
            // 为了从 HashMap$Node 取出k-v
//1.先做一个向下转型
            Map. Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey() +"-" + entry.getValue() );

        }

    }
}

在这里插入图片描述
'Map接口常用方法

  1. put:添加
  2. remove:根据键删除映射关系
  3. get:根据键获取值
  4. size:获取元素个数
  5. isEmpty:判断个数是否为0
  6. clear:清除
  7. containsKey:查找键是否存在
package com.dxl.staticpar;

import java.util.HashMap;
import java.util.Map;

public class Map_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("大亨", new Book("", 100));
        map.put("jd","hfej");
        map.put("ejf",null);
        map.put(null,"feef");
        map.put("fe","fe");

        System.out.println("map = " + map);

        map.remove(null);

        System.out.println("map = " + map);


    }
}
class Book{
    private String name;
    private int money;

    public Book(String name, int money) {
        this.name = name;
        this.money = money;
    }

    public String getName() {
        return name;
    }

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

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }

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

Map接口和常用方法
Map接口遍历方法> Map遍历方式
1)containsKey:查找键是否存在
2) keySet:获取所有的键
3) entrySet:获取所有关系k-v
4) values:获取所有的值

package com.dxl.staticpar;

import java.util.*;

public class Map_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("邓超","孙俪");
        map.put("王宝强","马蓉");
        map.put("宋喆","马蓉");
        map.put("刘令博", null);
        map.put(null,"刘亦菲");
        map.put("鹿晗","关晓彤");

        Set keys = map.keySet();
        for (Object obj : keys){
            System.out.println(obj + "_" + map.get(obj));
        }

        Iterator iterator = keys.iterator();
        while (iterator.hasNext()){
            Object key = iterator.next();
            System.out.println(key + "-" + map.get(key));
        }

//        把所有的values取出来
        Collection values = map.values();
//        可以使用所有collections使用的遍历方法
        for (Object value:values){
            System.out.println(value);
        }

        Iterator iterator1 = values.iterator();
        while (iterator1.hasNext()) {
            Object next = iterator1.next();
            System.out.println(next);
        }

//        EnterySet来获取k-v
        Set entrySet = map.entrySet();
        for (Object o : entrySet){
//            将o转成Map.Entry
            Map.Entry m = (Map.Entry) o;
             System.out.println(m.getKey() + "-" + m.getValue());
        }

        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()) {
            Object next =  iterator2.next();
            System.out.println(next.getClass());
//            向下转型 Map.Entry
            Map.Entry M = (Map.Entry) next;
            System.out.println(M.getKey() + "-" + M.getValue());
        }
    }
}

Map接口实现类-HashMap
HashMap小结

  1. Map接口的常用实现类:HashMap、Hashtable和Properties.
  2. HashMap是 Map接口使用频率最高的实现类。
  3. HashMap是以key-val对的方式来存储数据[HashMap$Node]Entry
  4. key不能重复,但是是值可以重复,允许使用null键和null值。
    5)如果添加相同的key,则会覆盖原来的key-val ,等同于修改.(key不会替换,val会替换)
    6)与HashSet一样,不保证映射的顺序,因为底层是以hash表的方式来存储的.
  5. HashMap没有实现同步,因此是线程不安全的
package com.dxl.staticpar;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class MapExercise {
    public static void main(String[] args) {
        Map hashMap = new HashMap();
        hashMap.put(1,new Emp("jack",5000,1));
        hashMap.put(2,new Emp("lili",5800,2));
        hashMap.put(3,new Emp("yue",5500,3));

//        两种遍历方式
        Set keySet = hashMap.keySet();
        for (Object key: keySet){
            Emp emp =(Emp) hashMap.get(key);
            if (emp.getSal() > 5500){
                System.out.println(emp);
            }
        }

        Set entrySet = hashMap.entrySet();
        Iterator iterator = entrySet.iterator();
         while(iterator.hasNext()){
             Map.Entry entry = (Map.Entry) iterator.next();
             Emp emp = (Emp) entry.getValue();
             if (emp.getSal() > 5500){
                 System.out.println(emp);
             }
         }
    }
}

class Emp{
    private String name;
    private double sal;
    private int id;

    public Emp(String name, double sal, int id) {
        this.name = name;
        this.sal = sal;
        this.id = id;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", id=" + id +
                '}';
    }

    public String getName() {
        return name;
    }

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

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public int getId() {
        return id;
    }

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

在这里插入图片描述
扩容机制[和HashSet相同]

  1. HashMap底层维护了Node类型的数组table,默认为null
    2)当创建对象时,将加载因子(loadfactor)初始化为0.75.
    3)当添加key-val时,通过key的哈希值得到在table的索引。然后判断该索引处是否有元素。
    如果没有元素直接添加。如果该索引处有元素,继续判断该元素的key是否和准备加入的key相等,如果相等,则直接替换val;如果不相等需要判断是树结构还是链表结构,做出相应处理。如果添加时发现容量不够,则需要扩容。
    4)第1次添加,则需要扩容table容量为16,临界值(threshold)为12.
    5)以后再扩容,则需要扩容table容量为原来的2倍,临界值为原来的2倍,即24,依次类推.
    6)在Java8中,如果一条链表的元素个数超过TREEIFY_THRESHOLD(默认是8),
    table的大小 >= MIN_TREEIFY_ CAPACITY(默认64),就会进行树化(红黑树)
package com.dxl.staticpar;

import java.util.HashMap;

public class MapExercise {
    public static void main(String[] args) {
        HashMap hashMap = new HashMap();
        for (int i = 1; i < 12; i++) {
            hashMap.put(new A(i),"heu");
        }

        System.out.println("hashMap = " + hashMap );
    }
}

class A{
    private int num;

    public A(int num) {
        this.num = num;
    }

    public int getNum() {
        return num;
    }

    public void setNum(int num) {
        this.num = num;
    }

    //    @Override
//    public boolean equals(Object o) {
//        if (this == o) return true;
//        if (!(o instanceof A)) return false;
//        A a = (A) o;
//        return num == a.num;
//    }

    @Override
    public int hashCode() {
        return 100;
    }

    @Override
    public String toString() {
        return "\nA{" +
                "num=" + num +
                '}';
    }
}

Map接口实现类-Hashtable
HashTable的基本介绍
1)存放的元素是键值对:即K-V
2) hashtable的键和值都不能为null,否则会抛出空指针异常
'3) hashTable使用方法基本上和HashMap一样
4) hashTable是线程安全的,hashMap是线程不安全的
//1。底层有数组 Hashtable$Entry[]初始化大小为11
//2.临界值threshold 8 = 11 * 0.75
//3.扩容:按照自己的扩容机制来进行即可.
在这里插入图片描述
在这里插入图片描述
Map接口实现类-Properties
●基本介绍
1.Properties类继承自Hashtable类并且实现了Map接口,也是使用一种键值对的形式来保存数据。
2.他的使用特点和Hashtable类似
3.Properties还可以用于从 xxx.properties文件中,加载数据到Properties类对象,并进行读取和修改
4.说明:工作后xxx.properties文件通常作为配置文件。

package com.dxl.staticpar;

import java.util.Properties;

public class Properties_ {
    public static void main(String[] args) {
        Properties properties = new Properties();
        properties.put( "john",100);
//        properties.put(null,100);不能放空键和空值

//        properties.put("john", null);
        properties.put("lucy",100);
        properties.put("lic",100);
        properties.put("lic", 88);//相同的key,value被替换

        System.out.println("Properties = " + properties);

        System.out.println(properties.get("lic"));

        properties.remove("lic");
        System.out.println("per = " + properties);

        properties.put("john","雨夜");
        System.out.println(properties);
    }
}

在这里插入图片描述

package com.dxl.staticpar;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSet_ {
    public static void main(String[] args) {
        //1.当我们使用无参构造器,创建TreeSet时,仍然是无序的
        //2.老师希望添加的元素,按照字符串大小来排序
//3.使用TreeSet提供的一个构造器,可以传入一个比较器

//        TreeSet treeSet = new TreeSet();
        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o2) .compareTo((String) o1);
            }
        });

        treeSet.add("jack");
        treeSet.add("tom");
        treeSet.add("sh");
        treeSet.add("a");

        System.out.println("treeSet = " + treeSet);

//        底层构造器把传入的对象赋给了TreeMap
    }
}

在这里插入图片描述

package com.dxl.staticpar;

import java.util.Comparator;
import java.util.TreeMap;

public class TreeSet_ {
    public static void main(String[] args) {
        //使用默认的构造器,创建TreeMap,是无序的(也没有排序)

//        TreeMap treeMap = new TreeMap();
        TreeMap treeMap = new TreeMap(new Comparator()
        {
            @Override
            public int compare(Object o1, Object o2) {
//                按字符K的大小排序
//                return ((String) o1).compareTo((String) o2);
//                按照K的长度大小排序
                return ((String) o1).length() - ((String) o2).length();
            }
        });
        treeMap.put("jax","fe");
        treeMap.put("tom","汤姆");//按长度加入不了,不是替换
        treeMap.put( "kristina","克瑞斯提诺");
        treeMap.put( "smith","斯密斯");
        System.out.println("treeMap = " + treeMap);
    }
}

Collections工具类
Collections工具类介绍

  1. Collections是一个操作Set、List和 Map等集合的工具类
  2. Collections中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作排序操作:(均为static方法)
  3. reverse(List):反转List 中元素的顺序
  4. shuffle(List):对List集合元素进行随机排序
  5. sort(List):根据元素的自然顺序对指定List集合元素按升序排序
  6. sort(List,Comparator):根据指定的Comparator产生的顺序对 List集合元素进行排序
  7. swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
package com.dxl.staticpar;

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

public class Collections_ {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("tom");
        list.add("smoith");
        list.add("kogn");
        list.add("milan");

//        翻转
        Collections.reverse(list);
        System.out.println("list = " + list);
        //shuffle(List):对List集合元素进行随机排序
//        Collections.shuffle(list);
//        System.out.println(list);
//        sort(List):根据元素的自然顺序对指定 List集合元素按升序排序
        Collections.sort(list);
        System.out.println("自然排序:" + list);
//        sort(List,Comparator):根据指定的Comparator产生的顺序对List 集合元素
// 我们希望按照字符串的长度大小排序
        Collections.sort(list, new Comparator() {
           @Override
            public int compare(Object o1,Object o2){
                return ((String)o1).length() - ((String)o2).length();
            }
        });
        System.out.println(list);

//        swap(List,int, int):将指定 list 集合中的i处元素和j处元素进行交换
        Collections.swap(list,0,1);
        System.out.println("list = " + list);

    }
}

Collections工具类
●查找、替换

  1. Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
  2. Object max(Collection, Comparator):根据Comparator 指定的顺序,返回给定集合中的最大元素
  3. Object min(Collection)
    4)Object min(Collection,Comparator)
  4. int frequency(Collection,object):返回指定集合中指定元素的出现次数
  5. void copy(List dest,List src):将src中的内容复制到dest中
  6. boolean replaceAll(List list,Object oldVal, Object newVal):使用新值替换List对象的所有旧值
    在这里插入图片描述
package com.dxl.staticpar;

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

public class Collections_ {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("tom");
        list.add("smoith");
        list.add("kogn");
        list.add("milan");

//        翻转
        Collections.reverse(list);
        System.out.println("list = " + list);
        //shuffle(List):对List集合元素进行随机排序
//        Collections.shuffle(list);
//        System.out.println(list);
//        sort(List):根据元素的自然顺序对指定 List集合元素按升序排序
        Collections.sort(list);
        System.out.println("自然排序:" + list);
//        sort(List,Comparator):根据指定的Comparator产生的顺序对List 集合元素
// 我们希望按照字符串的长度大小排序
        Collections.sort(list, new Comparator() {
           @Override
            public int compare(Object o1,Object o2){
                return ((String)o1).length() - ((String)o2).length();
            }
        });
        System.out.println(list);

//        swap(List,int, int):将指定 list 集合中的i处元素和j处元素进行交换
        Collections.swap(list,0,1);
        System.out.println("list = " + list);

        //object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素System.out.println("自然顺序最大元素=" +Collections.max(list));
//Object max(Collection,Comparator):根据Comparator 指定的顺序,返回给定集合中的最大元素
// 比如,我们要返回长度最大的元素
       Object maxObject = Collections.max(list,new Comparator() {
            @Override
            public int compare(Object o1,Object o2) {
                return ((String)o1).length() - ((String)o2).length();
            }
        });
        System.out.println("长度最大的元素:" + maxObject);

        //object min(collection)
//object min(Collection,Comparator)

        //int frequency(Collection,Object):返回指定集合中指定元素的出现次数
        System.out.println("tom出现的次数=" + Collections.frequency(list,"tom"));
//void copylList dest,List src):将src中的内容复制到dest中
        ArrayList dest = new ArrayList();
        //为了完成一个完整拷贝,我们需要先给dest赋值,大小和list.size()一样
        for(int i = 0; i< list.size(); i++) {
            dest.add("");
        }
//拷贝
        Collections.copy(dest,list);
        System.out.println("dest=" +dest);

//boolean replaceAli(List list,Object oldVal,Object newVal):使用新值替换 List对象的所有旧值
        Collections.replaceAll(list,"tom","汤姆");
        System.out.println(list);
    }
}
package com.dxl.staticpar;

import java.util.ArrayList;

public class HomeWork {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(new News("新冠确诊病例超千万,数百万印度教信徒赴恒河\"圣浴\"引民众担忧\n"));
        arrayList.add(new News("男子突然想起2个月前钓的鱼还在网兜里,捞起一看赶紧放生\n"));

        int size = arrayList.size();
        for (int i = size - 1; i >= 0 ; i--) {
            News news = (News)arrayList.get(i);
            System.out.println(News.processTitle(news.getTitle()));
        }
    }
}

class News{
    private String title;
    private String content;

    public News(String title) {
        this.title = title;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    @Override
    public String toString() {
        return "News{" +
                "title='" + title + '\'' +
                '}';
    }

    public static String processTitle(String title){
        if (title == null){
            return "";
        }
        if (title.length() > 15){
            return title.substring(0,15) + "...";
        }else{
            return title;
        }
    }
}
package com.dxl.staticpar;

import java.util.*;

public class HomeWork {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("jack",650);
        map.put("tom",1200);
        map.put("simth",2900);
        System.out.println("map = " + map);

        map.put("jack",2600);

        System.out.println("map = " + map);

        Set keySet = map.keySet();
        for (Object o : keySet){
            map.put(o, (Integer)map.get(o) + 100);
        }
        System.out.println(map);

        Set entrySet = map.entrySet();
        Iterator iterator = entrySet.iterator();
        while (iterator.hasNext()) {
            Map.Entry next =  (Map.Entry)iterator.next();
            System.out.println(next.getKey() + "-" +next.getValue());
        }

        Collection  values = map.values();
        for (Object value : values){
            System.out.println(value);
        }
    }
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
泛型的理解和好处
使用传统方法的问题分析
1)不能对加入到集合ArrayList中的数据类型进行约束(不安全)
2)遍历的时候,需要进行类型转换,如果集合中的数据量较大,对效率有影响
泛型快速体验-用泛型来解决前面的问题
ArrayList arrayList = new ArrayList{};
泛型的理解和好处
●泛型的好处
1)编译时,检查添加元素的类型,提高了安全性
2)减少了类型转换的次数,提高效率
√不使用泛型
Dog -加入->Object -取出-> Dog //放入到ArrayList 会先转成Object,在取出时,还需要转换成Dog
√使用泛型
Dog -> Dog -> Dog!/放入时,和取出时,不需要类型转换,提高效率
3)不再提示编译警告

package com.dxl.staticpar;

import java.util.ArrayList;

//@SuppressWarnings({"all"})
public class generic_ {
    public static void main(String[] args) {
        ArrayList<Dog> arrayList = new ArrayList<Dog>();//表示存放在ArrayList集合中的元素只能是Dog类型
        arrayList.add(new Dog("旺财",56));
        arrayList.add(new Dog("发财",12));
        arrayList.add(new Dog("小黄",4));

//        arrayList.add(new Cat("招财猫",12));

//        遍历可以直接取出Dog类型,而不是Object类型
        for (Dog dog:arrayList){
//            Dog dog = (Dog)o;
            System.out.println(dog.getName() + "_" + dog.getAge());
        }
    }
}
class Dog{
    private String name;
    private int age;

    public Dog(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 String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

class Cat{
    private String name;
    private int age;

    public Cat(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 String toString() {
            return "Dog{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
            }
}

泛型介绍
int a = 10;
泛(广泛)型(类型)=> Integer,String,Dog
1)泛型又称参数化类型,是Jdk5.0出现的新特性,解决数据类型的安全性问题2)在类声明或实例化时只要指定好需要的具体的类型即可。
3) Java泛型可以保证如果程序在编译时没有发出警告,运行时就不会产生
ClassCastException异常。同时,代码更加简洁、健壮。
4)泛型的作用是:可以在类声明时通过一个标识表示类中某个属性的类型,或者是某个方
法的返回值的类型,或者是参数类型.
public class ArrayList{} E称为泛型,那么Dog->E

package com.dxl.staticpar;

public class Generic_ {
    public static void main(String[] args) {
        //E 的具体数据类型,在定义时确定,即编译时
        Person<String> stringPerson = new Person<String>("哈哈哈哈");
        /*
        Person中的E 全部用String表示
         */
        Person<Integer> integerPerson = new Person<Integer>(100);
         /*
        Person中的E 全部用Integer表示
         */
        integerPerson.show();

    }
}

//泛型的作用是;可以在类声明时通过一个标识表示类中某个属性的类型,
// 或者是某个方法的返回值的类型,或者是参数类型

class Person<E>{
    E s;//E 表示 s的数据类型,该数据类型在定义Person对象的时候指定,即在编译期间就确定E是什么类型

    public Person(E s) {//E也可以是参数类型
        this.s = s;
    }

    public E f(){//返回类型使用E
        return s;
    }

    public void show(){
        System.out.println(s.getClass());
    }
}

泛型的语法
●泛型的声明
interface接口0和class类<K.V>{}
//比如: List , ArrayList
说明:
1)其中,T,K,V不代表值,而是表示类型。
.2)任意字母都可以。常用T表示,是Type的缩写泛型的实例化:
要在类名后面指定类型参数的值(类型)。如:

  1. List strList = new ArrayList();
  2. Iterator iterator = customers.iterator();
package com.dxl.staticpar;

import java.util.*;

public class Generic_ {
    public static void main(String[] args) {
//        使用泛型给hashSet创建对象
        HashSet<Student> students = new HashSet<>();
        students.add(new Student("jack",12));
        students.add(new Student("tom",23));
        students.add(new Student("mary",22));

        for (Student s : students){
            System.out.println(s);
        }

//        使用泛型给HashMap创建对象
        HashMap<String, Student> stringStudentHashMap = new HashMap<>();
        stringStudentHashMap.put("jack",new Student("jack",12));
        stringStudentHashMap.put("tom",new Student("tom",23));
        stringStudentHashMap.put("mary",new Student("mary",22));

//        迭代器,EntrySet
        /*
        public Set<Nap .Entry<K, V>> entrySet() {
                Set<Map.Entry<K, V>> es;
                return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
            }
         */
        Set<Map.Entry<String, Student>> entries = stringStudentHashMap.entrySet();
        /*
        public final Iterator<Map. Entry<K, V>> iterator() {
                return new EntryIterator();
                }

         */
        Iterator<Map.Entry<String, Student>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, Student> next =  iterator.next();
            System.out.println(next.getKey() + " " + next.getValue());
            
        }
    }
}
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;
    }

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

泛型使用的注意事项和细节
1.interface List{} , public class HashSet{}等等
说明:T,E正只能是引用类型
看看下面语句是否正确?:
List list = new ArrayList();//正确
List list2 = new ArrayList();//错误
2.在指定泛型具体类型后,可以传入该类型或者其子类类型
3.泛型使用形式
List list1 =new ArrayList();
List list2 = new ArrayList<>();

package com.dxl.staticpar;

public class Generic_ {
    public static void main(String[] args) {
        Pig<A> aPig = new Pig<A>(new A());
        Pig<A> aPig1 = new Pig<>(new B());

        aPig.show();

        aPig1.show();
    }
}
class A{}
class B extends A{}

class Pig<E>{
    E e;

    public Pig(E e) {
        this.e = e;
    }

    public void show(){
        System.out.println(e.getClass());
    }
}

4.如果我们这样写 List list3 = new ArrayList();默认给它的泛型是就是Object ]即:
在这里插入图片描述
在这里插入图片描述

package com.dxl.staticpar;

public class MyDate implements Comparable<MyDate> {
    private int year;
    private int month;
    private int dar;

    public MyDate(int year, int month, int dar) {
        this.year = year;
        this.month = month;
        this.dar = dar;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDar() {
        return dar;
    }

    public void setDar(int dar) {
        this.dar = dar;
    }

    @Override
    public String toString() {
        return "MyDate{" +
                "year=" + year +
                ", month=" + month +
                ", dar=" + dar +
                '}';
    }

    @Override
    public int compareTo(MyDate o) {//把对年月日的比较
//                    name相同,比较birthday
        int yearMinus = year - o.getYear();
        if (yearMinus != 0){
            return yearMinus;
        }
//                    如果年相同,比较months
        int monthMinus = month - o.getMonth();
        if (monthMinus != 0){
            return monthMinus;
        }
        return dar- o.getDar();

    }
}

package com.dxl.staticpar;

public class Employee {
    private String name;
    private double sal;
    private MyDate birthday;

    public Employee(String name, double sal, MyDate birthday) {
        this.name = name;
        this.sal = sal;
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

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

    public double getSal() {
        return sal;
    }

    public void setSal(double sal) {
        this.sal = sal;
    }

    public MyDate getBirthday() {
        return birthday;
    }

    public void setBirthday(MyDate birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "\nEmployee{" +
                "name='" + name + '\'' +
                ", sal=" + sal +
                ", birthday=" + birthday +
                '}';
    }
}

package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.Comparator;

public class Generic_ {
    public static void main(String[] args) {
        ArrayList<Employee> employees = new ArrayList<>();
        employees.add(new Employee("tom",20000,new MyDate(2000,11,5)));
        employees.add(new Employee("jack",12000,new MyDate(1980,12,12)));
        employees.add(new Employee("tom",50000,new MyDate(1980,10,10)));

        System.out.println("employees = " + employees);

        System.out.println("========对雇员进行排序===========");
        employees.sort(new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                if (!(o1 instanceof Employee && o2 instanceof Employee)) {
                    System.out.println("类型不正确!");
                    return 0;
                }
                else {
                    int i = o1.getName().compareTo(o2.getName());
                    if (i != 0) {
                        return i;
                    }
                    return o1.getBirthday().compareTo(o2.getBirthday());
                }
            }
        });

        System.out.println("=====排序后的结果======");
        System.out.println("employees = " + employees);
    }
}

自定义泛型
自定义泛型类(难度)

基本语法
class类名<T,R…>{成员
}
注意细节
1)普通成员可以使用泛型(属性、方法)
2)使用泛型的数组,不能初始化
3)静态方法中不能使用类的泛型
4)泛型类的类型,是在创建对象时确定的(因为创建对象时,需要指定确定类型)5)如果在创建对象时,没有指定类型,默认为Object

package com.dxl.staticpar;

import java.util.Arrays;

public class Generic_ {
    public static void main(String[] args){
        Tiger<Double, String, Integer> g = new Tiger<>("john");
        g.setT(10.9);
        System.out.println(g);
        Tiger g2 = new Tiger("john~~~");
        g2.setT("yy");
        System.out.println("g2 = " + g2);
    }
}
//1.Tiger后面泛型,所以我们把 Tiger 就称为自定义泛型类
//2.T,R,H泛型的标识符,一般是单个大写字母
//3.泛型标识符可以有多个。
//4.普通成员可以使用泛型〔属性、团法)
//5.使用泛型的数组不能初始化
//6.静态方法不能使用泛型,
//因为静态是和类相关的,在类加载时,对象还没有创建
//所以,如果静态方法和静态属性使用了泛型,JVM就无法完成初始化

class Tiger<T,R,M>{
    String name;
        R r;
        M m;
        T t;
        T[] ts;//无法确定T的类型,无法在内存开空间,不能初始化
//        static R r1;

    public Tiger(String name) {
        this.name = name;
    }

    public Tiger(String name, R r, M m, T t) {
        this.name = name;
        this.r = r;
        this.m = m;
        this.t = t;
    }

    public String getName() {
        return name;
    }

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

    public R getR() {
        return r;
    }

    public void setR(R r) {
        this.r = r;
    }

    public M getM() {
        return m;
    }

    public void setM(M m) {
        this.m = m;
    }

    public T getT() {
        return t;
    }

    public void setT(T t) {
        this.t = t;
    }

    @Override
    public String toString() {
        return "Tiger{" +
                "name='" + name + '\'' +
                ", r=" + r +
                ", m=" + m +
                ", t=" + t +
                ", ts=" + Arrays.toString(ts) +
                '}';
    }
}

自定义泛型接口>基本语法
interface接口名<T,R…>{}

注意细节
1)接口中,静态成员也不能使用泛型(这个和泛型类规定一样)
2)泛型接口的类型,在继承接口或者实现接口时确定
3)没有指定类型,默认为Object

package com.dxl.staticpar;

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

    }
}

interface IUsb<U, R>{
    int n = 10;


    R get(U u);//普通方法可以使用方法
    void hi(R r);
    void run(R r1,R r2,U u1, U u2);

    //在jdk8 中,可以在接口中,使用默认方法
    default R method(U u){
        return null;
    }
}

//继承接口时需要指定类型
interface IA extends IUsb<String ,Double>{

}

//当我们去实现IA接口时,因为IA在继承IUsU 接口时,指定了U为String R为Double
// ,在实现IUsu接口的方法时,使用String替换,是Double替换R
class AA implements IA{

    @Override
    public Double get(String s) {
        return null;
    }

    @Override
    public void hi(Double aDouble) {

    }

    @Override
    public void run(Double r1, Double r2, String u1, String u2) {

    }

    @Override
    public Double method(String s) {
        return IA.super.method(s);
    }
}

//实现接口时,直接指定泛型接口类型
//实现接口时,直接指定泛型接口的类型
// 给U指定Integer给R指定了 Float
//所以,当我们实现IUsb方法时,会使用Integer替换U,使用Float替换R
class BB implements  IUsb<Integer, Float>{

    @Override
    public Float get(Integer integer) {
        return null;
    }

    @Override
    public void hi(Float aFloat) {

    }

    @Override
    public void run(Float r1, Float r2, Integer u1, Integer u2) {

    }

    @Override
    public Float method(Integer integer) {
        return IUsb.super.method(integer);
    }
}

//等价与类型为Object
class CC implements IUsb{

    @Override
    public Object get(Object o) {
        return null;
    }

    @Override
    public void hi(Object o) {

    }

    @Override
    public void run(Object r1, Object r2, Object u1, Object u2) {

    }

    @Override
    public Object method(Object o) {
        return IUsb.super.method(o);
    }
}

自定义泛型方法
基本语法
修饰符<T,R…>返回类型方法名(参数列表){}
注意细节
1.泛型方法,可以定义在普通类中,也可以定义在泛型类中
2.当泛型方法被调用时,类型会确定
3. public void eat(E e) (),修饰符后没有<T,R…> eat方法不是泛型方法,而是使用了泛型

package com.dxl.staticpar;

import java.util.ArrayList;

@SuppressWarnings({"all "})
public class GenericInterface {
    public static void main(String[] args) {
        Car car = new Car();
        car.fly("玉玉", 100);//当调用方法使,传入参数,编译器会确定类型
        car.fly(100,5.69);//包含了自动装箱

//        T ---> String,  R --->  ArrayList
        Fish<String , ArrayList> fish = new Fish<>();
        fish.hello(new ArrayList(),11.3f);
    }
}
class Car{
    public void run(){

    }

    public <T, R> void fly(T t, R r){
        System.out.println(t.getClass());
        System.out.println(r.getClass());
    }

    public void show(){

    }
}

class Fish<T, R> {
    public void run(){

    }
    public <U,M> void eat(U u,M m){

    }

    public void hi(T t){
        //不是泛型方法,是hi方法使用了类型声明的泛型
    }

    public <K> void hello(R r,K k){
        //泛型方法,可以使用类声明的泛型,也可以使用自己声明的泛型
        System.out.println(r.getClass());
        System.out.println(k.getClass());
    }
}

泛型的继承和通配符
1)泛型不具备继承性
List list = new ArrayList0);//对吗? 不对
2)<?>︰支持任意泛型类型
3)<? extends A>:支持A类以及A类的子类,规定了泛型的上限
4)<? super A>:支持A类以及A类的父类,不限于直接父类,规定了泛型的下限

package com.dxl.staticpar;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings({"all "})
public class GenericInterface {
    public static void main(String[] args) {
        Object o = new String("xx");

        //举例说明下面三个方法的使用
        List<Object> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        List<AA> list3 = new ArrayList<>();
        List<BB> list4 = new ArrayList<>();
        List<CC> list5 = new ArrayList<>();

        printCollection(list5);
        printCollection(list1);
        printCollection(list2);
        printCollection(list3);
        printCollection(list4);

        printCollection2(list3);
        printCollection2(list4);
        printCollection2(list5);

        printCollection3(list1);
        printCollection3(list3);

    }

    //List<?>表示 任意的泛型类型都可以接受
    public static void printCollection(List<?> c){
        for (Object object : c){//通配符,取出时,就是Object
            System.out.println(object);
        }
    }

//    规定泛型的上限
    public static void printCollection2(List<? extends AA> c){
        for (Object object : c){//通配符,取出时,就是Object
            System.out.println(object);
        }
    }

//    规定泛型的下限
    public static void printCollection3(List<? super AA> c){
        for (Object object : c){//通配符,取出时,就是Object
            System.out.println(object);
        }
    }
}
class AA{

}

class BB extends AA{

}

class CC extends BB{

}

JUnit
为什么需要JUnit
1.一个类有很多功能代码需要测试,为了测试,就需要写入到main方法中。
2.如果有多个功能代码测试,就需要来回注销,切换很麻烦
3.如果可以直接运行一个方法,就方便很多,并且可以给出相关信息,就好了-> JUnit
●基本介绍
1.JUnit是一个Java语言的单元测试框架
2.多数Java的开发环境都已经集成了JUnit作为单元测试的工具

package com.dxl.staticpar;

import org.junit.jupiter.api.Test;

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

    }

    @Test
    public void m1(){
        System.out.println("m1()方法被调用!");
    }

    @Test
    public void m2(){
        System.out.println("m2()方法被调用!");
    }
}

package com.dxl.staticpar;

public class User {
    private int id;
    private int age;
    private String name;

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

    public int getId() {
        return id;
    }

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

    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

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

package com.dxl.staticpar;

import java.util.*;

public class DAO<T> {
    private Map<String , T> map = new HashMap<>();

    public T get(String id){
        return map.get(id);
    }

    public void update(String id, T entity){
        map.put(id,entity);
    }

    //遍历map [k-v],将map的所有value(entity),封装到ArrayList返回即可
    public List<T> list(){
      List<T> list =  new ArrayList<>();

      //遍历map
        Set<String> keySet = map.keySet();
        for (String key:keySet){
            list.add(map.get(key));
        }
        return list;
    }

    public void delete(String id){
        map.remove(id);
    }

    public void save(String id, T entity){
        map.put(id,entity);
    }
}

package com.dxl.staticpar;

import org.junit.jupiter.api.Test;

import java.util.List;

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

    }

    @Test
    public void testList(){
        DAO<User> dao = new DAO<>();
        dao.save("001",new User(1,10,"jacl"));
        dao.save("002",new User(2,20,"fefe"));
        dao.save("003",new User(3,30,"ege"));

        List<User> list = dao.list();

        System.out.println("list = " + list);

        dao.update("003",new User(3,56,"j8"));

        list = dao.list();
        System.out.println("list = " + list);

        dao.delete("001");
        list = dao.list();
        System.out.println("list = " + list);

        System.out.println("id = 0003" + dao.get("003"));
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值