Java入门笔记

news2024/12/22 23:09:22

目录

  • Java入门笔记
    • 快捷键
    • 基础准备
      • 环境准备
      • Java编译运行流程
      • TODO
      • 自定义模板
    • 基础语法
      • 变量原理
      • 标识符
        • 标识符命名规则
      • 数据类型
        • 整数型
        • 浮点型
        • 类型转换
        • 引用数据类型
      • 面向对象
        • 类和对象
          • 判断一个对象是不是某个类
        • 方法传参
          • 可变参数
          • 基本数据类型传参
          • 字符串数据类型传参
          • 引用数据类型传参
        • 静态属性和方法
        • 静态代码块
        • 包package
        • 导入Import
          • 导入多个包写法
        • 构造方法
        • 继承
          • this & super
          • 子类调用父类
        • 多态
        • 方法重载 overload
          • 构造方法互相调用
          • 基本数据类型自动扩增
          • 引用数据类型自动扩增
        • 方法重写 overrite
        • 访问权限
        • 内部类和外部类
        • 单例模式
        • final
        • 抽象类 abstract
        • 接口 interface 实现 implements
        • 枚举类 enum
          • 自定义枚举类
        • 匿名类
        • Bean规范
      • 常用类和对象
        • Object类
          • toString()
          • hashCode()
          • equals()
          • getClass()
        • 数组
          • 定义固定长度数组
          • 二维数组
          • 冒泡排序
          • 选择排序
          • 二分查找
        • 字符串
          • 创建字符串
          • 拼接 concat
          • 比较 equals compareTo
          • 截取 subString
          • 分解 split
          • 去除首尾空格 trim
          • 替换 replace
          • 大小写转换
          • 查找 indexOf contains
          • StringBuilder 效率高
        • 包装类
          • 装箱
          • 拆箱
        • 日期类 Date
          • 日期转字符串
          • 字符串转日期
          • 日期类的一些操作
        • 日历类 Calendar
          • 获取年月日
          • 使用日期类Date给日历类时间
          • 打印一个日历
        • 自定义工具类
          • 判断字符串是否为空
          • 生成随机字符串
          • 生成指定随机字符串
          • 转换字符串字符集
          • 日期类和字符串互转
        • 比较
          • 包装类型
      • 异常
        • 语法
        • 常见异常
        • 抛出异常
        • 自定义异常
    • 进阶语法
      • 集合
        • 定义
        • 常用接口和类
          • Collection接口
          • Map接口
        • Collection接口
          • ArrayList类
            • 创建ArrayList对象
            • 增加数据 add
            • 查看长度 size
            • 判空和清空
            • 获取数据 get
            • 遍历
            • 修改数据 set
            • 删除数据 remove
            • 判断是否包含 contains
            • 获取数据位置
            • 集合转数组 toArray
            • 克隆集合 clone
          • LinkedList类
            • 创建LinkedList对象
            • 添加数据 add
            • 获取数据 get
            • 遍历
            • 修改数据 set
            • 删除数据 remove
            • 其他常用操作
          • HashSet类
            • 创建HashSet
            • 增加数据 add
            • 删除数据 remove
            • 修改数据
            • 遍历
            • 转为数组 toArray
            • 其他常用方法
            • 重复数据
          • Queue类
            • 创建对象
            • 存入数据
            • 取出数据
        • Map接口
          • HashMap类
            • 创建对象
            • 添加修改数据 put
            • 获取数据 get
            • 删除数据 remove
            • 获取所有Key
            • 获取所有键值对
            • 常用方法
          • Hashtable类
            • 基本操作
          • 迭代器
            • 为什么要用迭代器
            • 迭代器使用
        • 泛型
          • 为什么要使用泛型
          • 如何使用泛型
          • 注意
        • 比较器接口
        • 工具类
          • Arrays类
        • 集合异常
        • 工具类
          • Arrays类
        • 集合异常

Java入门笔记

快捷键

Ctrl + D     		复制当前行且粘贴
Ctrl + R     		替换字符
Alt  + Enter 		错误提示
Ctrl + Shift + Y 	翻译
Ctrl + ALT + L 		整理代码  
Ctrl + H  			查看层次体系
Ctrl + P			可以查看所有重载方法的参数
    
.sout       打印.前面的东西
.var.前面的东西添加变量
.for        遍历.前面的东西

基础准备

环境准备

java -version 查看JDK版本

Java编译运行流程

源码(.java)经过编译器(javac.exe)编译后生成out文件夹中的字节码文件(.class)

java.exe启动虚拟机执行字节码文件

TODO

IDEA中可以在多行注释时写上TODO 表示待办的事情

在这里插入图片描述

自定义模板

Settings—Editor—Live Templates

可以设置快捷键模板

在这里插入图片描述

基础语法

变量原理

可以改变的向量存储就成为变量

image-20221202202702949

标识符

标识数据的符号称为标识符

image-20221202203254952

标识符命名规则

  1. 特殊符号只能使用美元$ 和下划线 _

  2. 数字不能出现在开头

  3. 标识符区分大小写

  4. 不能使用Java的保留字(static public …)

  5. 推荐使用驼峰命名法 userData myName

    image-20221202203653288

数据类型

byte : 8bit 1字节

short: 6bit

char : 16bit 正负

int : 32bit

image-20221202204146271

整数型

java整数默认为int类型
byte A = 1;  //1为Int类型

浮点型

java浮点数默认为双精度double类型
float A = 1.0//这时候1.0为double类型

想要声明单精度float类型需要加上f / F
flaot A = 1.0f; 
flaot A = 1.0F; 

类型转换

小的类型能够直接转为大的类型,大的类型转为小的类型需要强转

比如:

float A = 1.0f;
double B = 2.0; 

float C = B;  		//错误
float C = (float)B; //正确	

引用数据类型

image-20221202205557426

Q:为何int float 这些不称为引用数据类型而是基础数据类型

A:因为int float 这些基础数据类型存储在了向量存储的位置(红、黄色),他们没有箭头

image-20221202205642809

面向对象

类和对象

  • 类的首写字母是大写
  • 数字特殊符号这些和标识符一样

Q:如何创建一个对象?

A:user变量在栈中创建,然后在元空间中找到这个类的结构,在堆中生成这个对象,最后栈中的user变量指向这个新生成的对象。

image-20221203003759142

判断一个对象是不是某个类

instanceof

Object obj = new User();
if(obj instanceof User){

}

方法传参

可变参数

image-20221203004932710

image-20221203004859819

基本数据类型传参

传过去的只是形参,不会改变原来的

image-20221203010448539

字符串数据类型传参

image-20221203005849592

虽然字符串是引用数据类型,传过去的是指针,但是s=s+10会进行字符串拼接操作,堆中会生成一个拼接后的字符串。

image-20221203005938426

引用数据类型传参

image-20221203011029920

传过去的是对象地址,修改会改变对象的值

image-20221203010746538

静态属性和方法

静态属性存在于元空间(也称方法区)内

image-20221203012710551

直接用类名.静态方法();

image-20221203011642858

静态属性同理

image-20221203011805938

成员方法能够访问静态属性和静态方法(没static可以调用有static的)

静态方法能够访问成员属性和成员方法(有static不可以调用没有static的)

