Java学习

java体系平台

  • JavaSE 标准版 像开发360,百度网盘
  • JavaEE 企业版
  • JavaME 

JDK=JRE+开发工具集 JRE=JVM+JAVA SE API(即JavaSE标准类库

常用基本命令行

  • 更改盘符 d:
  • 打开文件 cd 路径
  • 查看文件目录 dir
  • 新建文件夹 md name
  • 退回上一级 cd..
  • 删除文件夹 rd name
  • 删除文件 del name
    注释
    Java特有文档注释
    可以被javadoc解析 生成一个以网页形式出现的文件,页面效果类似JavaAPI文档说明

    1.Java编译过程

    1.编写

    创建一个HELLOWORLD.java文件

class HELLOCHIMA{

}

2.编译

javac HELLOWORLD.java

3.运行

java HELLOCHINA

2.Java命名规范

包名:所有字母都小写

类名,接口名:所有单词的首字母大写

变量名,方法名:第一个单词首字母小写,后面的单词首字母大写

常量名:所有字母都大写,每个单词用下划线连接

3.Java数据类型

基本数据类型

​ 整型:byte(1)、short(2), int(4), long(8,long型变量必须以大写L或者小写l结尾)

​ 浮点型:float(4,7位小数,后面必须加F或f,表示范围比long还大), double(8,14位小数)

​ 字符型:char(2)

​ 布尔型:boolean

引用数据类型

​ 类(class)

​ 接口(interface)

​ 数组(array)

自动类型提升

byte,short,char—–>int——->long——>float——->double

当byte,short,char三种进行运算时,结果都为int

强制类型转化

可能会导致精度损失

string类

不可以有子类,String常量放入常量池(常量池中的数据在运行期间在也不允许改变)

  • equals:比较的是值
  • startsWith(String s)//判断当前String对象的字符序列前缀是否含有s的字符
  • endsWith(String s)
  • str1.compareTo(“s2”)//s1与s2比较
  • s1.contains(“s2”)
  • Arrays.sort(b)
  • getChars(int start,int end,char,int offset)
    字符串类型。引用数据类型 ,拼接运算+

system.out.println(‘a’+’/t’);//输出107

system.out.println(‘a’+“/t”+’a’);//输出a a

String与StringBuffer

  • StringBuffer为可修改的对象
  • StringBuffer性能更优于String,线程安全允许并发

    进制转化

1.二进制 0b或者0B

2.八进制 0开头

3.十进制

4.十六进制 0x或者0X

正数的原码,补码,反码一样

正数的符号位是0,负数的符号位是1

负数

反码:在原码的基础上,符号位不变,其余取反

补码:在反码的基础上加一

计算机底层都是补码的形式

4.Java运算符

算术运算符

  • /除

    整除

    1
    2
    3
    4
    5
    6
    7
    double a = 3; double b = 2;

    double c = a / b; //1.0不是1.5

    double c = a / ( b + 0.0 ); //是1.5

    double c = ( double ) a / b; //是1.5
  • %取模

    取模的符号和被模数的符号是一样的

  • 前++

    1
    2
    3
    4
    5
    6
    7
    先自增再运算  

    int a = 1;

    int b = ++ a;

    //a=2,b=2
  • 后++

    1
    2
    3
    4
    5
    6
    7
    先运算后自增

    int a = 1;

    int b = a ++;

    //a=2,b=1

    注意:单独写a++;++a的时候效果一样,并且自增自减不会改变原数据类型

赋值运算符

下面这些不会改变数据类型

short a = 1;

a += 1;//相当于a = a + 1;但是不会像它一样报错,会编译通过

  • +=

  • %=

  • /=

  • -=

比较运算符

结果为boolean型

  • ==

  • !=

逻辑运算符

只适用于boolean型的运算

  • &与

  • &&短路与

相同点1:&与&&的运算结果相同

相同点2:当符号左边为ture,都会执行符号右边的运算

不同点:当符号左边为false,&会继续执行符号右边,&&短路不再执行右边的运算
如:遇到&&就停止

1
2
3
4
5
6
b2 = false;
num = 1;
b2 && ( num++ );
//num = 1;
b2 & ( num ++);
//num = 2;

  • |或
  • ||短路或

相同点1:|与||的运算结果相同

相同点2:当符号左边为false,都会执行符号右边的运算

不同点:当符号左边为true,&会继续执行符号右边,&&短路不再执行右边的运算

  • !非
  • ^异或

位运算符(整形数据)

  • << 左移 每次向左移一位就是乘以2(在一定范围内)
  • >> 右移 每向右移一位除以2(在一定范围内)
  • >>> 无符号右移
  • & 与
  • | 或
  • ~ 取反 包括符号位在内取反,6取反就是-7
  • ^ 异或

注意:都是在二进制的基础上进行移位

三元运算符

要求表达式1与表达式2的类型一致
如果既能用三元又能用if语句,推荐使用三元。因为三元的运算效率更高更简洁。

运算符优先级

image-20200509212706397
没必要记住,想优先加小括号
有一个Java认证叫OCJP

break和continue

  • break 结束当前循环

  • continue 结束当次循环

注意:2个关键字的后面不能声明执行语句

5.数组

数组本身是引用数据类型,数组元素可以是基本数据类型或者引用类型

初始化

  • 静态初始化:数组的初始化和数组的赋值操作同时进行

    ids = new int[]{1001,1002,1003};

  • 动态初始化:数组的初始化和数组元素的赋值操作分开进行

    String[] names = new String[5];

    必须声明长度,一旦确定就不可修改

二维数组

1
2
3
4
5
6
7
8
9
静态初始化
int [] arr = new int [][]{{1,2,3},{1,2,3}};
动态初始化
int [] arr = new int [3][2];`或`int [] arr = new int [3][];

第一个必须赋值,第二个可以不赋值
调用二维数组的时候注意空指针问题
int [][] arr1 = new int [4][3]; System.out.println(arr1[0]);//输出地址值
int [][] arr1 = new int [4][]; System.out.println(arr1[0]);//输出null

初始化默认值

char型为0或‘\u0000’ 不是’0‘

boolean型为false

数组元素是引用数据类型 默认值为null

数组复制

复制arr1数组给arr2

1
2
3
4
arr2 = new int[arr1.length];
for(int i = 0;i<arr2.length;i++){
arr2[i] = arr1[i];
}

不能直接arr2 = arr1(此为赋值操作);这样给的是地址,arr2修改会影响arr1

数组反序

  • 中间临时变量temp,注意终止条件为小与数组长度的一半

  • 方式二:终止条件为 i < j;循环为i++,j–;

    数组查找

    • 线性查找String dest = "AA"; if(dest.equals(arr[i])){System.out.print("找到了")}
    • 二分法查找(要求有序数组)
    • 哈希
    • 差值
    • 等等

6.Eclise快捷键

  • ctrl shift f 格式化代码,使杂乱的代码整齐

  • ctrl shift o 一键导入所有包

  • shift enter 从任意位置跳到下一行

  • ctrl shift enter 从任意位置将本行跳到下一行,在前面出现一个空行

  • 补全代码的声明 art + /

  • 快速修复 ctrl + 1

  • 批量导包 ctrl + shift + o

  • 选择代码块注释 ctrl + shift +/

  • 取消代码块注释 ctrl + shift +\

  • 复制指定行向上(向下) ctrl + alt + up(down)

  • 删除指定行代码 ctrl + d

  • 上下移动 alt + up(down)

  • 下一行 shift + 回车

  • 上一行 ctrl + shift +回车

  • 查看源码 ctrl + 选中结构 或者 ctrl + shift + t

  • 退回到前(后)一个编辑页面 alt + left (right)

  • 查看继承树 ctrl + t

  • 格式化代码 ctrl + shift + f

  • 整体后移 tab

  • 整体前移 shift + tab

  • 在源码中查看 ctrl + o

  • 批量修改 alt + shift +r

  • 指定小写 ctrl + shift + y

  • 指定大写 ctrl + shift + x

  • 调出构造器 alt + shift + s

  • 显示当前选择资源(工程or文件)的属性 alt + enter

  • 快速查找:选中快速定位到下一个ctrl + k

  • 查看指定的结构使用过的地方 ctrl + alt + g

    IDEA快捷键

  • psvm public static void main(String[] args){}

  • sout System.out.println()

  • ctrl+D 向下复制本行代码

  • alert+回车 快速生成方法

    7.流程控制

1.顺序结构

2.分支结构

  • if else

    注意条件表达式之间的关系(互斥,相交,包含) 从而决定书写顺序

  • switch case

    switch结构的表达式,只能是如下的6种数据类型之一:byte,short,char,int,枚举类型(JDK5.0新增),String(JDK7.0新增)

    break是可选 不是必需

1.凡是可以用switch-case结构,都可以转化为if-else。反之不成立。
2.优先选用switch-case。因为switch-case效率比if-else高一些

3.循环结构

  • for

  • while

    for与while可以相互转化

  • do-while(较少使用,循环体至少执行)

    初始条件1;

    do{

    ​ 循环体3;

    ​ 迭代条件4;

    }while(循环条件2);

执行顺序:1–>3–>4–>2

8.scanner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.util.Scanner;

Scanner scan = new Scanner(System.in);

System.out.println("请输入你的姓名:")

String name = scan.next();
System.out.println(name);



Systmer.out.println("请输入你的年龄:")

int age = scan.nextInt();

//scanner 没有char类型,只有string字符串

System.out.println("请问你是否有稳定工作(是/否)")

String work = scan.next();

char workChar = work.charAt(0);//获得字符串索引为0的的字符

9.Math.random()

  • Math 和String,System一样都是一个类,首字母需要大写
  • Math.radom()是double类型,且随机数的范围是[0.0,1.0)
1
2
3
4
5
6
//随机产生一个数,范围在【10,99】
int number = (int)(Math.random()*90 + 10);
System.out.println(number);
//
Random ran = new Random();
ran.nextInt(100);//0-99左闭右闭

10.排序

冒泡排序

相邻元素依次比较。比如5个元素会比较4大轮,第一大轮会比较4 次

堆排序

归并排序

快速排序

  • 时间复杂度O(nlog(n))

  • 20世纪十大算法之一
    image-20200613141906329

性能

image-20200613142343940

Arrays类

  • Arrays.equals(arr1,arr2); //比较数组arr1与arr3
  • Arrays.toString(arr1);//输出arr1的信息
  • Arrays.fill(arr1,10); //将数组arr1的元素替换为10
  • Arrays.sort(arr1);//用快排排序
  • Arrays.binarySearch(arr1,10);//在数组arr1中查找10,找到返回索引值,找不到返回负数。

数组中的常见异常

1.数组角标越界异常

2.空指针异常

11.类

  • 方法
  • 属性
  • 构造器(或构造方法,constructor)

属性 = 成员变量 = filed = 域,字段

方法 = 成员方法 = 函数 = method

创建类的对象 = 类的实例 = 实例化类

类和对象的使用

  1. 创建类,设计类的成员

  2. 创建类的对象

  3. 调用属性,方法

    *如果创建一个类的多个对象,则每个对象都独立有一套类的属性(非static) *

    属性(成员变量) VS 局部变量

    • 局部变量没有初始化值,在调用之前一定要显式赋值。

栈(局部变量),堆(new出来的结构:对象,数组)

static变量 VS 实例变量

  • 类变量随对象的加载而加载,实例变量在类创建的时候分配空间

  • 只要权限允许,可以通过“对象.static属性”调用,存在于方法区的静态域,不能使用this,super

    类方法(static)与实例方法

  • 对象调用实例方法,类名调用类方法

    类中方法的声明和使用

    • 分类

      void 表示没有返回值

    • 声明:权限修饰符 返回值类型 方法名(形参列表){方法体}

      注意:static,final,abstract 来修饰方法

    • 说明1:Java规定4种权限修饰符(public,protected,友好,private)

    • 说明2:没有返回值(void)的方法,没有必要写return,如果要用,只能return;表示结束此方法

      mian

  • main()方法作为程序的入口

  • 是一个普通的静态方法

  • 作为我们与控制台交互的方式

    final

    可以修饰类,方法,变量
    修饰过的东西不能被其他的东西继承重写

  • static final用来修饰属性:全局属性

    abstract

    可以修饰类(抽象类),方法(抽象方法)
    抽象类:不能被实例化,一定有构造器,便于子类实例化调用
    抽象方法:只有方法名,没有方法体

** 包含抽象方法的类一定是抽象类,反之不成立(接口) **

  • abstract不能用来修饰私有方法,静态方法,final的类,final的方法

    方法的使用

  • 可以调用类的属性或方法

  • 不可以在方法中定义方法

构造器

构造方法:没有类型,用来创建对象的时候使用

  • 作用

    ①创建对象 new + 构造器

    ②初始化对象的属性

  • 说明

    格式:权限修饰符 类名(形参列表){}

  • 一个类中定义的多个构造器也构成重载

  • 一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器


    属性赋值的先后顺序

    ①默认初始化

    ②显式初始化

    ③构造器中的赋值

    ④通过“对象.方法”或“对象.属性”

    序号大的会覆盖序号小的

    包装类

    byte–Byte;short–Short;char–Character;int–Integer;long–Long;float–Float;double–Double

    小结:①类是组成java源文件的基本元素,一个源文件由若干个类组成②类有两种重要的成员:成员变量(实例变量,类变量)和方法(构造方法,实例方法,类方法)

    内部类

    Java中允许将一个类A声明在另外一个类B中,类A就是内部类
    命名:B$A

    匿名类

    匿名类一定是内部类,可以继续父类的方法也可以重写。类体内不能声明static成员变量和static方法

    12.封装与隐藏

封装性

1.将属性XX私有化,同时,提供公共的方法去获取(getXX)和设置(setXX)

2.不对外暴露私有的方法

3.单例模式(将构造器私有化)

4.如果不希望类在包外调用,可以将类设置为确省

  • 修饰类只能用确省或public

体现类及类的内部结构在被调用时的可见性的大小


this关键字

  • this理解为:当前对象 或 当前正在创建的对象

  • ①在构造方法中使用

  • ②在实例方法中使用:实例成员变量(this.成员变量),static成员变量(类名.成员变量)

  • this构造器

    可以显式的用this(参数列表),调用本类的其他构造器

    规定:this(参数列表)必须声明在当前构造器首行,每个构造器内部最多只能一个this构造器

    super

  • 成员变量与从父类继承的成员变量同名,子类就会隐藏所继承的成员变量,子类继承的方法只能操作子类继承和隐藏的成员变量。子类新定义的方法可以操作子类继承和子类新声明的成员变量,但无法操作子类隐藏的成员变量(使用super即可)

  • 可以用来调用:属性,方法,构造器

  • 在子类的方法或构造器中。通常使用super.属性/方法。显示调用父类中的声明或方法。一般省略super,当子父类同名时,super不能省略


13.继承extends

子父同包,子不能继承父的private ;子父不同包,子只能继承父的protected,public

  • 一个类可以被多个子类继承
  • 一个类只能有一个父类(单继承)
  • c++支持多继承,java中支持单继承和多层继承
  • 直接继承的父类叫直接父类
  • 子类继承了直接父类之后,就继承了所有间接父类的方法和属性
  • 所有的Java类都直接或间接的继承object类

14.重写overwrite

  • 子类继承父类以后,可以对父类同名同参方法进行覆盖

  • 子类重写的方法名和形参列表与父类被重写的形同

  • 子类重写的修饰符不小于父类被重写的修饰符权限

    子类不能重写父类中声明的private方法

    • 子类和父类中的同名同参的方法要么都声明为非static(考虑重写) 要么都声明为static(不考虑重写)

      重载(同名不同参,用于功能的改变)

      15.多态

  • 在编译的时候,只能调用父类中声明的方法。在运行期,我们实际执行的是子类重写父类的方法编译看左边 运行看右边

  • 对象的多态:父类的引用指向子类的对象(或子类的对象赋给父类的引用)

  • 对象的多态性只适用于方法,属性的编译和运行都看左边

    向下转型

向下转型:使用强制类型转换符(将父类转化为子类)

  • 使用强转时,可能出现ClassCastException异常,为了避免先进行instanceof判断

  • instanceof

  • a instanceof A:判断对象a是否为类A的实例,如果是,返回true

    向上转型:多态

    例如:
    老虎是动物,动物是老虎的上转型对象
    上转型对象仅仅不能操作对象新增的方法,变量
    多态:父类的某个方法被其子类重写时,各自产生自己的功能行为
    java中的2种多态:重写,重载

    16.接口interface

    interface B
    class A implement B

  • 实现接口implements,java可多实现接口,单继承

  • 接口是一个抽象类,接口中的所有方法都是抽象方法

  • 接口可以被extends

  • 如果一个类声明实现一个接口,但没有重写接口中的所有方法,那这个类必须是抽象类

  • java中,接口和类是并列的两个结构

接口回调:当接口变量调用被类实现的接口方法时,就是通知相应对象调用这个方法;当接口变量存放了实现接口的类的对象的引用后,接口变量就可以调用类实现的接口方法

抽象和接口有哪些异同

  • 都不能实例化,都有abstract方法
  • 抽象类有构造器,接口不能声明构造器,单继承,多实现
    demo
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package Example;

    public interface ShapeArea {
    public abstract double doublegetArea();
    public abstract double doublegetPerimeter();
    }
    package Example;

    public class Rectangle implements ShapeArea {
    double width;
    double height;

    public Rectangle(double w,double h){
    this.width = w;
    this.height = h;
    }
    @Override
    public double doublegetArea() {
    return width*height;
    }

    @Override
    public double doublegetPerimeter() {
    return (width+height)*2;
    }
    public String toString(){
    System.out.println("width="+ width + ",height = " + height + ",periment = "+ doublegetPerimeter() + ",area="+ doublegetArea());
    return null;
    }
    }

17.多线程

创建多线程的方式一:继承Thread类

  • 创建一个继承于Thread的子类

  • 重写run()方法

  • 创建一个子类的对象

  • 对象.start()

    ①启动多线程 ②实现run方法

    Thread.currentThread().getName()输出当前线程的名字

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    package Example;

    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;

    /*
    实现一个计数器,计数到100,在每个数字之间暂停1秒,每隔10个数字输出一个字符串 。
    */
    public class Number extends Thread {
    Lock lock = new ReentrantLock();
    @Override
    public void run(){
    lock.lock();
    for(int i = 0;i < 100; i++){
    System.out.println(i);
    try {
    Thread.sleep(100);
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    if(i%10 == 0){
    System.out.println("----"+i);
    }
    }
    lock.unlock();
    }
    }
    /*继承Thread类
    Number num = new Number();
    num.start();
    */

方式二:实现Runnable()接口

  • 创建一个实现Runnable接口的类

  • 重写run()

  • 创建实现类的对象

  • 将此对象作为参数传递到Thread类,创建Thread对象

  • Thread对象.start()


方式一,二比较

优先使用Runnable接口的方法

①实现的方式没有类的单继承性的局限性

②实现的方式更适合来处理多个线程有共享数据的情况


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package Example;
/**
三个窗口同时卖100张票
*/
import java.io.IOException;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class Ticket implements Runnable {
int ticket = 100;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖" + ticket--);
}
lock.unlock();
}
}
}

