【Java笔记】基础学习笔记汇总(上)

【Java笔记】基础学习笔记汇总(上)

原本笔记都是手写的,为了之后方便保存和查阅,还是下定决心,把他敲出来正好作为一篇博客的内容。也借这个机会,好好的复习一遍Java基础知识。这是上半部分。

自学材料:黑马程序员Java全套视频

1. 字节和位

位(bit):一个数字0或1

字节(byte):8位一字节,这是数据存储中的最小单位

1Byte = 8bit

1KB = 1024Byte

2. JDK/JRE/JVM的关系

  • JRE(Java Runtime Environment)

Java程序运行时的环境,包含 JVM 和 核心类库

  • JDK(Java Development Kit)

Java程序开发工具包, 包含 JRE 和 开发人员使用的工具


想要运行一个Java程序,只需要安装JRE;想要开发一个Java程序,必须安装JDK

结构:

  • JDK
    • 编译等开发工具
    • JRE
      • 运行类库
      • JVM

3. 标识符

指在程序中,我们自己定义的内容。比如类的名字、方法的名字和变量的名字等等

命名规范:

1)类名规范:

首字母大写,后面的每个单词的首字母大写(大驼峰式)

2)变量名规范:

首字母小写,后面每个单词首字母大写(小驼峰式)

3)方法名规范:

同变量名

4. 字符串常量和字符常量

字符串常量:凡是用双引号引起来的部分。“abc”

字符常量:只是用单引号引起来的单个字符。‘A’

5. 基本数据类型 (4类8种)

整数:byte short int long

浮点:double float

字符:char

布尔:boolean

6. 数据类型转换

byte、short、char这三种类型在运算的时候,都会被首先提升为int类型,然后再计算

7 .常用的ASCII码

‘0’ :48

‘A’ :65

‘a’ :97

8. 算数运算

一旦运算当中有不同数据类型的数据,那么结果将会是数据类型范围大的那种

  • 对于 ++ 和 --
  • 前++:那么变量立刻马上+1,然后拿着结果进行使用
  • 后++:那么首先使用变量本来的数值,然后再让变量+1
  • --类型 类似

9. 逻辑运算符的短路

与&&和||

如果根据左边可以判断得到最终结果,那么右边的代码将不执行

10. 三元运算符

格式:

数据类型 变量名称 = 条件判断 ? 表达式A True :表达式B False

注意事项:

  • 必须同时保证表达式A和表达式B都符合左侧的数据类型的要求
  • 三元运算符的结果必须被使用

11. 重载

  • 方法重载与下列因素有关
    • 参数个数不同
    • 参数类型不同
    • 参数的多类型顺序不同
  • 重载与下列因素无关
    • 与参数的名称无关
    • 与方法的返回值类型无关

12. 初始化数组的格式

  • 动态初始化数组的格式:

数据类型[] 数组名称 = new 数据类型[长度]

  • 静态初始化数组的格式:

数据类型[] 数组名称 = new 数据类型[] {元素1,元素2,。。。}

数据类型[] 数组名称 = {元素1,元素2,。。。}

13. 各类型初始化值

使用动态初始化数组的时候,元素会被自动拥有一个默认值

  • 整数类型 0
  • 浮点 0.0
  • 字符 ‘\u0000’
  • 布尔 false
  • 引用 null

14. Java的内存需要划分为5各部分

1)栈

存放的都是方法种的局部变量。方法的运行一定要在栈中运行

作用域:一旦超过作用域,立刻从栈内存中消失

2)堆(Heap)

凡是new出来的东西,都在堆中

堆内存中的东西都有一个地址值:16进制

3)方法区(Method Area)

存储 .class 的相关信息,包含方法的信息

4)本地方法栈

5)寄存器

例如以下分析:

15. 面向对象的三大特性

面向对象的三大特性:封装、继承、多态

16.创建类

定义类时,成员方法不要static关键字

创建类,格式: 类名称 对象名 = new 类名称( )

17. 局部变量和成员变量

当方法的局部变量和类的成员变量重名时,根据”就近原则“,优先使用局部变量

如果在方法中需要访问本类中的成员变量,使用的格式:this.成员变量名

18. 构造方法

格式:

public 类名称 (参数类型 参数名称,。。。){方法体}

注意:

  • 如果没有编写任何的构造方法,编译器会默认给一个构造方法
  • 构造方法是可以进行重载的