类和对象都可以直接调用静态属性和静态方法

静态代码块

静态代码块会在类的信息被方法区加载后,被自动调用

image-20221203013339078

image-20221203013350185

静态代码块可以有多个,会按顺序执行

对象创建时也有类似的代码块

如下方法表示

{

}

包package

package mypkg;

规范来说一般都是小写

java.lang下的包自动导入(import)

导入Import

import需要写在包下面

导入多个包写法

import java.util.*;

构造方法

只是进行成员属性的初始化赋值,和对象创建无关

如果不写构造函数,JVM会自动生成一个无参的构造函数 权限为public

image-20221203183919023

代码块在构造方法之前执行

继承

image-20221203184359737

this & super

父类子类中都有同个属性时默认使用this关键字,使用super可以访问父类属性

image-20221203184812475

子类调用父类

子类的构造方法会使用super() 去调用父类的构造方法,也就是说父类对象会在子类对象之前生成(这里不太准确,父类对象没有被生成new只会创建一个对象,红色部分是子类为从父类中继承过来的成员属性和成员方法开辟出的内存空间)

image-20221203185524176

也就是说每创建一个子类对象都会创建一个父类对象(这里不太准确,父类对象没有被生成new只会创建一个对象,红色部分是子类为从父类中继承过来的成员属性和成员方法开辟出的内存空间)

image-20221203185743678

如果父类自定义了带参数的构造函数,那么子类默认构造函数中自带的super() 就无法找到父类的构造函数

image-20221203190355597

image-20221203185825048

这时候就需要自己显示得使用带参数的super()

image-20221203190247139

多态

多态时能不能使用子类中的成员方法,取决于这个方法在父类中存不存在,如果是子类独有的就无法调用(这里指的是能不能使用,而不是到底用哪个),如果父类子类都有的,会调用子类的

image-20221203192052625

方法重载 overload

构造方法也可以重载

image-20221203192401226

image-20221203193537077

构造方法互相调用

构造方法间的互相调用需要使用到this关键字

image-20221203194036868

基本数据类型自动扩增

byte作为参数传入,但是方法中并没有byte作为形参的方法时

会进行扩增 byte为一个字节 会优先选 short 这种两个字节的 而不是int这种4个字节的或者报错

但是byte类型无法转为char类型,因为byte类型有负数,char类型没有负数,所有byte在没有short时会转为int

image-20221203194657616 image-20221203194730595
引用数据类型自动扩增

基本数据类型找不到时,会扩增长度

引用数据类型找不到时,会寻找父类

比如这里并没有BBB类型的参数的test方法,于是JVM会寻找以BBB的父类AAA为参数的test方法

image-20221203200306485

image-20221203200437492

如下情况使用多态写成 AAA aaa = new BBB()会直接报错,因为找不到AAA类型的会去找AAA的父类Object类,发现也没有,所以报错

image-20221203200915595

方法重写 overrite

image-20221203202056618

CCC ddd = new DDD(); 调用的是DDD中的i属性以及sum方法结果是40

因为多态时CCC决定的只是能否使用某个属性和方法,

如果这个方法父类没有子类有,就无法使用

如果这个方法父类和子类都有,就会调用子类中的方法

image-20221203202830402 image-20221203202852930

以下情况时结果会是20,而不是30

因为和方法不同,属性是哪里声明就在哪里使用,成员属性前默认有一个this.

image-20221203203503650

以下结果为30

因为DDD中没有sum方法,所有会使用CCC中的sum方法,

CCC中的sum方法调用的getI方法调用的是DDD中的getI方法,因为方法具体使用是需要看具体对象的

而DDD中getI方法使用的i是DDD中的20 所以结果为30

image-20221203204253313

访问权限

默认时,子包无法访问

image-20221203210526488

image-20221203211112950

Q:clone是Object类中的protected权限的方法,这里作为子类却无法调用,这是为啥呢?

A:注意到这里有两个子类都继承自Object类,而每个子类对象创建是都会有自己独立的父类内存空间,这里在子类A中去调用子类B的父类Object的clone方法就会出现没有权限的问题,而在子类B中调用子类B的父类Object的clone方法就没问题。

image-20221203211519240

image-20221203212036463

内部类和外部类

image-20221203212732594

单例模式

保证只存在一个对象,这种多线程会有问题

实现方法:

  1. 构造函数权限设为private
  2. 内部创建一个private权限的类对象
  3. 对外暴露一个创建对象的函数,函数中判断是否已经有对象了
image-20221204001747136

final

image-20221204002749932

抽象类 abstract

抽象类和抽象方法前都有abstract关键字

只要有抽象方法的就是抽象类,抽象类中可以有不抽象方法

image-20221204003643256

抽象类是不能创建对象的,一个类继承抽象类后想要创建对象需要重写抽象类的抽象方法

在这里插入图片描述

抽象类和抽象方法都不能使用final修饰,因为分别无法被继承和被重写

接口 interface 实现 implements

image-20221204004616866

接口和类是两个层面的东西

接口中的属性都是静态属性,方法都是抽象方法 都是public权限

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

        Computer computer = new Computer();
        Light light1 = new Light();
        Light light2 = new Light();
        
        computer.usb1 = light1;
        computer.usb2 = light2;
        computer.powerSupply();
    }
}
//所有USB接口都要继承的接口
interface USBInterface{
	
}
//提供电源的接口
interface USBSupply extends USBInterface{
    public void powerSupply();
}
//接收电源的接口
interface USBReceive extends USBInterface{
    public void powerReceive();//接受电源
}
//电脑类,实现提供电源的接口,用于提供电源
class Computer implements USBSupply{
    public USBReceive usb1; //电脑上接收电源的接口
    public USBReceive usb2; //电脑上接收电源的接口
    public void powerSupply() {
        System.out.println("电脑提供能源");
        usb1.powerReceive();
        usb2.powerReceive();
    }
}
//电灯类,实现了接收电源的接口,用于接受电源
class Light implements USBReceive{
    public void powerReceive() {
        System.out.println("电灯接受能源");
    }
}

枚举类 enum

枚举是一个特殊的类,他的对象不能在外部创建,只能在内部创建

image-20221204011144830

enum City{
    BEIJING,SHANGHAI;//这俩其实就是枚举类的对象,此时使用默认的无参构造
}
public class Java01_Variable {
    public static void main(String[] args) {
        System.out.println(City.BEIJING.code);
        System.out.println(City.SHANGHAI.name);

    }
}

enum City{
    //这俩其实就是枚举类的对象
    BEIJING("北京" ,1000),SHANGHAI("上海",1001);

    City(String name, int code) {
        this.name = name;
        this.code = code;
    }
    public String name;
    public int code;
}
自定义枚举类
public class Java01_Variable {
    public static void main(String[] args) {
        System.out.println(MyCity.BEIJING.code);
        System.out.println(MyCity.SHANGHAI.name);

    }
}

class MyCity{
    public String name;
    public int code;
	
    //使用private不然外部创建对象
    private MyCity(String name, int code) {
        this.name = name;
        this.code = code;
    }

    public static final MyCity BEIJING = new MyCity("北京",1000);
    public static final MyCity SHANGHAI = new MyCity("上海",1001);

}

