1. 数据结构
栈: 先进后出 Java内存的栈结构
队列: 先进先出 生活中的排队,第一个排队的人,第一个办理业务
数组: ArrayList
查修快: 因为有连续的整数索引,所以可以直接定位查找;
增删慢: 因为需要改变数组的结构,新建一个数组;
链表: LinkedList - List get(int index);
查修慢: 因为只能从头或者从尾开始一个一个查找元素;
增删快: 因为不需要改变数据结构,只需要改变节点中的地址值即可;
单向链表:只能从头开始查,因为一个对象,只记录了下一个对象的地址值,没有记录上一个对象的地址值;
双向链表:只能从头或者从尾都可以查;一个对象,记录上上一个对象和下一个对象的地址值;
红黑树(平衡数): 根节点两端的子节点趋近于平衡,提升查询效率
查询快: 二分查找法; 但是还有没有数组快
增删快: 因为不需要改变数据结构,但是还是需要使树平衡,需要左旋右旋;
可以排序!!!
扩展运算符:
>> : 二进制向右移动不足补0 移动一位相当于除以 2
<< : 二进制向左移动不足补0 移动一位相当于乘以 2
>>> : 无符号位移 符号位不动
^ : 异或 相同为0,不同为1 8 ^ 7
0000 1000 = 8
^
0000 0111 = 7
0000 1111 = 15
7 ^ 7
0000 0111 = 7
0000 0111 = 7
0000 0000 = 0
2. List
有序单列集合!
特点:
1. 有索引
2. 有序
3. 可重复
常用方法:
void add(int index, E e); 在指定的索引处添加元素;
E remove(int index); 删除指定索引处的元素,返回被删除元素
E set(int index , E e); 替换指定索引处的元素,并将被替换元素返回
E get(int index); 获取指定索引处的元素
LinkedList: 双向链表结构,可以从头或从尾开始操作
里面但凡和索引相关的方法,都是模拟出来的,链表结构底层并没有索引;
void addFirst(E e); 在集合的头添加元素
void addLast(E e); 在集合的尾部添加
void push(E e); 在集合的头添加元素
E removeFirst(); 移除集合的第一个元素
E removeLast(); 移除集合的最后一个元素
E pop(); 移除集合的第一个元素
Vector: 底层数组 JDK1.0产物,线程同步,数据安全 被JDK1.2的ArrayList替代
3. Set集合
1. 无序
2. 无索引
3. 不可重复
HashSet/HashMap: 【去重】 hashCode()以及equals()
HashSet底层使用的HashMap中的方法;
JDK1.8【数组+链表+红黑树】:当哈希桶中,链表长度超过8个的时候,才会转成红黑树,提高查询效率
去重原理:
【通过hashCode()以及equals()去重,双重保险】
如果自定义对象想要实现去重,那么必须重写hashCode()以及equals()
for(拿到集合中的每一个元素){
if(hashCode() == e.hashCode() && equals()){ &&:双true则true
不存;
}
存;
}
Object - hashCode()
根据对象的地址值返回一个对应的十进制的值;
而每个对象的地址值不可能相同,所以哈希值也就不可能相同;
我们必须重写hashCode()
String s = "abc"; //123
String s2 = new String("abc");//123
new Student("张三",17);
new Student("张三",17);
"重地".hashCode(); 1179395
"通话".hashCode(); 1179395
HashSet/HashMap【数组+链表+红黑树】:【掌握】
初始化数组:16个长度
添加元素,拿元素的hash值去模以数组的长度;来确定这个元素,存储在数组中的位置;
JDK1.8开始,当某个数组位置中的元素个数,超过8个,
就会从链表结构,转成红黑树结构,为了提高数据查找;
当树结构的元素数量少于6个,又会把树形结构,重新转成链表结构
扩容因子:0.75 16 * 0.75 = 12
阀值:12
扩容系数:2 16 * 2 = 32
16 7 % 16 = 7
8471 % 16 = 7
32 7 % 32 = 7
8471 % 32 = 23
扩容之后,会把桶中的数据,重新排列,放到对应的桶中,为了每个哈希桶中的元素个数不多;
LinkedHashSet: 【有序】的【去重】集合
去重的原理是依赖于HashSet去的重;
有序的原理是依赖于Linked的链表结构;
可变参数:底层就是一个【数组】
1. 调用的时候,可传可不传,0~多个元素
2. 可变参数只能定义一个
3. 可变参数只能定义在参数列表末尾
Comparable:内部比较器(默认比较器)
重写compareTo(Object t1,Object t2); 内部【默认】比较规则
排序的规则,就是compare方法中的代码;
t1-t2 升序(自然顺序)
t2-t1 降序(倒叙)
Comparator:外部比较器
重写int compare(T t1, T t2) 【自定义】的比较规则
t1-t2 升序(自然顺序)
t2-t1 降序(倒叙)
【外部比较器的优先级高于内部比较器】;
ArrayList<Integer> l = new ArrayList<>();
Collections.addAll(l,10,20,30,40,50,60);
System.out.println(l);
Collections.shuffle(l);
System.out.println(l);
Collections.sort(l);
System.out.println(l);
Collections.sort(l, new Comparator<Integer>() { //外部比较器
@Override
public int compare(Integer o1, Integer o2) { //重写比较规则
return o2-o1;
}
});
System.out.println(l);
public final class Integer extends Number implements Comparable<Integer> {//内部比较器
@Override
public int compareTo(Integer anotherInteger) { //重写内部比较规则
return compare(this.value, anotherInteger.value);
}
}