/*Ticket t1 = new Ticket();
Ticket t2 = new Ticket();
Ticket t3 = new Ticket();
t1.setName("1");
t2.setName("2");
t3.setName("3");
t1.start();
t2.start();
t3.start();*/

方式三:Callable

方式四:线程池

好处:

  • 提高响应速度
  • 降低资源消耗
  • 便于线程管理
1
2
3
4
5
6
7
//1.提供指定线程数量的线程池
ExecutorService service = Exectors.newFixedThreadPool(10);
//2.执行线程的操作。需要提供实现Runnable或者Callable接口的类
service.execute(new NumberThread());//适用于Runnable

service.submit();//适用于Callable
service.shutdown();//关闭线程池

corePoolSize:核心池大小

maximunPoolSize:最大线程数

keepAliveTime:线程没有任务时最多保持多长时间后会终止


线程常用方法

  • start()启动当前线程,调用当前线程的run()方法

  • run()将线程要执行的操作写在此方法中

  • currrentThread()静态方法,返回执行当前代码的线程

  • getName()获取当前线程的名字

  • setName()设置当前线程的名字

  • yield()释放当前cpu的执行权

  • join()在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a结束阻塞状态。

  • sleep(long millis)休眠

  • isAlive()判断线程是否存活


    优先级

    MAX_PRIORITY:10

    MIN_PRIORITY:1

    • getPriority()

    • setPriority(int p)

      运行不是绝对按照优先级,只是从概率上。