匿名类

image-20221204012611931

匿名类可以用来实现抽象类和接口

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

        Fly fly = new Fly() {
            public void fly() {
                System.out.println("飞");
            }
        };
        fly.fly();

        Run run = new Run() {
            public void Run() {
                System.out.println("跑");
            }
        };
        run.Run();
    }
}

interface Fly{
    public void fly();
}
abstract class Run{
    public abstract void Run();
}

Bean规范

  1. 抽象类,接口这些主要用于编写逻辑
  2. 类主要用于建立数据模型(Bean)

第二种类就称为Bean类,建立的对象就称为Bean对象

  1. 需要有无参公共的构造函数
  2. 需要有private的属性,并提供公共的setter getter

image-20221204013528578

常用类和对象

Object类

java.lang.Object 是所有类的父类

toString()

把对象转为字符串

Object obj = new Person();
String str = obj.toString();

得到包名.类名@16进制表示的对象的内存地址(tips:这里的内存地址指的是是hashcode,hashcode大部分情况是内存地址)

image-20221204181708322

为了使得对象的内容变得更直观,我们也可以重写这个方法

Object obj = new Person();
String str = obj.toString();

class Person{
    public String name = "zhangsan";
    @Override
    public String toString(){
        return "Person : name = " + name;
    }
}
hashCode()

获取对象的10进制表示的内存地址(其实并不是真正的内存地址)

Object obj = new Person();
int i = obj.hashCode(); //i为十进制表示的内存地址
equals()

判断两个对象是否相等,默认比较内存地址

Object obj = new Person();
boolean b = obj.equals(new Person());  //false

可以重写equals()

getClass()

获取对象的类型名称

Object obj = new Object();
Class<?> aClass = obj.getClass();
System.out.println(aClass.getSimpleName()); //获取对象的类名
System.out.println(aClass.getPackageName()); //获取对象的包名

image-20221204185437935

数组

数组长度:数组.length

定义固定长度数组
int[] nums = new int[3];    	//默认为0
User[] users = new User[4]; 	//默认为null
String[] strs = new String[5];	//默认为null 不是空字符串

for (int num: nums){
    System.out.println(num);
}

定义的时候进行初始化

int[] nums = {1,2,3};
String[] strs = {"aaa","bbb","ccc"};
二维数组
int[][] nums = new int[3][4];

int[][] arr = new int[3][];// 此时一维数组还没有分配内存空间;arr[i]的地址为null;
    for (int i = 0; i < arr.length; i++) {
        // 给每个一维数组开辟空间,若没有这一步,一维数组的内存空间就是null
        arr[i] = new int[i + 1];
    }

java中的二维数组是并不是C++中那种行和列的数组,可以像下面这样每行个数不相等

在这里插入图片描述

java中是以这样排列实现的

image-20221204191322829

冒泡排序

每轮找到最大值或最小值,放到最后面或者最前面

一轮需要进行多次交换数据

选择排序

每轮找到最大值或最小值,放到最后面或者最前面

一轮只需要1次交换数据

二分查找

在排好序的数组中,每次拿查看剩余部分中间的那个数与目标数比较,以此来每次去掉一半数

字符串

创建字符串

java.lang.String

//因为JVM进行了优化,内存中只会有一个“zhangsan”
String name1 = "zhangsan";
String name2 = "zhangsan";
String name3 = "zhangsan";

//无需使用这种方式创建字符串对象
String name = new String("zhangsan");

用char数组生成String

char[] cs = {'a','1','中'};
String s = new String(cs); 

转义字符

\t \n \" \n \\
拼接 concat

“ + ” 拼接

数字也可以和字符串一起拼接

//下面两个String的hashcode是一样的,因为jvm优化了
String s1 = "a" + "b";
String s2 = "ab";

//会从左到右向加,数字之间做运算,数字字符串之间会将数字变为字符串
String s3 = 1 + "abc" + 2;	//1abc2
String s3 = 1 + 2 + "abc";	//3abc

concat()

String s1 = "12";
s1.concat("abc"); //12abc
比较 equals compareTo

**相等 equals() **

String s1 = "a";
s1.equals("A"); //false

忽略大小写判断相等 equalsIgnoreCase()

String s1 = "a";
s1.equalsIgnoreCase("A"); //true

大小比较 compareTo()

正数左边比右边大,负数左边比右边小,0相等

String a = "a";
String b = "b";
a.compareTo(b); //a和b相比较
截取 subString

subString()

需要两个参数:

第一个开始位置(下标,包含)

第一个结束位置(下标,不包含)

String a = "Hello World";
b = a.subString(0,3); //Hel

想截下Hello也可以这样

String a = "Hello World";
b = a.subString(0,"Hello".length()); //Hello

b = a.subString(6,a.length()); //World	

如果只提供一个参数,就是从指定位置截到最后

String a = "Hello World";
b = a.subString(6); //World
分解 split

split(字符) 按照指定字符分解字符串到数组中

String s = "Hello World ";
String[] strs = s.split(" "); 
去除首尾空格 trim

trim() 只会去掉首位空格,不会去掉中间空格

String a = "  Hello World  ";
String b = a.trim();//Hello World 
替换 replace

**replace(原来的字符串,修改的字符串) **

String a = "Hello World";
String b = a.replace("World","Java");//Hello Java

**replaceAll(规则,修改的字符串) ** 按照指定规则进行替换

String a = "Hello World zhangsan";
//这里规则使用了|表示这两种都进行替换
String b = a.replaceAll("World|zhangsan","Java");//Hello Java Java

大小写转换

**toLowerCase()**字符串全部变小写

**toUpperCase()**字符串全部变小写

Q:想把user变为User怎么办?

A:先截取u和ser出来,u变为大写后拼接

String a = “user";
String part1 = a.subString(0,1);
String part2 = a.subString(1);
part1 = part1.toUpperCase();
String result = part1 + part2;	//User
查找 indexOf contains

toCharArray() 字符串转为char数组

charAt() 返回指定下标的字符

getBytes(字符集) 得到编码数字

String s = "Hello World";
char[] chars = s.toCharArray();
s.charAt(1);//e
byte[] bytes = s.getBytes("UTF-8");

indexOf() 查找字符串在另一个字符串第一次出现的下标位置

lastIndexOf() 查找字符串在另一个字符串最后一次出现的下标位置

String s = "World Hello World";
s.indexOf("World"); //0
s.lastIndexOf("World"); //12

contains() 是否包含指定的字符串

String s = "Hello World";
s.contains("World"); //true

startsWith() 是否以指定字符串开头

endsWith() 是否以指定字符串结尾

String s = "World Hello World";
s.startsWith("World"); //true
s.endsWith("World"); //true

isEmpty() 判断字符串是否为空 空格字符串不算空

String a = "";
a.isEmpty(); //true
String b = "  ";
b.isEmpty(); //false
StringBuilder 效率高

用concat 或者 “+” 来拼接字符串效率很慢,因为每次拼接数字都需要创建字符串对象

image-20221204211759334

我们可以使用StringBuilder来提高效率

StringBuilder s = new StringBuilder();
for (int i = 0; i < 100; i++) {
    s.append(i);
}
System.out.println(s.toString());  //记得toString()