19. Scanner类

  • 创建

Scanner sc = new Scanner(System.in)

  • 使用

1)获取键盘输入的一个int数字

int num = sc.nextInt();

2)获取键盘输入的一个字符串

String str = sc.next();

20. 匿名对象

只有右边的对象,没有左边的名字和赋值运算符

形如:

new Person().name = "xxx";

new Person().showName();

注意:

  • 匿名对象只能使用唯一的一次,下次再用不得不在创建一个新的对象

21. Random类

用来生成随机的数字

  • 创建

Random r = new Random();

  • 使用

1)获取一个随机int数字(范围是int 的所有范围,有正负两种):

int num = r.nextInt();

2)获取一个随机的int数字(参数代表了范围,左闭右开区间):

int num = r.nextInt(3); // 表示[0,3),也就是0到2

22. 泛型

也就是装在集合中的所有元素,全都是统一的什么类型

注意:泛型只能是引用类型,不能是基本类型

23. ArrayList

从JDK1.7开始,创建ArrayList时的右侧尖括号<> 内不用写泛型

常用方法:

1)添加数据:.add()

2)获取数据,参数是索引:.get(int index)

3)删除元素,参数是索引号,并返回对应位置的元素:.remove(int index)

4)获取集合的长度:.size()

注意:

如果希望向集合ArrayList当中存储基本类型数据,必须使用基本类型的包装类

24. 包装类

基本类型 包装类(引用类型,包装类都位于java.Lang包下)

byte Byte

short Short

int Integer

long Long

float Float

double Double

char Character

boolean Boolean

注意:

从JDK1.5开始,支持自动装箱/拆箱

25. 字符串 String类

字符串效果上相当于char[]字符数组,但是底层原理是Byte[]字节数组

  • 创建字符串的常见3+1种方式
    • 三种构造方法
      • public String()
      • public String(char[] array):根据字符数组的内容,创建字符串
      • public String(byte[] array):根据字节数组的内容,创建
    • 直接创建:String str = "Hello";

对于基本数据类型来说:”==“ 是进行数值的比较

对于引用类型来说:”==“是进行地址值的比较


String类的常用方法

1)比较字符串的内容是否相同(两种)

  • .equals(..)

注意:如果比较双方一个常量,一个变量,推荐把常量字符串写在前面,防止空指针异常。

  • .equalsIgnoreCase(..):忽略大小写进行比较

2)字符串操作的方法

  • .length():字符串的长度
  • .concat(String str):拼接字符串,返回新的字符串
  • public char charAt(int index):获取指定索引位置的单个字符(索引从0开始)
  • public int indexOf(String str):找到参数字符串在本字符串中首次出现的索引位置,如果没有返回-1值

3)字符串的截取方法

  • .substring(int index):截取从参数位置到字符串末尾,返回新字符串
  • .substring(int begin,int end):截取从begin开始,到end结束。
  • 注意:[begin,end):包含左边,不包含右边

4)字符串转换的方法

  • .toCharArray():转化为字符数组,返回
  • .getBytes():获取当前字符串底层的字符数组
  • public String replace(CharSequence oldString, CharSequence newString):将字符串中的老字符串替换为新的字符串,返回

5)分割字符串

  • public String[] split(String regex):根据regex,将字符串切分成若干个部分
  • regex:是正则表达式

26. Static关键字

用了Static关键字以后,里面的内容不再属于对象自己,而是属于类的,所以凡是本类的对象,都共享同一份

  • 一旦使用static修饰成员方法,那么这就成为了静态方法。静态方法不属于对象,而是属于类
  • 对于静态方法来说,最好通过类名称来调用;而且不需要创建对象就可以直接通过类名称来调用

总结:无论是成员变量,还是成员方法,如果有了static,都推荐使用类名称进行调用

例如:

类名称.静态变量

类名称.静态方法()


注意:

  • 静态不能访问非静态
  • 静态方法中不能用this

27. 静态代码块

格式:

public class 类名称{

​ static{//静态代码块的内容}

}

特点:

  • 当第一次用到本类的时候,静态代码块执行唯一的一次
  • 静态内容总是优先于非静态,所以静态代码块比构造方法还要先执行

静态代码块的典序用途:

  • 用来一次性的对静态成员变量进行赋值

28. 工具类java.util.Arrays

与数组相关的工具类

1)public static String toString(..):将数组变成字符串