线程状态

新建–>就绪—><—运行—>死亡

新建到就绪调用start()

就绪到运行获取CPU执行权

运行到就绪失去cpu执行权或yield()

运行到死亡:

- 执行完run()
- 调用线程的stop()
- 出现error/exception且没有处理

运行到阻塞:

- sleep()
- join() //a join() b ;a线程阻塞
- 等待同步锁
- wait()
- suspend()

阻塞到就绪:

- sleep()时间到
- join()结束
- 获取同步锁
- notify()/notifyAll()
- resume()

解决线程安全 问题

方式一:同步代码块

synchronized(同步监视器){

//需要被同步的代码

}

①操作共享数据的代码,即为需要被同步的代码

②同步监视器:锁。任何一个类的对象都可以作为锁。多个线程必须要共用同一把锁

方式二:同步方法
方式三:lock
  • 实例化 private ReentrantLock lock = new ReentrantLock();
  • lock.lock(); lock.unlock();

synchronized与lock区别:lock手动结束


线程通信

  • notify();//唤醒一个线程
  • notifyAll();//唤醒所有线程
  • wait();//一旦执行此方法,此线程就会进入阻塞,并释放同步监视器

只能出现在同步代码块或者同步方法

并且调用者要是监视器

sleep()与wait()的异同