append(字符串) 拼接字符串

length() 获取长度

reverse() 反转

insert(下标,字符串) 插入字符串

包装类

让基本数据类型有了类的概念

int => Integer

char => Character

别的都是首字母大写

image-20221204212648773

装箱
int i = 10;
Integer integer = new Integer(i);  		//不推荐使用了

Integer integer = Integer.valueOf(i);   //推荐
Integer integer = i; 					//自动装箱,本质使用了valueOf
拆箱
int i = integer.intValue();
int i = integer;						//自动拆箱,本质使用了intValue

日期类 Date

java.util.Date (注意不是sql下的Date)

System.currentTimeMillis();   //从1970以来的到现在的毫秒数(时间戳)

获取到日期后,还需要进行格式修改

使用 java.text.SimpleDateFormat 进行格式化

image-20221204214155001

日期转字符串

format()

Date date = new Date();
SimpleDateFormat simpleDateFormat =
    new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");   //设定格式
String format = simpleDateFormat.format(date);		   //传入日期
System.out.println(format);
字符串转日期

parse() 解析

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
String dataString = "2022-06-21";
Date parseData = simpleDateFormat.parse(dataString);
System.out.println(parseData);
日期类的一些操作

setTime() 设置时间戳

getTime() 获取时间戳

before(Date) 判断对象的的日期是否在括号内的之前

after(Date) 判断对象的的日期是否在括号内的之后

Date date1 = new Date();
date1.setTime(System.currentTimeMillis());
System.out.println(date1.getTime());

Thread.sleep(1000);

Date date2 = new Date();
System.out.println(date2.getTime());

System.out.println(date1.before(date2)); 	//true
System.out.println(date1.after(date2));		//false

日历类 Calendar

Calendar是一个抽象类无法创建对象,所有使用getInstance()获取实例

Calendar instance = Calendar.getInstance();
System.out.println(instance);

//java.util.GregorianCalendar[time=1670171217516,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=31,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2022,MONTH=11,WEEK_OF_YEAR=50,WEEK_OF_MONTH=2,DAY_OF_MONTH=5,DAY_OF_YEAR=339,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=26,SECOND=57,MILLISECOND=516,ZONE_OFFSET=28800000,DST_OFFSET=0]
获取年月日
System.out.println(instance.get(Calendar.YEAR));
//注意月份从0开始,所有会少一个月
System.out.println(instance.get(Calendar.MONTH));  
System.out.println(instance.get(Calendar.DATE));

instance.add(Calendar.YEAR,-1);  //可以修改

使用日期类Date给日历类时间
instance.setTime(new Date());
打印一个日历

这里需要注意的就是 Calendar.DAY_OF_WEEK 是从周日开始的(1开始)

System.out.println("一\t二\t三\t四\t五\t六\t日");
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH, 1); //设为当月第一天
int maxDay = calendar.getMaximum(Calendar.DAY_OF_MONTH);  //获取当月总天数
for (int i = 0; i < maxDay; i++) {
    int weekX = calendar.get(Calendar.DAY_OF_WEEK); //获取周几
    int monthY = calendar.get(Calendar.DAY_OF_MONTH); //获取几号
    if(i == 0){
        //每月一号需要判断亲密要空多少制表符
        if(weekX == Calendar.SUNDAY) {
            //周日需要前面6个制表符然后换行
            for (int j = 0; j < 6; j++) {
                System.out.print("\t");
            }
            System.out.println(monthY);
        }else{
            //周一到六需要计算制表符
            //weekX 从周日开始算 周日是1 周一是2 周二是3 周三是4
            // 所以需要的制表符应该是weekX-2
            for (int j = 0; j < weekX - 2; j++) {
                System.out.print("\t");
            }
            System.out.print(monthY + "\t");
        }
    }else{
        //不是一号的话
        if(weekX == Calendar.SUNDAY){
            //周日需要换行
            System.out.println(monthY);
        }else{
            //周一到六需要制表符
            System.out.print(monthY + "\t");
        }
    }
    //增加一天
    calendar.add(Calendar.DATE,1);
}

自定义工具类

image-20221205010931615

判断字符串是否为空

这里的是否为空是自己定义的

  1. 字符串为null为空
  2. 字符串为空字符串为空
  3. 字符串中都是空格为空
public static boolean isEmpty(String str){
    //2 3 两点进行了合并
    if(str == null || "".equals(str.trim())){
        return true;
    }
    return false;
}
生成随机字符串

纯随机字符串

public static String makeString(){
    return UUID.randomUUID().toString();
}
生成指定随机字符串

要求字符串从给定范围选,长度限定

public static String makeString(String from, int len) {
    if (len < 1) {
        return "";
    }else{
        char[] chars = from.toCharArray();
        StringBuilder str = new StringBuilder(); //StringBuilder效率高
        for (int i = 0; i < len; i++) {
            Random random = new Random();
            //随机生成一个索引
            int index = random.nextInt(chars.length);
            //获取随机索引对应的字符
            char c = chars[index];
            str.append(c);
        }
        return str.toString();
    }
}
转换字符串字符集

ISO8859-1 => str => UTF-8

public static String transform(String source, String encodeFrom, String encodeTo) throws UnsupportedEncodingException {
    byte[] bytes = source.getBytes(encodeFrom);
    return new String(bytes,encodeTo);
}
日期类和字符串互转
//字符串转日期
public static Date parseDate(String dateString, String format) throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    return  sdf.parse(dateString);
}

//日期转字符串
public static String formatDate(Date date, String format) throws Exception {
    SimpleDateFormat sdf = new SimpleDateFormat(format);
    return  sdf.format(date);
}

比较

结论:基本数据类型用== 引用数据类型用equals()

int a = 10 float b = 10.0 这俩相等

字符串用双引号的会在字符串常量池生成

字符串new出来的不在字符串常量池

image-20221205014538110

对象之间比较用== 和 equals 是一样的,因为equals方法中用的也是==

所以我们想要比较内容需要重写equals

一般重写时也会重写hashCode方法

包装类型
Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1 == i2); //true

Integer i1 = 200;
Integer i2 = 200;
System.out.println(i1 == i2); //false

Q:这是为什么呢?

A:因为装箱使用的是valueOf 可以在看下面到这里如果数值不在缓存内,就会重新创建包装类对象

缓存的范围是 -128 to 127

@IntrinsicCandidate
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

所以包装类最好使用equals()来比较大小

包装类的equals是进行拆箱后再比较的

异常

分为运行期异常和编译期异常

RuntimeException编译时不会给你提示

image-20221205020503550

语法

image-20221205021332293

int i = 0;
int j = 0;

try {
    j = 10 / i;
}catch (ArithmeticException e){
    e.getMessage(); // by zero
    e.getCause(); 	// null
    e.printStackTrace(); //打印堆栈信息见下图
}finally {

}
image-20221205021711973

常见异常