使用:Arrays.toString(...)

2)public static void sort(...):对数组元素进行排序

注意:

  • 如果是数组数组,默认升序,从小到大
  • 如果是字符串,按照字母升序
  • 如果是自定义类型,那么自定义的类需要有Comparable或Comparator接口的支持

29. 工具类java.util.Math

与数学运算有关

  • Math.abs(double num)
  • Math.ceil(double num):向上取整
  • Math.floor(double num):向下取整
  • Math.round(double num):四舍五入
  • Math.PI:近似圆周率常量

30. 继承是多态的前提

如果没有继承,就没有多态

继承主要解决的问题就是:共性抽取

31. 区别子类方法中重名的三种变量

  • 局部变量:直接写成员变量名
  • 本类的成员变量:this.成员变量名
  • 父类的成员变量:super.成员变量名

32. 重写(Override)和重载(Overload)

  • 重写:方法的名称一样,参数列表 也一样
  • 重载:方法的名称一样,参数列表 不一样

注意:

1)方法的覆盖重写的特点:创建的是子类对象,则优先用子类的方法

2)子类方法的返回值必须小于等于父类方法的返回值范围

3)子类方法的权限必须大于等于父类方法的权限修饰符

33. 权限修饰符

public > protected > (default) > private

34. 继承关系中,父子类构造方法的访问特点

1)子类构造方法中有一个默认隐含的”super()“调用,所以一定是先调用父类的构造,后执行子类的构造

2)子类的构造可以通过super关键字来调用父类的重载构造

3)super的父类构造调用,必须是子类构造方法的第一个语句。不能一个子类构造调用多次super()

总结:

子类必须调用父类构造方法,不写则赠送super();写了则用写的指定的super()调用。super()只能有一个,还必须是第一个

35. super关键字和this关键字

super关键字的三种用法:

  • 在子类的成员方法中,访问父类的成员变量
  • 在子类的成员方法中,访问父类的成员方法
  • 在子类的构造方法中,访问父类的构造方法

this关键字的三种用法:

  • 在本类的成员方法中,访问本类的成员变量
  • 在本类的成员方法中,访问本类的另一个成员方法
  • 在本类的构造方法中,访问本类的另一个构造方法

注意:

1)this(...)调用也必须是构造方法的第一个语句,唯一一个

2)super和this两种构造调用,不能同时使用

36. 抽象类和抽象方法

1)

抽象方法:就是加上abstract关键字,然后去掉大括号,直接分号结束

抽象类:抽象方法所在类,必须是抽象才行。在class之前写上abstract即可

2)如何使用抽象类和抽象方法

  • 不能直接创建new抽象类对象
  • 必须先用一个子类来继承抽象父类,子类必须重写抽象父类中的抽象方法
  • 创建子类对象进行使用

3)抽象类使用的注意事项

  • 抽象类不能创建对象,只能创建其非抽象子类的对象
  • 抽象类中,可以有构造方法,是供子类创建对象时,初始化父类成员使用
  • 抽象类中,不一定含有抽象方法,但是有抽象方法的类必定是抽象方法
  • 抽象类的子类,必须重写抽象父类的所有的抽象方法,除非该子类也是抽象类

37. 接口

就是多个类的公共规范

1)

Java7,接口包含:1.常量、2.抽象方法

Java8,额外包含:3.默认方法、4.静态方法

Java9,额外包含:5.私有方法

2)定义抽象方法

格式:

public abstract 返回值类型 方法名(参数列表);

注意:

  • 接口中的抽象方法,修饰符必须是两个固定的关键字:public abstract
  • 这两个关键字修饰符,可以选择性的省略

3)实现类必须重写接口中所有的抽象方法,除非实现类是抽象类

38. Java8开始,接口里允许定义默认方法

用来解决接口升级的问题

格式:

public default 返回值类型 方法名称(参数列表){方法体}

注意:

  • 接口的默认方法,可以通过接口的实现类的对象,直接调用
  • 接口的默认方法,也可以被接口的实现类进行覆盖重写

39. Java8开始,接口里允许定义静态方法

格式:

public static 返回值类型 方法名称(参数列表){方法体}

用法:通过接口名称,直接调用其中的静态方法;格式:接口名称.静态方法名(参数);

40. Java9开始,接口里允许定义私有方法