一旦执行都会进入阻塞

Thread类中声明sleep();Object类中声明wait()

sleep()会自动释放监视器;wait()不能

18.异常

Error:Java虚拟机无法解决的问题如JVM系统错误。不编写针对性的代码进行处理
Expection:空指针。可以解决①终止程序②编写时提前处理
①try-catch-finally处理异常
②throws抛出异常
③throw(手动)声明异常
④用户自定义
异常对象的产生:

  • 系统自动生成的异常对象
  • 手动生成一个异常对象并抛出(throws)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    package Example.Excep;

    //自定义异常
    public class NoThisException extends Exception {

    public NoThisException(){
    super();
    }
    public NoThisException(String message){
    super(message);
    }
    }
    //抛出异常
    public class Player {
    public void play(int index) throws NoThisException {
    if (index > 10) {
    throw new NoThisException("您播放的歌曲不存在");

    }
    System.out.println("正在播放歌曲");
    }
    }
    //处理异常
    public class NumExceTest {
    public static void main(String[] args) {
    Player player = new Player();
    try{
    player.play(9);
    }catch(NoThisException e) {
    System.out.println(e.getMessage());
    }
    }
    }

    19.集合

    数组弊端:
  • 一旦初始化,长度就确定了
  • 方法有限效率低
  • 对于无序,不可重复的需求无法满足
  • 元素类型单一
    collection(单列集合)

    list(有序可重复–动态数组)
    Vector
    ArrayList
    LinkedList
    set(无序,不可重复)
    HashSet
    LinkedHashSet
    SortedSet
    TreeSet

    1
    2
    3
    4
    5
    6
    7
    8
    /*ArrayList arr = new ArrayList();
    for (int i = 0; i < 10; i++) {
    arr.add((int)(Math.random()*10));
    }
    Iterator iterator = arr.iterator();
    while(iterator.hasNext()){
    System.out.println(iterator.next());
    }*/