运行时异常 通过编程能够解决的异常

  1. java.lang.ArithmeticException 算术异常 除数为0
  2. java.lang.NullPointerException 空指针异常
  3. java.lang.ArrayIndexOutOfBoundsException 数组越界
  4. java.lang.StringIndexOutOfBoundsException 字符串索引越界
  5. java.lang.NumberFormatException 格式化异常
  6. java.lang.ClassCastException 类型转换错误
  1. java.lang.StringIndexOutOfBoundsException 例子

    String s = "abc";
    s.charAt(3);
    s.subString(4);
    
  2. java.lang.NumberFormatException 格式化异常例子

    String s = "abc";
    Integer i = Integer.parseInt(s);
    
  3. java.lang.ClassCastException 类型转换错误

    Object a = new A();
    B b = (B)a;
    
    class A{
    }
    class B{
    }
    

抛出异常

给调用者处理异常 throws 和 throw别看错了

  1. throws 抛出异常给上级

image-20221205024328143

  1. throw 手动抛出异常

image-20221205024729746

3.调用者处理异常

image-20221205024834082

自定义异常

自定义异常需要继承自RuntimeException

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

        String account = "admin";
        String password = "123";
		
        //处理账号和密码异常
        try {
            login(account,password);
        }catch (AccountException accountException){
            System.out.println("账号不正确,需要重写修正");
        }catch (PasswordException passwordException){
            System.out.println("密码不正确,需要重写修正");
        }catch (LoginException loginException){
            System.out.println("登录相关的其他错误,需要重写修正");
        }


    }
    
    //如果账号和密码有错误就抛出异常给调用者
    public static void login(String account, String password) throws LoginException{
        if(!"admin".equals(account)){
            throw new AccountException("账号不正确");
        }
        if(!"admin".equals(password)){
            throw new PasswordException("密码不正确");
        }
        System.out.println("登录成功");
    }
}

//账号异常 继承自 登录异常
class AccountException extends LoginException{
    public AccountException(String message) {
        super(message);
    }
}
//密码异常 继承自 登录异常
class PasswordException extends LoginException{
    public PasswordException(String message) {
        super(message);
    }
}

//登录异常 继承自 运行时异常
class LoginException extends RuntimeException{
    public LoginException(String message){
        super(message);
    }
}

进阶语法

集合

定义

集合是容纳数据的容器

image-20221205181858943

根据存储数据的不同,Java的集合分为两大体系

  1. 单一数据体系: Collection接口定义的相关规则
  2. 键值对(Key,Value):Map接口定义了相关规则

常用接口和类

java.base.java.util 下有很多类和接口

Collection接口

常用子接口

  1. List : 按照插入顺序保存数据,数据可以重复

    ​ 具体实现类 ArrayList LinkList

  2. Set : 集,无需保存,数据不能重复

    ​ 具体实现类 HashSet

  3. Queue : 队列

    ​ 具体实现类 ArrayBlockingQueue

Ctrl + H 可以查看这些类和接口的层次结果

image-20221205182447570

Map接口

具体实现类 HashMap Hashtable

image-20221205183047958

Collection接口

单一数据体系

ArrayList类

底层由数组实现,数据可重复

image-20221205183723052

创建ArrayList对象

一共三种创建方式

  1. 无参,底层为空数组
  2. 传一个int,用于设定底层数组长度
  3. 传一个Collection集合类型的值,用于把其他集合中的数据放置在当前集合中
ArrayList list = new ArrayList();
ArrayList list = new ArrayList(10);

image-20221205184726047

增加数据 add

add()

添加数据时,如果ArrayList集合中没有任何数据,那么底层会创建长度为10的数组

ArrayList list = new ArrayList();
list.add("zhangsan");

添加数据时如果底层数组不够用了会自动扩容

创建一个长度更长的新数组,然后基本数据类型已过去,引用数据类型把指针移过去,然后弃用旧数组

指定下标插入数据,后面的会后移

list.add(1,"zhangsan");
image-20221205191637713

addAll(otherList)

可以把其他List加入到末尾

ArrayList list = new ArrayList();
ArrayList otherList = new ArrayList();
list.addAll(otherList);
查看长度 size
list.size();
判空和清空
list.isEmpty(); //判空
list.cleat();	//清空
获取数据 get

获取指定下标的数据

list.get(1);  //获取下标为1的数据,也就是第二个
遍历

这种遍历会按照顺序输出

ArrayList list = new ArrayList();
for(int i = 0; i < list.size(); i++){
	sout(list.get(i)); 
}

如果不关心数据输出顺序的话,可以使用下面这种增强for循环

ArrayList list = new ArrayList();
for(Object obj : list){
	sout(obj); 
}
修改数据 set

修改指定下标的数据,会返回修改下标位置的旧值

ArrayList list = new ArrayList();
//把下标1处修改为zhangsan并返回旧值
Object objVal = list.set(1,"zhangsan"); 
删除数据 remove

删除指定下标的数据,会返回删除下标位置的旧值

ArrayList list = new ArrayList();
//把下标1处数据删除并返回该值
Object removeVal = list.remove(1); 

removeAll(otherList) 删除另一个List中有的数据

ArrayList list = new ArrayList();
ArrayList otherList = new ArrayList();
list.addAll(otherList);

list.remove(otherList); //删除otherList
判断是否包含 contains

contains() 判断是否包含某个数据

ArrayList list = new ArrayList();
list.contains("zhangsan");
获取数据位置

indexOf() 获取数据在集合中第一次出现的的下标,不存在返回-1 , 有多个只会返回第一个

lastIndexOf()* 获取数据在集合中最后一次出现的的下标,不存在返回-1

list.indexOf("zhangsan");
list.lastIndexOf("zhangsan");
集合转数组 toArray
Object[] objs = list.toArray();
克隆集合 clone

clone() 是转为通用Object类型

Object clone = list.clone();
ArrayList list1 = (ArrayList)clone;
LinkedList类

带首尾指针的双向链表

image-20221205194551272

image-20221205194608992

创建LinkedList对象
LinkedList list = new LinkedList();
添加数据 add

add()

list.add("zhangsan");

add(index,element) 在指定下标添加数据

这种链表本来是没有下标的,但是我们把放入的数据从0开始当作有下标

list.add(1,"zhangsan");

addFirst() 在首部添加

addLast() 在尾部添加

addAll(otherList)

可以把其他List加入到末尾

LinkedList list = new LinkedList();
LinkedList otherList = new LinkedList();
list.addAll(otherList);
获取数据 get

可以获取首尾的数据

list.getFirst();
list.getLast();

获取指定下标的数据

list.get(1);
遍历

这种遍历会按照顺序输出

LinkedList list = new LinkedList();
for(int i = 0; i < list.size(); i++){
	sout(list.get(i)); 
}

如果不关心数据输出顺序的话,可以使用下面这种增强for循环

LinkedList list = new LinkedList();
for(Object obj : list){
	sout(obj); 
}
修改数据 set

修改指定下标的数据,会返回修改下标位置的旧值

LinkedList list = new LinkedList();
//把下标1处修改为zhangsan并返回旧值
Object objVal = list.set(1,"zhangsan"); 
删除数据 remove

删除指定下标的数据,会返回删除下标位置的旧值

LinkedList list = new LinkedList();
//把下标1处数据删除并返回该值
Object removeVal = list.remove(1); 

list.remove(“zhangsan“);  //也可直接删除数据

remove() 无参表示删除第一个

removeFirst() 删除第一个

removeLast() 删除最后一个