只有接口自己才能调用,不能被实现类或别人调用

1)普通私有方法,解决多个默认方法之间的重复代码问题

格式:

private 返回值类型 方法名称(参数列表){方法体}

2)静态私有方法,解决多个静态方法之间重复代码问题

格式:

private static 返回值类型 方法名称(参数列表){方法体}

41. 接口中定义”成员变量“

必须使用 public static final 三个关键字进行修饰

格式:public static final 数据类型 常量名称 = 数据值;

注意:

  • 接口中的常量,可以省略public static final关键字
  • 接口中的常量,必须进行赋值,不能不赋值,一旦赋值就不能gaib
  • 接口中的常量的命名规则:使用完全大写的字母,用下划线进行分割

42. 使用接口的注意事项

1)接口是没有静态代码块或者构造方法的

2)一个类的直接父类是唯一的;但是一个类可以同时实现多个接口

3)如果实现类所实现的多个接口中,存在重复的默认方法,那么实现类必须对冲突的默认方法进行重写

4)一个类如果直接父类中的方法和接口中的默认方法产生冲突时,优先用父类中的方法

43. 接口之间的多继承

接口与接口之间可以是多继承

例如:public interface A extends B,C

注意:

  • 多个父接口中的默认方法如果重复,那么子接口必须进行默认方法的重写,而且要带着default关键字

44. 多态

1)

一个对象拥有多种形态,就是对象的多态性

即,【左侧】父类引用 指向【右侧】子类对象

格式:

父类名称 对象名 = new 子类名称(); 或者: 接口名称 对象名 = new 实现类名称();


2)多态情况下访问成员变量有两种方式:

  • 直接通过对象访问成员变量:等号左边是谁,优先用谁,没有则向上找
  • 间接通过成员方法访问成员变量:看该方法属于谁,优先用谁,没有则向上找

3)多态情况下,成员方法的访问规则:

  • 看new的是谁,就优先用谁,没有则向上找

45. 对象的向上转型,其实就是多态的写法

格式:同多态的写法

含义:右侧创建的一个子类对象,把它当作父类来看待使用

注意事项:向上转型一定是安全的,从小范围转向大范围

弊端:对象一旦向上转型为父类,那么就无法调用子类原本特有的内容

解决方案:用对象的向下转型还原

46. 对象的向下转型

格式:子类名称 对象名 = (子类名称) 父类对象;

注意:向下转型的前提是保证对象本来创建的时候,就是这个子类的

47. 判断对象是不是某个类 instanceof

格式:对象 instanceof 类名称

返回的是布尔值

48. final关键的使用

常见的四种用法

1)当final关键字用来修饰一个类的时候

public final class 类名称{。。。}

含义:当前这个类不能有任何的子类(太监类);所有的成员方法都无法进行覆盖重写(因为没有子类)


2)当final关键字用来修饰一个方法时

这个方法就是最终方法,不能被覆盖重写

注意:对于类、方法来说,abstract关键字和final关键字不能同时使用,因为矛盾


3)当final用来修饰 局部变量,那么这个变量就不能进行更改

不变的含义:

  • 基本数据类型,变量中的数据不变
  • 引用类型,变量的地址值不可改变,但是内容可以改变

4)当final用来修饰 成员变量,这个变量也是不可变

  • 成员变量必须手动赋值,不能再给默认值了
  • 对于final的成员变量,要么使用直接赋值,要么通过构造方法赋值。二者选其一
  • 必须保证类中的所有构造方法都会对final的成员变量进行赋值

49. 内部类

一个类内部包含另一个类

分类:

  • 成员内部类
  • 局部内部类(包含匿名内部类)

50. 成员内部类

定义格式:

外部类{

​ 内部类

}

注意:内用外,随意访问;外用内,需要内部类对象


1)使用成员内部类,有两种方式:

  • 间接方式:在外部类的方法中,使用内部类,然后调用外部类的方法
  • 直接方式,公式:

外部类名.内部类名 对象名 = new 外部类名().new 内部类名();


2)内部类的重名变量访问

局部变量: num

内部类的成员变量: this.num

外部类的成员变量: 外部类名称.this.外部类成员变量名

51. 定义一个类时,权限修饰符规则

  • 内部类:public / (default)
  • 成员内部类:public / protected / (default) / private
  • 局部内部类:什么都不能写

52. 局部内部类

