ArrayList
ArrayList集合的特点
ArrayList类实现接口List,ArrayList具备了List接口的特性 (有序,重复,索引)
-
ArrayList集合底层的实现原理是数组,大小可变 (存储对象的时候长度无需考虑).
-
数组的特点 : 查询速度快,增删慢.
-
数组的默认长度是10个,每次的扩容是原来长度的1.5倍.
-
ArrayList是线程不安全的集合,运行速度快.
LinkedList
LinkedList集合的特点
LinkedList类实现接口List,LinkedList具备了List接口的特性 (有序,重复,索引)
-
LinkedList底层实现原理是链表,双向链表
-
LinkedList增删速度快
-
LinkedList查询慢
-
LinkedList是线程不安全的集合,运行速度快
LinkedList集合特有方法
集合是链表实现,可以单独操作链表的开头元素和结尾元素
-
void addFirst(E e) 元素插入到链表开头
-
void addLast(E e) 元素插入到链表结尾
-
E getFirst() 获取链表开头的元素
-
E getLast() 获取链表结尾的元素
-
E removeFirst() 移除链表开头的元素
-
E removeLast() 移除链表结尾的元素
-
void push(E e)元素推入堆栈中
-
E pop()元素从堆栈中弹出
Set集合
Set集合,是接口Set,继承Collection接口. Set集合不存储重复元素
Set接口下的所有实现类,都会具有这个特性.
Set接口的方法,和父接口Collection中的方法完全一样
Set接口实现类HashSet类
-
HashSet集合类的特点 :
-
实现Set接口,底层调用的是HashMap集合
-
HashSet的底层实现原理是哈希表
-
HashSet不保证迭代顺序,元素存储和取出的顺序不一定
-
线程不安全,运行速度快
-
对象的哈希值
每个类继承Object类,Object类定义方法 :
public native int hashCode(); // C++语言编写,不开源
方法使用没有区别 : 方法返回int类型的值,就称为哈希值
哈希值的结果不知道是怎么计算的,调用toString()方法的时候,返回的十六进制数和哈希值是一样的, @1b6d3586叫哈希值 (根本和内存地址是无关的)
String类的哈希值
字符串类重写方法hashCode(),自定义了哈希值,哈希值的计算方法是 :
h = 31 * 上一次的计算结果 + 字符数组中元素的ASCII码值
*31 的目的,减少相同哈希值的计算
//字符串String对象的哈希值
private static void stringHash(){
String s1 ="abc";
String s2 ="abc";
System.out.println(s1 == s2); //T
//String类继承Object,可以使用方法hashCode
System.out.println(s1.hashCode() == s2.hashCode()); //T
/**
* String类继承Object类
* String类重写父类的方法 hashCode() 自己定义了哈希值
*/
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println("=============");
/**
* 字符串内容不一样,有没有可能计算出相同的哈希值
* String s1 ="abc";
* String s2 ="abc";
*/
String s3 = "通话";
String s4 = "重地";
//1179395
//1179395
System.out.println(s3.hashCode());
System.out.println(s4.hashCode());
System.out.println(s3.equals(s4));
}
哈希值的相关问题
问题 : 两个对象A,B 两个对象哈希值相同,equals方法一定返回true吗?
两个对象A,B 两个对象equals方法返回true,两个对象的哈希值一定相同吗
结论 : 两个对象的哈希值相同,不要求equals一定返回true. 两个对象的equals返回true,两个对象的哈希值必须一致
Sun 公司官方规定 : 上面的结论
哈希表的数据结构
数组 + 链表的组合体
class Node{
E element; //存储的元素
Node next; //下一个元素
}
main(){
Node[] node = new Node[5];
}
-
哈希表的底层数组长度默认是16个,扩容为原来长度的2倍
-
加载因子默认是0.75F,数组中存储元素的个数达到长度的75%,扩容
哈希表存储对象的过程
public static void main(String[] args) {
Set<String> set = new HashSet<String>();
//存储对象
set.add("abc");
set.add("bbc");
set.add(new String("abc"));
set.add("通话");
set.add("重地");
System.out.println("set = " + set);
}
哈希表源码
HashSet集合本身不具备任何功能,内部调用了另一个集合对象HashMap
哈希表面试问题
JDK7版本和JDK8版本的哈希表的区别
-
JDK7没有转红黑树
-
JDK8转成红黑树
-
转成树的两个参数
-
当一个数组中存储的链表长度>=8 转树
-
数组的整体长度超过64
-
-
树转回链表
-
链表的长度 <=6
-
-
-
JDK7元素采用头插法,JDK8元素采用尾插法
红黑树
红黑树(Red-Black-Tree)
-
二叉树,本质就是链表
-
查询速度快
-
每个一个节点,只有两个子节点,左和右
-
树长偏了
-
-
自然平衡二叉树
-
二叉树的基础上,改进,保证树是平衡的
-
-
红黑树
-
每个节点有颜色,要么红,要么是黑
-
根节点必须是黑色
-
叶子节点必须是黑色
-
变量表示颜色,true黑色,false红色
-
TreeSet集合使用
TreeSet集合,底层是红黑树结构,依赖于TreeMap的实现
红黑树特点查找速度快,线程不安全
可以对存储到红黑树的元素进行排序,元素的自然顺序 abcd.. 字典顺序
LinkedHashSet
底层的数据结构是哈希表,继承HashSet
LinkedHashSet数据是双向链表, 有序的集合,存储和取出的顺序一样
Collections工具类
-
java.util.Collection 集合的顶级接口
-
java.util.Collections 操作集合的工具类
-
工具类的方法全部静态方法,类名直接调用
-
主要是操作Collection系列的单列集合,少部分功能可以操作Map集合
-
/**
* 集合操作的工具类
* Collections
* 工具类有组方法: synchronized开头的
*
* 传递集合,返回集合
* 传递的集合,返回后,变成了线程安全的集合
*/
public class CollectionsTest {
public static void main(String[] args) {
sort2();
}
//集合元素的排序,逆序
public static void sort2(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(15);
list.add(5);
list.add(20);
list.add(9);
list.add(25);
System.out.println("list = " + list);
//Collections.reverseOrder() 逆转自然顺序
Collections.sort(list,Collections.reverseOrder());
System.out.println("list = " + list);
}
//集合元素的排序
public static void sort(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(15);
list.add(5);
list.add(20);
list.add(9);
list.add(25);
System.out.println("list = " + list);
Collections.sort(list);
System.out.println("list = " + list);
}
//集合元素的随机交换位置
public static void shuffle(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(15);
list.add(5);
list.add(20);
list.add(9);
list.add(25);
System.out.println("list = " + list);
Collections.shuffle(list);
System.out.println("list = " + list);
}
//集合的二分查找
public static void binarySearch(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(5);
list.add(9);
list.add(15);
list.add(20);
list.add(25);
int index = Collections.binarySearch(list, 15);
System.out.println(index);
}
}