其他常用操作
list.clear() //清除
list.contains("zhangsan") //是否包含
list.isEmpty();	//是否为空
list.size();	//长度
list.element();	//获取第一个数据

list.indexOf("zhangsan"); 	//获取第一次出现的下标
list.lastIndexOf("zhangsan"); 	//获取最后一次出现的下标
//首位置添加数据
list.push("zhangsan");
//首位置弹出数据
list.pop();
HashSet类

数据不可重复无序,如果同个数据第二次出现,经过hash算法后和第一次相同,结果不会放入

image-20221205233454878

创建HashSet
HashSet hashSet = new HashSet();
增加数据 add

add()

HashSet hashSet = new HashSet();
hashSet.add("a");
hashSet.add("b");
hashSet.add("c");

addAll() 把另一个集合放入这个集合

HashSet hashSet = new HashSet();
hashSet.add("a");
hashSet.add("b");
hashSet.add("c");

ArrayList arrayList = new ArrayList();
arrayList.add("zhangsan");
arrayList.add("lisi");

hashSet.addAll(arrayList);  
/*
a
lisi
b
c
zhangsan
*/
删除数据 remove
hashSet.remove("b");
修改数据

HashSet无法直接修改,因为哈希算法的存在你无法把新的放到旧的那个位置

可以通过先删除再增加来实现

//b 改为 d
hashSet.remove("b");
hashSet.add("d");
遍历
for (Object obj :
     hashSet) {
    System.out.println(obj);
}
转为数组 toArray
Object[] objects = hashSet.toArray();
for (Object obj :
     objects) {
    System.out.println(obj);
}
其他常用方法
hashSet.isEmpty();
hashSet.size();
hashSet.contains("a"); //是否包含a

Object clone = hashSet.clone(); //克隆后强转
HashSet hashSet1 = (HashSet) clone;
重复数据

Q:如果有同个类的两个对象,他们的属性数据全都一样,放入HashSet后,他们是相同的吗

A:不相同,还是两个不同的数据

这里三个都可以成功存进去

image-20221205235740766

如果想要让HashSet认为user1 和 user2 为相同的数据的话,我们需要重写HashCode 和 equals方法

public class Java01_Variable {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        
        User user1 = new User();
        user1.id = 1001;
        user1.name = "zhangsan";

        User user2 = new User();
        user2.id = 1001;
        user2.name = "zhangsan";

        User user3 = new User();
        user3.id = 1002;
        user3.name = "lisi";

        hashSet.add(user1);
        hashSet.add(user2);
        hashSet.add(user3);

        for (Object obj :
                hashSet) {
            System.out.println(obj);
        }
        //可以看到只有两个了
        //User[1001,zhangsan]
		//User[1002,lisi]
    }
}

class User{
    int id;
    String name;

    //重写hashCode,让其用id来进行hash
    @Override
    public int hashCode() {
        return id;
    }

    //重写equals,判断两个对象是否相等
    @Override
    public boolean equals(Object obj) {
        // 先判断类对不对,也是为了之后强转
        if( obj instanceof User){
            User otherUser = (User)obj;
            if(otherUser.id == this.id){
                if(otherUser.name.equals(this.name)){ //这里为了方便没判断空
                    return true;
                }
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return "User["+id+","+name+"]";
    }
}

如果id相同但是name不同的话,就发生了hash碰撞,会把第二个以链表的形式接在第一个数据的后面

image-20221206003348737

Queue类

按照顺序,先进先出

ArrayBlockingQueue类 存满了会堵塞

image-20221206002051305

创建对象
ArrayBlockingQueue queue = new ArrayBlockingQueue(3);
存入数据

三种方式存入

queue.add("a");		//满了再存直接报错
queue.put("b");		//满了再存会一直等待
boolean b = queue.offer("c");   //返回是否存入成功
取出数据
queue.poll();	//取完了再取返回null
queue.take();	//取完了再取会一直等待

Map接口

键值对类型

HashMap类

存储无序,不能重复,根据key判断是否相同

与HashSet不同的是,HashMap有覆盖的概念

如果两个Key一样,Value不一样的键值对放入HashMap,后面放入的会覆盖掉前面的

image-20221206004039021
HashMap hashMap = new HashMap();
hashMap.put("a","zhangsan");
hashMap.put("a","lisi"); //覆盖
System.out.println(hashMap.get("a")); //lisi

而如果Key不同,但是经过hash计算后结果相同的话,就会发生hash碰撞

这时候会继续往下链,但是如果长了以后相率非常慢,JDK使用红黑树进行优化

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2SuFgVf-1670268579457)(https://qiuyusy-img.oss-cn-hangzhou.aliyuncs.com/img/202212060320637.png)]

创建对象
HashMap hashMap = new HashMap();
添加修改数据 put

put() 如果key本来就已经有了就会覆盖(等于修改),并返回被覆盖的值

hashMap.put("a","zhangsan");
hashMap.put("b","lisi");

//如果key本来就已经有了就会覆盖,并返回被覆盖的值
Object oldValue = hashMap.put("a","123");  //zhangsan

putIfAbsent() 如果map中key不存在就放入,如果key以及存在就不放入

hashMap.putIfAbsent("b","456");

replace() 替换修改数据,如果key不存在返回null,存在返回被替换的值(真正的修改函数)

hashMap.replace("b","456");
获取数据 get
hashMap.get("a");
删除数据 remove
hashMap.remove("a");  //key对上就删

hashMap.remove("a","zhangsan"); //key和value都对上才删
获取所有Key

获取Map集合总所有的Key

HashMap hashMap = new HashMap();

hashMap.put("a","zhangsan");
hashMap.put("c","lisi");
hashMap.put("b","wangwu");

Set set = hashMap.keySet();
System.out.println(set);
//[a, b, c]
获取所有键值对

不加泛型时

HashMap hashMap = new HashMap();

hashMap.put("a","zhangsan");
hashMap.put("c","lisi");
hashMap.put("b","wangwu");

Set set = hashMap.entrySet();

for (Object o : set) {
    System.out.println(o);
}
//a=zhangsan
//b=wangwu
//c=lisi

加泛型时

HashMap<String,String> hashMap = new HashMap();

hashMap.put("a","zhangsan");
hashMap.put("c","lisi");
hashMap.put("b","wangwu");

Set<Map.Entry<String, String>> entries = hashMap.entrySet();

for (Map.Entry<String, String> entry : entries) {
    System.out.println(entry.getKey() +"="+ entry.getValue());
}
//a=zhangsan
//b=wangwu
//c=lisi
常用方法
hashMap.clear();				//清空
hashMap.containsKey("a");		//判断map集合中有无指定key
hashMap.containsValue("123");	//判断map集合中有无指定value

Hashtable类

注意t是小写

和HashSet的区别

  1. 继承的类不一样,Hashtable 继承自 Dictionary
  2. 底层容量不同,HashMap默认容量16 Hashtable默认容量11
  3. HashMap的K,V都可以为null Hashtable K,V都不能为null
  4. 底层做Hash运算不一样,HashMap采用Hash算法,Hashtable采hashcode方法
  5. 性能差别,HashMap性能较高,Hashtable较低因为考虑多线程冲突
基本操作

和HashMap基本一样

迭代器
为什么要用迭代器

下面的代码运行会报错,这是因为再遍历的中途把hashMap的中间一个键值对给删了

但是Set并不知道,所以还会往下遍历,导致出错

HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("a",1);
hashMap.put("b",2);
hashMap.put("c",3);

Set<String> keys = hashMap.keySet();

for (String key : keys) {
    if("b".equals(key)){ //如果这里b改为c不会报错,因为以及遍历到后面了前面无所谓
        hashMap.remove("b");
    }
    System.out.println(hashMap.get(key));
}

Q:那有没有办法再修改map的时候,把map改变了通知set呢?

A:使用迭代器

迭代器使用
HashMap<String, Integer> hashMap = new HashMap<>();
hashMap.put("a",1);
hashMap.put("b",2);
hashMap.put("c",3);

Set<String> keys = hashMap.keySet();

Iterator<String> iterator = keys.iterator();
//hasNext() 用于判断有没有下一条数据
while (iterator.hasNext()){
    String key = iterator.next();
    if("b".equals(key)){
        //使用迭代器来删除,会同时更新数据
        iterator.remove(); //注意remove只能对当前数据删除,不能对别的数据删除
    }
    System.out.println(hashMap.get(key));
}

//1
//null
//3

泛型

约束集合的数据类型

image-20221205203558114

为什么要使用泛型

从集合中取出的对象类型为Object

因为多态限制的原因,父类Object并不能使用子类的方法

image-20221205201815304

如果此时想要使用子类的方法,就需要进行类型强转

image-20221205202025448

但是此时问题又出现了,集合内部可能会发生变化,不能确定取出的对象的类型

这就可能发生类型转换错误

所以拿出来前还需要进行类型的判断 这种太麻烦了

image-20221205202551034

如何使用泛型

原本集合内可以存各种类型的数据,使用泛型直接把集合限定为只能使用某一种类型

有时泛型也称为类型参数

此时不设定泛型,那么data的类型是什么都可以

public class Java01_Variable {
    public static void main(String[] args) {
        MyContainer myContainer = new MyContainer();
        //此时不设定泛型,那么data的类型是什么都可以
        myContainer.data = new Object();
    }
}

//这里的C表示类 
class MyContainer<C>{
    public C data;
}

class User{
}

此时设定泛型,那么data的类型只能是User

public class Java01_Variable {
    public static void main(String[] args) {
        //此时设定泛型,那么data的类型只能是User
        MyContainer<User> myContainer = new MyContainer();
        myContainer.data = new User();
    }
}

class MyContainer<C>{
    public C data;
}

class User{
}
注意

Q:Object是User的父类,限定为Object的泛型,输入Object的子类User可以吗?

A:不行,泛型没有多态

public class Java01_Variable {
    public static void main(String[] args) {
        MyContainer<User> myContainer = new MyContainer();
        test(myContainer);
    }

    public static void test(MyContainer<Object> myContainer){
        System.out.println(myContainer); //报错!
    }
}

class MyContainer<C>{
    public C data;
}

class User{
}

image-20221205204509035

比较器接口

可以用于排序

需要去实现Comparator接口,重写compare方法

package chapter02;


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

public class Java01_Variable {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(1);
        list.add(3);
        list.add(2);
		
        //sort 需要传入一个Comparator比较器
        list.sort(new NumberComparator());
        System.out.println(list);
    }


}
//需要实现Comparator接口
class NumberComparator implements Comparator<Integer>{
    //需要重写compare方法
    @Override
    public int compare(Integer o1, Integer o2) {
        //如果第一个数大,返回正数,表示增序
        return o1-o2;
        //如果第二个数大,返回负数,表示降序
        //return o2-o1;
        //如果两个数一样大,返回0
		//return 0;
    }
}

工具类

静态方法

Arrays类

java.util.Arrays

toString() 方便打印出具体数据

int[] i = {1,2,3,4};
System.out.println(Arrays.toString(i));
System.out.println(i);
//[1, 2, 3, 4]
//[I@776ec8df

asList() 数组、数字变集合

int[] i = {1,2,3,4};
List<int[]> ints = Arrays.asList(i);
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);