20.常用类

String

  • 不可变字符序列

  • 实现了Serializable接口:表示字符串是支持序列化的

  • 实现Comparable接口:表示字符串比较大小

  • 实例化方法

    • 字面量定义(常量池)

    • new + 构造器(堆)

    • String s = new String(“abc”);

      在内存中实际创建了2个对象,一个是堆空间中的new结构,另一个是char[]对应的常量池中的数据

值传递:基本数据类型传的是值,引用数据类型传的是地址

底层都用char[] 存储

String:不可变

StringBuffer:可变,线程安全,效率低

StringBuilder:可变,没有scynoriza,线程不安全,效率高

效率:StringBuilder > StringBuffer > String

Date

JDK8之前

  • System类中的currentTimeMiles()

  • java.util.Date类

    • java.sql.Date类
  • SimpleDateFormat

    对日期Date类的格式化和解析

    两个操作:①格式化:日期–》字符串

    ​ ②格式化逆过程(注意参数符合格式)

  • Calendar(抽象类,不能实例化,可变性)

    • 实例化可以调用其静态方法getInstance()

      • getTime(): 日历类–》Date

      • setTime(): Date—>日历类

      • 获取这个月第几天的时候,1号是0

JDK8之后

LocalDateTime相较于LocalDate,LocalTime,使用频率更高

  • now();
  • of():设置指定的年,月,日,时,分,秒没有偏移量
  • 不可变性