如果一个类是定义在一个方法内部的,那么这就是一个局部内部类

”局部“:只有当前所属方法才能使用它,出了这个方法外面就不能使用了

格式:

外部类{

​ 外部类方法{

​ 局部内部类

​ }

}


局部内部类,如果希望访问所在的方法的局部变量,那么这个局部变量必须是【有效final的】

53. 匿名内部类

如果接口的实现类或父类的子类,只需要使用唯一一次,那么这种情况下就可以省略该类的定义,而改为使用匿名内部类。创建对象和调用方法的时候只能使用一次

匿名内部类的定义格式:

接口名称 对象名 = new 接口名称(){ //覆盖重写所有的抽象方法 }

54. 工具类java.util.Date

1)知识点

  • 时间原点(0毫秒):英国格林威治的 1970年1月1日00:00:00;中国属于东八区,所以会加上8小时
  • System.currentTimeMills():获取当前系统时间到时间原点的距离
  • 1天 = 24*60*60 = 86400秒 = 86400 000毫秒

2)Date类的构造方法

  • 空参构造:Date()

获取当前系统的日期和时间

  • 带参构造:Date(long date)

参数:毫秒值;把毫秒值转化为Date日期


3).getTime() 方法

把日期转化为毫秒值;相当于System.currentTimeMills()

55. 抽象类java.text.DateFormat

作用:

  • 格式化(日期 -> 文本)
  • 解析(文本 -> 日期)

成员方法:

  • String format(Date date)
  • Date parse(String source)

DateFormat类是抽象类,无法直接创建对象使用,用DateFormat的子类java.text.SimpleDateFormat

56. DateFormat的子类java.text.SimpleDateFormat

构造方法:SimpleDateFormat(String pattern)

参数pattern:传递指定的模式

y 年;M 月;d 日;H 时;m 分;s 秒

例如:”yyyy-MM-dd HH:mm:ss“

注意:模式中的字母不能改变,连接模式的符号可以改变


  • 把日期格式化为文本,例如:

new SimpleDateFormat("yyyy-MM-dd").format(new Date())

  • 把文本解析为日期,例如:

new SimpleDateFormat("yyyy-MM-dd").parse("2020-10-10")

其中,如果字符串和构造方法的模式不一样,就会抛出ParseException异常

57. 抽象类java.util.Calendar

  • 提供了日历字段:YEAR、MONTH、DAY_OF_MONTH、HOUR
  • 其中有一个静态方法:getInstance():返回Calendar类的子类对象
  • 常用的成员方法
    • public int get(int field)
    • public void set(int field,int value)
    • public abstract void add(int field,int account)
    • public Date getTime()

58. System类

1)public static long currentTimeMills()

返回以毫秒为单位的当前时间

2)public static void arraycopy(参数1,2,3,4,5)

静态方法,将数组中指定的数据拷贝到另一个数组中

参数:

  • src:源数组
  • srcpos:源数组中的起始位置(索引)
  • dest:目标数组
  • destpos:目标数组中的起始位置
  • length:要复制的数组元素的数量

59. java.lang.StringBuilder类 和 String类

1)String类

字符串是常量,在创建之后不能改变

字符串底层是被final修饰的数组(private final byte[] value),不能改变,是一个常量

2)StringBuiler类:字符串缓冲区

可以提高字符串的操作效率。底层也是一个数组,但是没有被final修饰,可以改变长度。

初始容量为16(byte[] value = new byte[16])。如果超出容量,会自动扩容


3)构造方法:

  • StringBuilder()
  • StringBuilder(String str)

4)常用方法:

  • public StringBuilder append(...);

添加任意类型数据的字符串形式,并返回

  • public String toString()

把当前的StringBuilder对象转换为String对象

60. Java1.5之后的新特性:自动装箱和自动拆箱

61. 基本数据类型与字符串之间的转换

  • 基本数据类型 -> String

1)基类 + ”“

例如:int i1 = 100; String s1 = i1 + "";

2)包装类中的静态方法toString

static String toString(int i)

例如:Integer.toString(100);

3)String类的静态方法valueOf

static String valueOf(int i)

例如:String.valueOf(100);

  • String -> 基本数据类型

使用包装类的静态方法parseXxx("...")

例如:Integer类:static int parseInt(String s)

62. java.util.Collection集合接口的框架介绍

63. java.util.Collection接口和单列集合的共性方法(7个)