sort() 排序,默认升序

int[] i = {2,3,4,7,8,9,1};
Arrays.sort(i);
System.out.println(Arrays.toString(i));

binarySearch() 二分查找,注意这个返回的是排序后的下标

int[] i = {7,8,9,1,4};

Arrays.sort(i); //排序

int index = Arrays.binarySearch(i,4);
System.out.println(index);

equals() 判断数组相不相等 数据和数据的顺序都相等才算相等

int[] a = {7,8,9,1,4};
int[] b = {7,8,9,1,4,5};

System.out.println(Arrays.equals(a, b));  //false

选取范围比较

int[] a = {7,8,9,1,4};
int[] b = {7,8,9,1,4,5};

Arrays.equals(a,0,3, b,0,3);  //true

集合异常

java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 0

List 的索引范围和数组不同,List的是0~实际数据的长度-1

image-20221206014916492

java.util.NoSuchElementException

LinkedList list = new LinkedList();
list.getFirst();  //此时还没有第一个数据

java.util.ConcurrentmodificationException

因为修改了数据数量,只改值没事

image-20221206015435124
ss Java01_Variable {
public static void main(String[] args) {
MyContainer myContainer = new MyContainer();
test(myContainer);
}

public static void test(MyContainer<Object> myContainer){
    System.out.println(myContainer); //报错!
}

}

class MyContainer{
public C data;
}

class User{
}




<img src="https://qiuyusy-img.oss-cn-hangzhou.aliyuncs.com/img/202212060320642.png" alt="image-20221205204509035" style="zoom:50%;" />



#### 比较器接口

可以用于排序

需要去实现Comparator接口,重写compare方法

~~~java
package chapter02;


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

public class Java01_Variable {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(1);
        list.add(3);
        list.add(2);
		
        //sort 需要传入一个Comparator比较器
        list.sort(new NumberComparator());
        System.out.println(list);
    }


}
//需要实现Comparator接口
class NumberComparator implements Comparator<Integer>{
    //需要重写compare方法
    @Override
    public int compare(Integer o1, Integer o2) {
        //如果第一个数大,返回正数,表示增序
        return o1-o2;
        //如果第二个数大,返回负数,表示降序
        //return o2-o1;
        //如果两个数一样大,返回0
		//return 0;
    }
}

工具类

静态方法

Arrays类

java.util.Arrays

toString() 方便打印出具体数据

int[] i = {1,2,3,4};
System.out.println(Arrays.toString(i));
System.out.println(i);
//[1, 2, 3, 4]
//[I@776ec8df

asList() 数组、数字变集合

int[] i = {1,2,3,4};
List<int[]> ints = Arrays.asList(i);
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);

sort() 排序,默认升序

int[] i = {2,3,4,7,8,9,1};
Arrays.sort(i);
System.out.println(Arrays.toString(i));

binarySearch() 二分查找,注意这个返回的是排序后的下标

int[] i = {7,8,9,1,4};

Arrays.sort(i); //排序

int index = Arrays.binarySearch(i,4);
System.out.println(index);

equals() 判断数组相不相等 数据和数据的顺序都相等才算相等