instant:瞬时时间戳//子午线的时间

java.time.format.DateTimeFormatter:格式化

java比较器

  • Comparable接口
    • 自然排序
  • Comparator接口
    • 定制排序

System类

void gc():垃圾回收

Math类

关于数学的计算都可以用

BigInteger类

对于超过long范围的int数表示

任意位数的数

BigDecimal类

任意精度的数

关于JDK8前后的日期时间相关类总结

  • java.until.Date和java.sql.Date—-> Instant
  • SimpleDateFormat —-> DateTimeFormatter
  • Calendar —-> LocalDate,LocalTime,LocalDateTime

21.枚举类

  • 当类的对象只有有限个,确定的

  • 需要定义一组常量时,强烈建议使用枚举类

  • 如果枚举类中只有一个对象,可以作为单例模式的实现方式

定义

  • 自定义枚举类(JDK5.0前)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class s{
    //1.声明S对象的属性:private final修饰
    private final String name;
    //2.私有化构造器,并给对象属性赋值
    private s(){
    this.name = name;
    }
    //3.提供当前枚举类的多个对象:public statuc final
    public static final SPRING = new s("春");
    public static final SUMMER = new s("夏");
    }
  • enum关键字(JDK5.0之后)

    定义的枚举类默认继承于java.lang.Enum

