Java基础知识
1.变量
一、 变量
变量相当于自然语言中的代词。比如:“您好”中的您。
a) 变量的分类
- 成员变量(实例变量、全局变量)-?写在类中的
- 局部变量(写在方法中的)---随时回收---GC—System.GC
- 常量 ---不可变
b) 变量有哪些规则
Java是强类型语言,在使用变量时,有既定的规则:
- 变量必须声明,并初始化以后才能使用
- 变量必须有明确的类型
- 变量不能重复定义(在相同代码域中)
- 变量有作用域
二、 进制
1.10进制
十进制(逢10进1)
23678(10进制)=2 * 10000 + 3* 1000 + 6100 + 7 10 + 81
=210^4 + 310^3+ 610^2 + 710^1 + 810^0
=23678
2.二进制
逢2进1 基数是2的进制。
权:128 64 32 16 8 4 2 1
15 = 0000 1111
0100 0001(2进制) = 65
4. 补码
1000 -8
1001 -7
1010 -6
1011 -5
1100 -4
1101 -3
1110 -2
1111 -1
0000 0
0001 1
0010 2
0011 3
0100 4
0101 5
0110 6
0111 7
在二进制中,符号位(最高位)为0的是正数,为1的是负数.
-1 + 1 = 0
1111 + 0001 = 0
1111
+ 0001
0000
在封闭的四位运算中,(超出4位就丢弃)
1101 -3 ~0010 + 1
0011 3 0011
计算机中正数和负数的关系是取反加一。举例:~3 + 1 = -3(表示对3取反)
补码运算是封闭的,运算结果保留在补码范围内,超出范围就溢出。
补码有边界溢出风险。
4位二进制补码最多能表示2^4(16)个数,数的范围是-8 7
16进制:
0 – f
十六进制中的一个数代表了二进制中4位
1234567890
二进制:01001001100101100000001011010010
十六进制:499602d2
192
256 – 192 64
二进制:0000000011000000
十六进制:00c0
0xf4;(十六进制的书写形式)
二进制:1111 0100
十进制:128 + 64 + 32 + 16 + 4 = 244
三、 Java的数据类型
Java中的数据类型,分为引用类型和基本数据类型,基本类型有8种。
基本数据类型
整形:byte short int long
浮点型 float double
字符型char
布尔型boolean
a) 整数类型
byte 8位 0x7f 0x80
short 16位 0x7fff 0x8000
int 32位 0x7fffffff 0x80000000
long 64 … …
b) 浮点数类型
float 32位 float的精度是23位(即能精确表达23位的数,超过就被截取)
不精确,很少被使用。
用小数表示的数据类型
double 类型能表示64位
double精确度比int精确,但是不如long
需要注意的是:浮点数的字面量默认就是double
c) 字符类型
char 经常用到的,必须掌握,字符类型是一个16位无符号位的整数。
这个数是一个字符的unicode编码值。
Unicode编码值 是全球范围内的编码方法,编制了英文,中,日,韩,阿拉伯,希伯来等等共65535个字符.
Java中的char 的范围是0-65535
Unicode编码中英文部分与Ascii码兼容(ASCII表示0-128)
编码是什么?在计算机中不能写字,只能有0和1表示的数。
人为规定某个数除了表示一个数还可以表示一个字符。
一个10进制的65 代表的字符就是大写的A。
d) 布尔类型
布尔类型:boolean 表示真(true)假(false)
四、 数据类型的转换
自动类型转换
小类型到大类型的转换称为自动类型转换,是自动完成的。也叫隐式类型转换。
一般不需要处理,规则是:符号位会自动扩展,负数补1,正数不0.保证补码数值不变。
强制类型转换
这种转换有风险,会溢出,或者损失精度。要注意数据范围。
数组
数组的声明方式:
1.动态初始化
2.静态初始化
动态数组一般就理解成可以无限扩大的容器,二而静态数组就是一开始设定时就规定了其大小
动态初始化指在创建时,使用了new对象的方式创建:
格式为:
int arr[] =new int [4];
int []arr=new int[]{1,2,3,4};
静态初始化个格式:
int arr[]={1,2,3,4};
动态是运行期间确定元素值,静态是编译期间确定元素值 ,静态数组一经建立不可以更改。
复制扩容的方法改变;
1.arrays.copyof(src,length);src表示数组名,length表示长度
2.System.arraycopy(src,srcpos,dest,destpos,length);
其中
src:数组源 (被复制)
srcpos:原数组开始复制的位置
dest:目标数组(当前希望复制的数组)
destpos:目标数组复制的位置
length:复制长度
数组的访问都是,从0开始,0表示数组开始的下标
数组定义格式
数组输出方式:
System.out.println(arrays.tostring(XX));
数组排序
public class ArrSortDemo {
public static void main(String[] args) {
Integer[] ary = {2,7,9,3,6,8,1};
//1.可以使用Arrays.sort对数组进行排序
Arrays.sort(ary);
System.out.println(Arrays.toString(ary));
//2.Comparator:是一个接口,这个接口中的compare的方法是自定义排序方法
Arrays.sort(ary,new Comparator
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
});
System.out.println(Arrays.toString(ary));
}
}
递归
栈内存:
栈内存是计算机的一种数据存储方式,是Java进程启动的时候在内存中开辟的存储空间。
栈内存利用遵循LIFO(后进先出)原则
Java中所有的局部变量都在栈内存中分配空间(压入),方法的参数(形参)也是局部变量,局部变量离开作用域时,收回(从栈内存中弹出)。
Java方法调用使用栈实现,递归调用就是栈的操作。
注意:递归的时候按照递归深度分配全部临时变量,栈内存开销极大,性能不好。
在使用递归调用的时候,切记要有跳出条件。如果没有跳出条件,就会爆栈.
什么时候使用递归?
尽可能不使用。
面向对象
什么是Object(对象)?
Object是指一个具体的事物实例。
面向对象的定义。
首先根据客户需求抽象出业务对象,然后对需求进行合理分层。构建相对独立的业务模块,之后设计业务逻辑,利用多态,继承,封装,抽象的编程思想,实现业务需求,最后通过整合各个模块,达到高类聚,低耦合的效果,满足客户需求。
面向对象分析/面向对象设计
软件企业广泛采用的一项有效技术,OOAD 在设计中要映射现实生活中指定问题领域中的对象和实体。这种设计要尽可能的接近于现实,即,以最自然的方式表述实体。所以说,面向对象技术的有点就是能构建与现实世界相对应的问题模型,并且保持结构、关系、行为。
面向对象的概念
类型(类) 指一个名词的概念
引用(变量) 指引用具体概念实例的代词。
对象(东西) 指具体概念的个体实例
行为 指具体实例的功能/函数/方法
多态 行为或者引用,在具体情形下会发生变化的现象。
在Java中,多态多表示父类引用指向子类实例
封装 任何对象实例都是尽可能封装,减少暴露它的实现细节是不可见的
继承 增强代码的可复用性,抽取业务功能的共性。
构造器
什么是构造器?
构造对象的函数。
构造器的特点:
Java中的构造器(构造方法)声明在类内部
方法名与类名一直的方法叫构造方法
构造方法不能声明返回值类型
构造方法可以包含参数,参数一般是创建对象实例必须依赖的条件。
任何类都一定有构造器,如果程序员不写构造器,JVM会自动的为该类添
一个无参构造器。
构造器重载
构造器重载指写多个参数不一样的构造器。
this关键字
指当前对象。
四、方法的重载
方法的重载是发生在同类中的,方法名一样,方法签名不一样的方法,称为重载。
方法的重载与返回值无关。
多态,功能的多样性。
Java参数的传递规则
Java是基于值的传递,是变量值的复制.
基本类型就是其中的值的复制
引用类型就是地址值的复制
继承
提高代码的复用性。抽取业务功能的共通性。
继承中有两个概念:
父类
用来抽取共性代码。
子类
? 继承
exdents 关键字 是继承的意思
Object类
Java类默认继承于Object,任何类都继承了Object类的所有属性和方法,
其中有三个方法,比较重要:
1.toString()
重写了对象的内容。如果不重写toString(),打印对象会打印出地址值。如果重写toString(),将打印toString()方法返回
的指定的字符串。
2.equals();
用来比较两个对象是否相等的方法
比较对象分为两种:"引用相等"与"对象相等"
比较引用值是否相等,使用 "=="
比较对象是否相等,使用"equals"
但是 equals需要被重写,因为Object的类的equals方法就是 ==
eques默认的比较规则是地址值的比较。
如果覆盖的话,请规循比较规则:
自反性:
对称性:
传递性:
一致性:
3.hashCode();
hachCode方法要与equals方法一同覆盖(规定)
当两个对象equals比较为true时,应具有相同的hashCode值
当两个对象equals比较为false时,应具有不同的hashCode值
hashCode值要稳定,一个对象创建以后就应该在变化。
默认的hashCode值是当前堆对象地址值转换的一个整数,这个整数不是内存地址。
一般使用对象的OID值作为hashCode值。
IOD是对象的唯一编号,在项目中一般采用数据库生成IOD,也就是数据库中的"主键".
重写
重写是发生在父类与子类之间的。
父类方法被子类方法重写后,一定调用子类的。
? 多态
父类引用指向子类实例。
重写,重载都是多态的一种。
方法动态绑定对象
属性静态绑定变量类型
? 继承中的构造器
子类构造器一定默认调用父类无参构造器。
子类优先调用父类无参构造器开辟内存空间,所以,父类空间先加载。
? 对象的实例化过程
? 在创建类之前,检查类是否被加载(是将硬盘上的.class文件加载到内存中),如果没有加载就加载这个类.在这个类被挤在之前要加载所有的父类。
Java运行时采用的策略:懒惰式加载(按需加载):如果第一次用到就加载,只加载一次,通过CLASSPATH指定的路径寻找文件(.class),加载以后是一个对象,类型Class.
? 在内存堆中分配对象空间。递归分配其所有父类和子类属性空间。属性默认自动初始化。
? 进行属性赋值
? 递归调用父类构造器(无参)
? 调用本类构造器
? 引用类型的转换
向上转换(隐式/自动类型转换),是小类型到大类型的转换
向下转换(强制类型转换),是大类型到小类型的转换
instanceof 运算符 ,用来检查引用对象的类型,经常与引用类型的强制类型转换配合,实现安全的类型转换,避免类型转换异常。
? 接口
我们使用抽象方法或者抽象类来作为系统的分析和设计的工具。用来实现客户关系管理业务的架构。
接口的特性:
接口是特殊的抽象类
接口用来表示纯抽象的概念,没有任何具体的方法。
接口不能被实例化,可以定义变量
接口变量可以引用具体实现类的实例(多态)
接口只能被实现(继承)一个具体类实现接口,必须实现其所有的抽象方法。
接口的属性,默认是常量public static final
接口之间可以继承
一个具体的类可以实现多个接口,实现多继承现象。
接口中的方法一定是抽象方法。默认缺失public abstract xxx
实现接口,使用关键字implements,实际上是一种继承关系。
? 抽象类
只有行为的概念,没有具体的实现。
抽象类中的方法可以是抽象方法,也可以被具体化。抽象类不是纯抽象概念
包含抽象方法的类一定是抽象类。抽象类不能被实例化。只能定义引用变量
访问控制修饰符
Java中的访问控制修饰符是修饰Java中类、属性、方法的课间范围。
public 任意
protected 类 包内 子类
[default] 类 包内
private 类
同一个.java文件当中只能有一个public修饰的类
static
静态修饰符.
1.static修饰的资源属于类级别,是全体对象实例共享的资源
静态属性
使用static修饰,属于整个类的属性。
静态资源是在类加载期间初始化的
静态资源可以直接使用类名.资源名访问。比如:System.out
实例属性
属于对象的属性
必须要有对象才能够访问。
静态代码块是在类加载期间运行的代码块,由于类只加载一次,所以静态代码块只执行一次。
一般用来在类加载以后初始化一些静态资源的时候使用。
final
final修饰的类,不能被继承
final修饰方法不能被重写
final修饰的变量,初始化以后就不能再修改
JavaBean规范(开发规范)
JavaBean不是语法规范,是习惯性编程规范,用这个规范写的类比较方便。
有的时候,JavaBean的类也称为:POJO类(Plan Old Java Object)
简化规范:
1.必须有包
项目名、包名、类名、等路径名,不要使用中文。
2.Java类,具有无参数构造器
3.属性尽可能私有化,方法尽可能公开化
属性私有后提供set、get方法。
4.必须实现序列化接口
JDK提供的类几乎都符合JavaBean规范。
一、String 字符串
String是一个API提供的类,存放字符串。底层是char[]String字面量相同时,会替换为同一个String对象的引用。常量连接的结果也被优化为一个字符串.
String比较的时候用equals
解析:
在字符串当中使用加号(a+=b)可以对字符串进行拼接
也可以使用StringfBuffer类进行拼接,元素插入
例如:
buider.append("李敖先生").append("的前妻").append("胡因梦女士").insert(0, "大师").append("据说十分漂亮").delet(4, 6);
System.out.println(buider);
相比较String而言StringBuffer的性能更加高效
可以通过:
System.currentTimeMillis();
对比如二者效率
二、静态字符串
Java编译期间(javac),凡是字面量和常量的运算,都会先算出结果
运行期当字符串池有String"字面量"时,Java会直接用,如果没有才创建。
""就是一个对象 String是一个特殊的类
三、API
length() 返回字符串的长度
trim(); 去除前后两端的空白 \n \t \s
toLoweCase() 将字符串变为小写
toUpperCase() 将字符串变为大写
indexOf(String str) 根据指定的字符串返回下标
lastIndexof() 返回最后一次出现的指定字符的下标位置
endsWith() 是否已指定的后缀结尾
startsWith() 是否已指定的前缀开始
subString(int start,int end) 截取一段子字符串(包前不包后)
subString(int start) 截取一段子字符串(包前不包后)
tocharArray() 将字符串转换成一个数组
split() 根据既定的字符进行分割字符串
equalsIgnoreCase() 忽略大小写比较
四、StringBuilder、StringBuffer
StringBuilder内部也是对char数组的操作,但是数组内容是可变的,如果长度不够,利用数组边长算法来维护
自动扩容长度。
StringBuffer 是线程安全的,速度比较慢
StringBuilder 非线程安全的,速度比较快
StringBuilder与StringBuffer API几乎一模一样
五、日期
Date
long + 操作(很多API的方法已经过时了。有BUG)
Calender
long + 操作(一般情况都使用Calender)
Date内部维护着一个long值
即:1970年至今的毫秒数
Date date = new Date();
System.out.println(date);
long time = date.getTime();
System.out.println(System.currentTimeMillis());
System.out.println(time);
SimpleDateFormat
Date + 操作 (日期格式的操作)
解析:
System.out.println(dt);
六 一、集合
集合底层就是数组
集合的底层就是对象数组 = Object[] objs = new Object[n];
List
LinkedList
LinkedList实现了List接口,能进行队列操作。
LinkedList实现了Deque接口, 能当做双端队列使用。(即:头,尾操作,类似于栈)
#### 解析:
/****************基本操作**********************/
linkedList.addFirst(0);//添加元素到列表开头
linkedList.add(1);//在列表结尾添加元素
linkedList.add(2, 2);//在指定位置添加元素
linkedList.addLast(3);//添加元素到列表结尾
System.out.println("linkedList:" + linkedList);
//获取数据
System.out.println("getFirst():" +linkedList.getFirst());//返回集合中第一个元素
System.out.println("getLast():" + linkedList.getLast());//返回集合中的最后一个元素
System.out.println("removeFirst():" + linkedList.removeFirst());//移除并返回集合中的第一个元素
System.out.println("removeLast():" + linkedList.removeLast());//移除并返回集合中的最后一个元素
System.out.println("linkedList:" + linkedList);
System.out.println("contains(1):" + linkedList.contains(1));//判断此集合中指定的元素,如果包含返回true 否则false
位置访问操作
System.out.println("------------------------------------------------");
linkedList.set(1, 3);//将此集合中指定位置的元素替换成指定的元素
System.out.println("After set :" + linkedList);
System.out.println(linkedList.get(1));//获取指定下标位置的元素
linkedList.add(3);
System.out.println("linkedList:" + linkedList);
System.out.println("indexOf(3):" + linkedList.indexOf(3));//返回集合中首次出现的指定元素的索引
System.out.println("lastIndexOf(3):" + linkedList.lastIndexOf(3));////返回集合中最后一次出现的指定元素的索引
/*****************Queue操作***********************/
System.out.println("------------------------------------------");
//linkedList.clear();//清除集合中所有的元素
System.out.println(linkedList.peek()); //获取但不移除此列表的头
System.out.println(linkedList.element());//获取但不移除此列表的头
//linkedList.clear();//清除集合中所有的元素
/*
* poll()与remove()差异在于poll返回null remove 抛异常
*/
System.out.println("poll():" + linkedList.poll());//获取并移除此列表的头
System.out.println("After poll :" + linkedList);
System.out.println("remove():" + linkedList.remove());//获取并移除此列表的头
System.out.println("After remove :" + linkedList);
System.out.println("linkedList:" + linkedList);
linkedList.offer(4);//添加元素到列表结尾
System.out.println("linkedList:" + linkedList);
linkedList.offerFirst(2);//在此列表的开头插入指定元素
System.out.println("linkedList:" + linkedList);
linkedList.offerLast(5);//在此列表的结尾插入指定元素
System.out.println("linkedList:" + linkedList);
System.out.println("-------------------------------------------");
System.out.println(linkedList.peekFirst());//获取但不移除此列表的头
System.out.println("linkedList:" + linkedList);
System.out.println(linkedList.peekLast());//获取但不移除此列表的尾部
linkedList.pollFirst();//获取并且移除此列表的头
linkedList.pollLast();//获取并且移除此列表的尾部
linkedList.push(2);//将元素推入此列表所表示的堆栈(插入到列表的头)
System.out.println("linkedList:" + linkedList);
linkedList.pop();//从此列表所表示的堆栈弹出一个元素(获取并移除第一个元素)
System.out.println("linkedList:" + linkedList);
linkedList.add(3);
linkedList.removeLastOccurrence(3);//从此列表中移除最后一次出现的指定的元素(遍历)
System.out.println("linkedList:" + linkedList);
/**********************遍历操作***********************/
System.out.println("----------------------------");
linkedList.clear();
for (int i = 0; i < 1000000; i++) {
linkedList.add(i);
}
//迭代器遍历
long start = System.currentTimeMillis();
//获取迭代器
Iterator iterator = linkedList.iterator();
/*
* hasNext():判断集合中有没有元素,如果有返回true 否则false
*/
while(iterator.hasNext()) {
iterator.next();
}
long end = System.currentTimeMillis();
System.out.println("iterator:" + (end - start) + "ms");
//顺序迭代(随机遍历)
/* start = System.currentTimeMillis();
for (int i = 0; i temp = new LinkedList<>();
temp.addAll(linkedList);
//通过pollFirst或者pollLast来遍历
start = System.currentTimeMillis();
while(linkedList.size()!=0) {
linkedList.pollFirst();
}
end = System.currentTimeMillis();
System.out.println("pollFirst:" + (end - start) + "ms");
System.out.println(linkedList);
//通过removeFirst或者removeLast来遍历
start = System.currentTimeMillis();
while(temp.size()!=0) {
temp.removeFirst();
}
end = System.currentTimeMillis();
System.out.println("removeFirst:" + (end - start) + "ms");
}
ArrayList
ArrayList底层是由数组支持,而LinkedList是由双向链表支持的,其中的每个对象包含数据的同时
还包含指向链表中前一个与后一个元素的引用.
线性算法。
``` ArrayList list = new ArrayList<>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
System.out.println(list);
list.remove(2);
System.out.println(list);
list.add(0, "aaa");
System.out.println(list);
String one = list.get(1);//获取指定下标所对应的元素
System.out.println(one);
list.set(1, "2");
System.out.println(list);
String old = list.remove(1);
System.out.println(old);
System.out.println(list);
//contains 查看此集合中是否包含指定的元素,如果有 true 否则false
boolean flag = list.contains("aaa");
System.out.println(flag);
//isEmpty() 检索次列表是否为空
boolean f = list.isEmpty();
System.out.println(f);
System.out.println(list);
//截取一个子集合,按照包前不包后的原则
List list2 = list.subList(1, 2);
System.out.println(list2);
List list3 = new ArrayList<>();
list3.add("5");
list3.add("6");
list.addAll(list3);
System.out.println(list);
}
``` List list = new ArrayList<>();
User u1 = new User("Tom", "123456");
User u2 = new User("Tom", "123456");
User u3 = new User("Tom", "123456");
System.out.println(u1.equals(u3));//true
list.add(u1);
list.add(u2);
System.out.println(list);
boolean f = list.remove(new User("Tom", "123456"));
System.out.println(f);
System.out.println(list);
boolean f2 = list.contains(new User("Tom", "123456"));
System.out.println(f2);//true
/**************************/
LinkedList linkedList = new LinkedList<>();
linkedList.add(u1);
linkedList.add(u2);
System.out.println(linkedList);
boolean f3 = linkedList.contains(new User("Tom", "123456"));
System.out.println(f3);//true
/*
* LinkedList中 如果方法中包含First或者last 都不会去隐含调用equals和hashCode
*/
}
一 Hashset集合
这是一个无序去重的集合,在它的内部不存在重复的数据,这个原理基于
equalsHashset
虽然它是无序的,但是TreeMap弥补了这个缺陷
TreeMap
Set集合的实现类是HashSet() 与Arraylist区别是:算法不同
但是2个类都是继承与Collection。
假如有一个数组,里面包含重复的元素,你可以按照下面的形式进行元素去重
Set stes =new Hashset<>(names);
System.out.println(stes);
数组转集合
String []names={"tom","bob","bob"};
list
System.....//输出
list.add("???");
list.remove("???");//可以传入下标或者字符串
list.get(0);//获取某个下标值
list.set(0,"???");//修改某个下标的值
list.contains("???");//判断集合内是否有这个元素
Collections.sort();//排序
Collections.shuffle();//随机置换,可用于扑克牌
集合转数组
Object[]objs=list2.toArray();//无指定类型
String[]names=list.toArray(new String[]{});//转换成指定类型的数组
二、Map集合
Map集合是一个独立的集合不继承与Collection
HashTable() 是jdk1.0提供的,是线程安全的,性能比较慢
HashMap() 是jdk1.2提供的,是非线程安全的,性能相对于来说快一些。
Map maps = new HashMap();
maps.put("3866", "董大炮");
maps.put("8888", "剑");
maps.put("88888", "Andi");
maps.put("8888", "剑");
System.out.println(maps);
System.out.println(maps.get("3866"));
System.out.println(maps.size());
Set> setMap = maps.entrySet();//遍历map
System.out.println(setMap);
System.out.println(setMap.iterator().next());
System.out.println(setMap.iterator().next().getKey());//打印Key
System.out.println(setMap.iterator().next().getValue());//打印值
Set set = maps.keySet();
System.out.println(set);
Collection cs = maps.values();
System.out.println(cs);
//根据key删除元素,返回被删除的value
String rvalue = maps.remove("8888");
System.out.println(rvalue);
System.out.println(maps);
//判断是否有指定的key
System.out.println(maps.containsKey("38661"));
//判断是否有指定的value
System.out.println(maps.containsValue("Andis"));
Map stuMap = new HashMap<>();
stuMap.put(1, new Student("Jerry", 18));
stuMap.put(2, new Student("Jerry", 18));
System.out.println(stuMap);//hashMap中的元素重复与否与key相关,key的底层就是Set
map集合应用,统计字符串当中,每一个字出现的次数
public static void main(String[] args) {
// TODO Auto-generated method stub
NumberFormat number =NumberFormat.getInstance();
String s="如果你是在一个面临美国制裁的国家使用GitHub的在线服务,你的账号可能会因此被限制只能使用最基本的产品。GitHub 本周告诉居住在克里米亚的21岁俄罗斯公民 Anatoliy Kashkin,由于美国的贸易管制,它“限制”了他的 GitHub 账户。Anatoliy Kashkin 在 YC 上发了帖子说明此事,据说与该开发者同一地区的其他开发者也同样被限制。GitHub 确实为开发者提供了一个争议限制的申诉表格,但 Kashkin 声称通过上诉限制没有任何好处:“这是毫无意义的。我的帐户被标记为限制,为了取消标记,我必须提供一份证据证明我不住在克里米亚。我实际上是一名克里米亚人注册的俄罗斯公民,我身处其中克里米亚,我一生都住在克里米亚。”";
System.out.println(s);
Count(s);
}
public static void Count(String s)
{
int count = 0 ;
String sss=null;
NumberFormat number =NumberFormat.getInstance();
HashMap map =new HashMap<>();
int point;
for (int i = 0; i
三、集合的继承结构
Collection
List Set Map
ArrayList LinkedList HashSet SortedSet HashMap HashTable SortedMap
TreeSet Properties TreeMap
以上是集合的继承结构,请务必知悉。
四、集合的复制
Java默认的复制规则是浅层复制
集合复制有2种形式
1.clone() 是Object定义的.一般API都重写了这个方法
2.使用复制构造器
List> lists = new ArrayList<>(map.entrySet());
五、同步化(线程安全)
Collections.synchronizedList(list)
可以将非线程安全的list包装为一个线程安全的
如果将一个非线程安全的list包装为一个线程安全的转换以后就相当于Vector
Collections.synchronizedMap(Map)
可以将非线程安全的Map包装为一个线程安全的