所有单列集合最顶层的接口,里面定义了所有单列集合的共性方法(7个)

1)public boolean add(E e):添加元素到集合中

2)public boolean remove(E e):把给定的对象在当前的集合中删除

3)public boolean contains(E e):判断集合中是否包含给定的对象

4)public boolean isEmpty():判断当前集合是否为空

5)public int size():返回集合中元素的个数

6)public Object[] toArray():把集合中的元素,存储到数组中

7)public void clear():清空集合中所有的元素,但是不删除集合,集合还存在

64. java.util.Iterator迭代器接口

(对集合进行遍历)

接口中有两个常用的方法:

  • boolean hasNext():判断集合中还有没有下一个元素,有就返回true,没有就返回false
  • E next():返回集合中的下一个元素;把指针向后移动一位

  • Iterator迭代器是一个接口,需要使用接口的实现类对象
  • Collection接口中的 .iterator() 方法,返回迭代器的实现类对象

迭代器的使用步骤:

1)使用集合中的方法 .iterator() 获取迭代器的实现对象,使用Iterator接口来接收(多态);并且把指针(索引)指向集合的 -1 索引处

例如: Iterator< E > it = 集合名.iterator(); //其中,集合是什么泛型,迭代器是什么泛型

2)使用迭代器中的 .hasNext() 方法,判断有没有下一个元素

3)使用迭代器中的 .next() 方法 取出集合的下一个元素;并将指针向后移动一位

65. JDK1.5以后出现的 增强for循环(for each)

  • 专门用来遍历数组和集合。

  • 内部原理是个iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。

66. 泛型

1)创建集合对象,不使用泛型:

  • 好处:集合不使用泛型,默认类型就是Object类型,可以存储任意类型的数据
  • 弊端:不安全,会引发异常

2)创建集合对象,使用泛型

  • 好处:
    • 避免了类型转换的麻烦,存储的是什么类型,取出就是什么类型
    • 把运行期间的异常(代码运行之后抛出的异常),提升到了编译器(写代码的时候报错)
  • 弊端:泛型是什么类型,只能存储什么类型的数据

67. 使用和定义含有泛型的 类/方法/接口

1)类

例如:

public class 类名 < E > {

​ private E name;

​ ...

}


2)方法

泛型的定义在方法的修饰符和返回值类型之间

格式:

public <泛型> 返回值类型 方法名(参数列表)

例如:

public class ....{

​ public < M > void method (M m){

​ ......(m);

​ }

}


3)接口

两种使用方式:

  • 在一个实现类实现一个接口的时候,指定泛型
  • 创建对象的时候才确定泛型的类型

68. 泛型的通配符: ?

代表任意的数据类型

1)使用方式:

  • 不能在创建对象的时候使用
  • 只能作为方法的参数,传递数据类型时使用

2)通配符高级使用:受限泛型

  • 泛型上限:< ? extends 类 >

只能接收该类及其子类

  • 泛型下限:< ? super 类 >

只能接收该类及其父类

69. 集合工具类Collections中的静态方法 .shuffle(...)

  • static void shuffle(List<?> list)

使用默认的随机源使得集合中的元素随机化

例如:Collections.shuffle(集合);

70. java.util.list 接口 extends Collection

list接口中几个Collection中没有,list中特有的方法

1)public void add(int index, E element):将指定的元素添加到该集合中的指定位置上

2)remove(int index):删除指定元素,并返回被移除的元素内容

3)public E set(int index, E element):用指定的元素替换集合中指定位置的元素,并返回被替换的元素值

4)get(int index)


遍历集合的3种方法:

  • 普通for循环
  • 使用迭代器
  • 增强for循环

71. ArrayList集合,是多线程,底层用的是数组

增删元素,也是创建新的数组,所以也是查询快,增删慢

72. LinkedList集合,是多线程,底层用的是链表结构

查询慢,增删快

里面包含了大量操作首尾元素的方法(特有的方法)

注意:在使用LinkedList集合的特有的方法,不能使用多态


1)添加元素

  • public void addFirst(E e):插入列表开头
  • public void addLast(E e)
  • public void push(E e):插入到列表所表示的堆栈;等效于 .addFirst()

2)获取元素

  • public E getFirst()
  • public E getLast()

注意:如果使用.clear()清空了集合中的元素时,使用上述两个方法,会抛出异常