1
2
3
4
5
6
7
8
9
10
11
12
enum s{
//1.提供当前枚举类的多个对象:逗号隔开,分号结束
SPRING = new s("春"),
SUMMER = new s("夏");
//2.声明S对象的属性:private final修饰
private final String name;
//3.私有化构造器,并给对象属性赋值
private s(){
this.name = name;
}

}

常用方法

  • values():返回枚举类型的对象数组。遍历
  • valueOf(String str):将字符串转为对应的枚举类对象
  • toString()

22.注解

jdk5.0之后新增功能

Annotation其实就是代码中的特殊标记,这些标记可以在编译,类加载,运行时被读取

  • 文档注解
  • jdk内置3个基本注解
    • @Override
    • @Deprecated:表示所修饰的元素已经过时
    • @SuppressWarnings:抑制编译器警告
  • 跟踪代码依赖性

自定义

参照@SuppressWarning的定义

元注解

修饰其他Annotation,前2个元注解常用。

  • Retention:生命周期SOURCE\CALSS默认\RUNTIME
    • 只有声明为RUNTIME生命周期的注解,才能通过反射获取
  • Target:用于指定 注解可以修饰那些元素
  • Document:表示修饰的注解会被javadoc提取到文档
  • Inherited:使其具有继承性

jdk8新特性

可重复@Repeatable

23.泛型

jdk5.0新增的特性

  • 集合接口或集合类在jdk5.0时都修改为带泛型的结构

  • 在实例化集合类时,可以指明具体的泛型类型

  • 指明完以后,在集合类或接口中凡是定义类或接口时,内部结构都指定为实例化时的泛型类型

  • 泛型的类型必须是类

  • 如果实例化时没有使用过泛型,默认java.lang.Object

    静态方法,异常类不能使用泛型

    泛型方法

    在方法中出现了泛型结构,泛型参数与类的泛型参数没有任何关系

    泛型方法所属的类是不是泛型都没有关系

    通配符

    • 类A是类B的父类,G<A>G<B>是没有关系的,二者共同的父类是:G<?>

    • extends是小于等于

    • supper是大于等于