int[] a = {7,8,9,1,4};
int[] b = {7,8,9,1,4,5};

System.out.println(Arrays.equals(a, b));  //false

选取范围比较

int[] a = {7,8,9,1,4};
int[] b = {7,8,9,1,4,5};

Arrays.equals(a,0,3, b,0,3);  //true

集合异常

java.lang.IndexOutOfBoundsException: Index 1 out of bounds for length 0

List 的索引范围和数组不同,List的是0~实际数据的长度-1
在这里插入图片描述

java.util.NoSuchElementException

LinkedList list = new LinkedList();
list.getFirst();  //此时还没有第一个数据

java.util.ConcurrentmodificationException

因为修改了数据数量,只改值没事

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/64617.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL索引事务——小记

文章目录索引概念page索引类型B树vsB树主键索引非聚簇索引覆盖索引复合索引/联合索引优化基于B树的索引hash索引事务事务的特性ACID问题隔离级别索引 概念 使用一定的数据结构&#xff0c;来保存索引字段&#xff08;一列或多列&#xff09;对应的数据。以后根据索引字段来检…

低代码常见场景【上】|如何解决业务问题

全文 2105 字 阅读时间约 7 分钟 首发于码匠技术博客 目录 低代码用例 用于解决业务问题的低代码用例 内部系统开发所面临的困境 低代码如何解决上述困境 关于码匠 低代码平台通过在开发和部署应用程序时最大限度地减少编程来减轻 IT 团队的压力&#xff0c;不仅可以帮助…

[附源码]Python计算机毕业设计Django农村人居环境治理监管系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Java+MySQL 基于Springboot的垃圾分类网站-计算机毕业设计

项目介绍 当前全球都在提倡环境保护&#xff0c;现在社会高速发展&#xff0c;我们每个人每天都会产生很多的垃圾&#xff0c;尤其是工业发展到一定阶段之后这些垃圾的种类也越来越多&#xff0c;如果随意丢弃很可能会造成环境污染&#xff0c;尤其是一些电池等重污染垃圾&…

前端模块化开发

1.模块化产生的背景 Javascript模块化编程&#xff0c;已经成为一个迫切的需求。理想情况下&#xff0c;开发者只需要实现核心的业务逻辑&#xff0c;其他都可以加载别人已经写好的模块。 但是&#xff0c;Javascript不是一种模块化编程语言&#xff0c;它不支持"类&quo…

持续的敏捷转型--我们的经验

作者&#xff1a;Shalini Joshi、 Syed Tamkeen Banu 在这篇文章中&#xff0c;我们将分享自己的经验和教训&#xff0c;说明组织可能在哪些方面会失败&#xff0c;以及可以采取哪些积极措施。 一、简介 如今&#xff0c;大多数组织为了获取更快的交付、更高的商业价值和更好的…

Markdown使用模板

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

智能仓储机器人设计

目录 第一章 绪论 1 1.1 研究的背景与意义[1] 1 1.2 机器人的研究现状[4] 2 1.3机器人的发展趋势 4 1.4本文的主要研究内容 5 第二章 机器人总体方案设计 7 2.1 小型仓储机器人的功能 7 2.2 传感器系统[13] 7 2.3 移动载体 7 2.4 自由度与机器人的运作 8 2.5 控制方式的选择 9 …

Git使用及配置

一、下载安装 网上很多教程我就不出了&#xff0c;hh 二、配置 1.设置用户信息 //设置用户信息 git config --global user.name"xxx" git config --global user.email"xxxxx.xxx" 三、获取本地仓库 1.在电脑上创建一个空目录作为本地Git仓库 2.进入这…

【Redis】初识Redis

1.初识Redis1.1安装1.2数据结构1.2.1 通用命令1.2.2 String类型key的结构1.2.3 Hash类型2.Jedis2.1 添加依赖及配置2.2 配置StringRedisTemplte1.初识Redis Redis是一个基于内存的键值型NoSQL数据库。其具有性能优越、持久化的特点&#xff0c;能够支持每秒十几万次的读写操作…

前端面试题之【HTTP/HTML/浏览器】

1.说一下http与https http&#xff1a;超文本传输协议&#xff0c;https&#xff1a;超文本传输安全协议 区别&#xff1a; http传输数据是未加密的&#xff0c;是明文传输&#xff1b;https使用ssl协议对数据进行加密处理&#xff1b;https协议需要ca证书&#xff0c;费用高…

【VUE 嵌套路由】

目录 1. 嵌套路由 2. 通俗小结 1. 嵌套路由 要使用菜单显示出“点击不同的菜单项显示不同的内容”的效果&#xff0c;需要使用嵌套路由&#xff01; 因为&#xff0c;在当前设计中&#xff0c;App.vue是显示整个页面的入口&#xff0c;而App.vue就已经使用<router-view/…

应急物资仓库管理系统-3D可视化管理系统

1. 系统介绍 RFID智慧应急物资仓库可视化管理系统是杭州东识科技有限公司基于物联网RFID技术、云计算技术、3D可视化技术、数据采集技术等&#xff0c;专门为政府、军队等部门量身定制的一体化物资综合管理平台。 本系统包括&#xff1a;物资安全监控部分——提供对环境温湿度监…

[附源码]Python计算机毕业设计Django失物招领微信小程序论文

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Slowloris DoS攻击的原理与简单实现

前言 Slowloris 攻击是我在李华峰老师的书——《Metasploit Web 渗透测试实战》里面看的&#xff0c;感觉既简单又使用&#xff0c;现在这种攻击是很容易被防护的啦。不过我也不敢真刀实战的去试&#xff0c;只是拿个靶机玩玩罢了。 废话还是写在结语里面吧。&#xff08;划掉&…

Java 中重写了 equals 为什么还要重写 hashCode?

问题 不管是在书本或者是博客上&#xff0c;都会推荐我们在重写 equals 方法时重写 hashCode 方法。明明对象之间就是通过 equals 方法进行判断的&#xff0c;那么为什么非要写 hashCode 方法呢? equals 实验 创建一个 Teacher 类。方便起见&#xff0c;就一个 name 属性。…

1.1 异步相关概念:初步了解

1.进程和线程的概念 计算机有5大基本组成部分&#xff0c;运算器&#xff0c;控制器&#xff0c;存储器&#xff0c;输入和输出。运算器和控制器封装到一起&#xff0c;加上寄存器组和cpu内部总线构成中央处理器&#xff08;CPU&#xff09;。cpu的根本任务&#xff0c;就是执…

2022年跨境电商卖家如何在Facebook上做广告【完整指南】

关键词&#xff1a;跨境电商卖家、Facebook广告 了解如何在 Facebook 上做广告对于大多数跨境电商卖家来说是一项非常重要的技能&#xff0c;因为您在 Facebook 上做广告&#xff0c;您的广告可以覆盖21.7 亿人——换句话说&#xff0c;接近世界人口的 30%。此外&#xff0c;该…

Java项目:SSM物业缴费管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 管理员角色包含以下功能&#xff1a; 管理员登录,管理员管理,住户管理,缴费列表,公告列表管理,用户反馈管理等功能。 用户角色包含以下功能&…

[附源码]计算机毕业设计失物招领微信小程序论文Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…