3)删除元素

  • public E removeFirst():删除并返回第一个元素
  • public E removeLast()
  • public E pop():从列表表示的堆栈中弹出第一个元素;等效于 .removeFirst()

4)判断是否为空

  • public boolean isEmpty():不含元素,返回true

73. Vector集合,是单线程,底层用的是数组,是JDK1.0最早期的集合

74. java.util.Set 接口 extends Collection

这里面的方法和Collection接口里面的差不多一致

75. java.util.HashSet集合 implements Set

特点:

1)Set接口有的所有特点

2)是一个无序的集合,存储和取出元素的顺序可能不一样

3)底层是一个哈希表结构(查询的速度非常快)

遍历方式:

  • 使用迭代器
  • 使用增强for循环

注意:

HashSet存储的自定义类型元素类中,必须重写hashCode和equals方法

76. 哈希值/JDK里的哈希表结构

1)Java里的哈希值,是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个模拟出来的逻辑地址,而不是实际存储的物理地址)

2)在Object类中有一个获取对象哈希值的方法

int hashCode():返回对象的哈希值

hashCode方法的源码:public native int hashCode()

其中,native:代表该方法调用的是本地操作系统的方法


注意:

  • 之前对象的地址值(toString)输出的,就是hashCode地址值
  • String类重写了Object类的hashCode方法

3)哈希表结构

  • JDK1.8版本之前:哈希表 = 数组 + 链表
  • JDK1.8版本之后:哈希表 = 数组 + 链表 ;哈希表 = 数组 + 红黑树

两种混合使用。当链表的长度超过了8位时,就会把链表转化为红黑树,来提高查询的速度

77. Set集合存储元素不重复的原理

Set集合在调用add方法的时候,add方法会调用元素的hashCode方法和equals方法,判断元素是否重复

前提:存储的元素必须重写hashCode方法和equals方法

1)先调用hashCode方法计算元素hash值

  • 若没有hash冲突,就存入
  • 若有hash冲突,就进行 2)

2)调用equals方法比较哈希值相同的元素

78. java.util.LinkedHashSet集合 extends HashSet集合

特点:

  • 底层是:哈希表(数组+链表/红黑树)+链表。多了一个链表,用来记录元素的存储顺序,保证元素的有序

79. JDK1.5之后出现的 可变参数

  • 前提:当方法的参数列表里的数据类型已经确定,但是参数的个数不确定,就可以使用可变参数

  • 使用格式:在定义方法时使用

修饰符 返回数据类型 方法名(数据类型 ... 变量名){。。。}

  • 可变参数的底层原理

底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数


注意:

  • 一个方法的参数列表,只能有一个可变参数
  • 如果方法的参数有多个,那么可变参数必须写在参数列表的末尾

可变参数的特殊(终极)写法

public static void method(Object ... obj)

这种可以接收任意数据类型参数

80. 集合工具类 java.utils.Collections

用来对集合进行一些操作

1)public static < T > boolean addAll(集合,元素,,,):往集合中添加一些元素

2)public static void shuffle(list< ? > list):打乱集合顺序


3)public static < T > void sort(list< T > list):将集合中元素按照默认规则排序

注意:sort使用的前提时被排序的集合里的存储的元素必须:

  • 实现Comparable接口
  • 并重写接口中的compareTo方法

来定义排序规则

public class Person implents Comparable<Person>{
    @Override
    public int compareTo(person o){
        //升序
        //return this - o
        //降序
        return o - this
    }
}

Comparable接口的排序规则:

  • 自己(this)- 参数 :升序
  • 参数 - 自己(this):降序

4)public static < T > void sort(list< T > list, Comparator< ? super T >):将集合中的元素按照指定规则进行排序

Collections.sort(list,new Comparator<Integer>{
    //重写比较规则
    @Override
    public int compare(Integer o1,Integer o2){
        return o1 - o2;//升序
    }
});

Comparator的排序规则:

  • o1 - o2 :升序
  • 可以多写几个规划,组合排序

81. java.util.Map< k, v >集合

Map集合的特点:

1)Map集合是一个双列集合,一个元素包含两个值:一个key,一个value

2)key和value的数据类型可以相同,也可以不同

3)key是不允许重复的,value可以重复

4)key和value时一一对应的


Map接口中的常用方法:

1)public V put(K key,V value):把指定的键和指定的值添加到map集合中

返回值:

  • 存储键值对的时候,key不重复,返回值为null
  • 存储键值对的时候,key重复,会使用新的value替换map中重复key的value,返回被替换的value值

2)public V remove(Object key)

返回值:

  • 返回被删除元素的value值
  • key不存在时,返回null

3)public V get(Object key)

返回值:

  • key存在时,返回对应的value值
  • key不存在时,返回null

4)boolean containsKey(Object key)

判断集合中是否包含指定的键,包含返回true,不包含返回false

82. Map集合遍历的两种方式

  • 键找值方式

1)用Set< k > keySet()方法,把Map集合中的所有key取出来存储到Set集合中

2)使用迭代器或增强for循环,遍历Set集合,获取Map集合的每一个key

3)用 .get(key) 方法,获取所有value


  • Entry键值对对象方式

Map.Entry< k,v >:在接口Map中有一个内部接口Entry

作用:当Map集合一创建,那么就会在Map集合中创建一个Entry对象,用来记录键与值,即键值对对象/键与值的映射关系

步骤:

1)方法:Set<Map.Entry<k,v>> entrySet():把Map集合内部的多个Entry对象取出来存储的一个Set集合中

2)遍历Set集合,获取Set集合中的每一个Entry对象

3)应用Entry对象中的方法:

getKey():获取key

getValue():获取value

例如:

public static void main(String[] args) {
        //创建Map集合对象
        Map<String,Integer> map = new HashMap<>();
        map.put("赵丽颖",168);
        map.put("杨颖",165);
        map.put("林志玲",178);

        //1.使用Map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中
        Set<Map.Entry<String, Integer>> set = map.entrySet();

        //2.遍历Set集合,获取每一个Entry对象
        //使用迭代器遍历Set集合
        Iterator<Map.Entry<String, Integer>> it = set.iterator();
        while(it.hasNext()){
            Map.Entry<String, Integer> entry = it.next();
            //3.使用Entry对象中的方法getKey()和getValue()获取键与值
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+"="+value);
        }
        System.out.println("-----------------------");
        for(Map.Entry<String,Integer> entry:set){
            //3.使用Entry对象中的方法getKey()和getValue()获取键与值
            String key = entry.getKey();
            Integer value = entry.getValue();
            System.out.println(key+"="+value);
        }
    }

83. java.util.HashMap< k, v >集合 implements Map< k,v >接口

HashMap的特点:

  • HashMap集合底层是hash表,查询速度更快
  • 是一个线程不安全的集合,是多线程集合,速度快
  • HashMap集合是一个无序的集合,存储元素和取出元素的顺序可能不一致

注意:

HashMap存储自定义类型的键值对时,要保证key值得元素是唯一的,即必须重写hashCode()方法和equals()方法

84. java.util.LinkedHashMap< k,v >集合 extends HashMap< k,v >

特点:

  • 底层是哈希表+链表。可以保证迭代的顺序
  • 是一个有序的集合,存储元素和取出元素的顺序是一致的

85. java.util.HashTable< k, v >集合 implements Map< k,v >接口

1)HashTable

  • 底层是一个哈希表
  • 是一个线程安全的集合
  • 是单线程集合,速度慢

2)HashMap

  • 底层是一个哈希表
  • 是一个线程不安全的集合
  • 是多线程集合,速度快

1)HashTable

  • 不能存储null值和null键

2)之前学过的所有集合

都可以存储null值和null键


HashTable和Vector一样,在JDK1.2之后被更先进的HashMap、ArrayList取代了

但是HashTable的子类Properties仍然在被使用

86. 遍历String字符串,获取每一个字符(两种方法)

1)String类的方法toCharArray,把字符串转化为一个字符数组,在遍历

2)String类的方法length() + CharAt(索引),遍历数组

87. JDK9 在List、Set、Map接口中的新特性:静态方法 of

List、Set、Map接口里面添加了一个静态方法 of,可以给集合一次性添加多个元素

static < E > List< E > of (E ...)

使用前提:当集合中的元素个数不再改变的时候使用


注意:

1)of方法只适用于List、Map、Set接口,不适用于接口的实现类

2)of方法的返回值是一个不能改变的集合,集合不能再使用add、put方法添加元素,会抛出异常

3)Set、Map接口在使用of方法时,不能有重复的元素,否则也会抛出异常

# Java 

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×