基础知识点
🍻ArrayList和LinkedList的区别
🍺ArrayList
ArrayList是List接口的一个实现类,基于动态数组存储的,并且存储地址是连续的。因为ArrayList内部的存储形式是数组的形式,所以不适合做大量的增删操作(尤其是在中间插入或删除元素,因为后面的数组都要向前或向后移动),但是ArrayList在遍历和查找元素时效率很高。
ArrayList适合下标访问,也适合随机访问,在进行随机的get,set方法调用时,ArrayList的效率比LinkedList效率高。
当存入的元素超过了设定的ArrayList的长度时,ArrayList会在内存中分配一个更大的数组来存储这些元素,即新建数组,将旧的数组中的数据拷贝到新的数组中,如果不是尾插法,后面的数据都要移动。
ArrayList list1 = new ArrayList();
list1.add("xiaowei");
List1.add("haoshuai");
对于上面的代码,当运行第一行,底层先创建了一个长度为0的数组,这是因为没有指定数组大小;当运行到第二行时,add第一个元素时,会初始化数组的大小为10(默认的,可指定),如果超过此容量,再次扩容时就是之前的1.5倍。
🍺LinkedList
LinkedList是List接口的另一个实现类,LinkedList集合是一个双向链表,其内部包含有两个Node类型的first和last属性维护的双向循环链表,链表中的每一个元素都使用引用的方式来记住他的前一个和后一个元素,当插入或者删除一个节点时,只需要修改几个元素之间的引用关系就行了,无需造成数据的大量移动。所以Linked List在增删元素上具有很高的效率。
LinkedList没有初始化容量,其底层是双向链表结构,所以不存在扩容这一说。
优点:
随机增删元素效率较高,因为增删元素不涉及大量元素的位移。
缺点:
查询效率较低,每一次查找某个元素时都需要从头节点开始往下遍历
🍉HashMap和Hashtable的区别
🍇HashMap
HashMap 是 map 接口的实现类,是将键映射到值的对象,它的键和值都是对象,并且不能包含重复键,但可以包含重复值。HashMap 允许key和value为空值。
HashMap中的方法没有synchronized修饰,所以HashMap是线程不安全的。
HashMap的底层实现:数组+链表
jdk8开始如果链表高度到8,数组的长度超过64,链表就会转变为红黑树,元素以内部类Node节点存在。
计算key的hash值,二次hash然后对数组长度取模,对应到数组下标,如果没有产生hash冲突(下标位置没有元素),则直接创建Node存入数组,如果产生hash冲突,则先进行equal比较,相同的话就会取代该元素,如果不同的话,则判断链表高度插入链表,链表高度达到8,并且数组长度到64则转变为红黑树,长度低于6则将红黑树转回链表。
由于HashMap是线程非安全的,所以HashMap在效率上要优于HashTable。
🍇HashTable
HashTable中的方法都被Synchronized修饰,所以在多个线程访问HashTable时,不需要自己为它的方法实现同步。HashTable是线程安全的。
HashTable无论是key还是value,都不能为null值。
遍历方面:
HashMap只支持Iterator(迭代器)遍历。
而Hashtable支持Iterator(迭代器)和Enumeration(枚举器)两种方式遍历。
容量方面:
HashMap默认的容量大小是16;增加容量时,每次将容量变为“原始容量x2”。所以其容量一定是2的n次幂。
Hashtable默认的容量大小是11;增加容量时,每次将容量变为“原始容量x2 + 1”。
🚀用HashMap实现的小游戏
以下是用HashMap实现的斗地主小游戏,代码有发牌和看牌的操作,可以运行一下玩玩。
import java.util.*;
public class PlayPoker {
public static void main(String[] args) {
HashMap<Integer, String> hm = new HashMap<Integer, String>();
ArrayList<Integer> array = new ArrayList<Integer>();
// color数组装牌的花色
String[] color = {"♦","♣","❤","♠"};
// num数组装牌的大小
String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
int index = 0;
// 外层循环是牌的大小,内层循环是花色
for (String num1 : num) {
for (String color1 : color) {
hm.put(index,color1+num1);
array.add(index);
index++;
}
}
hm.put(index,"小王");
array.add(index);
index++;
hm.put(index,"大王");
array.add(index);
// 洗牌操作,掉头Collections工具类里面的shuffle方法
Collections.shuffle(array);
// 用TreeSet来实现对牌的排序
TreeSet<Integer> player1 = new TreeSet<Integer>();
TreeSet<Integer> player2 = new TreeSet<Integer>();
TreeSet<Integer> player3 = new TreeSet<Integer>();
TreeSet<Integer> dp = new TreeSet<Integer>();
for (int i = 0; i < array.size() ; i++) {
int s = array.get(i);
// 最后三张就是底牌
if (i >= array.size()-3) {
dp.add(s);
}else if (i % 3 == 0) {
player1.add(s);
}else if (i % 3 == 1) {
player2.add(s);
}else if (i % 3 == 2) {
player3.add(s);
}
}
lookPoker("蔡徐村",player1,hm);
lookPoker("苏珊",player2,hm);
lookPoker("小黑子",player3,hm);
lookPoker("底牌",dp,hm);
}
public static void lookPoker(String name,TreeSet<Integer> t,HashMap<Integer,String> hm) {
System.out.println(name+"的牌是:");
for (Integer key : t) {
String poker = hm.get(key);
System.out.print(poker + " ");
}
System.out.println();
}
}
文章到这里就先结束了,后面还会持续更新,希望能帮助到各位大佬。如果文章有需要改进的地方还请大佬斧正🎉🎉🎉。
制作不易,希望能得到各位小伙伴儿的支持😘😘😘。
小威再次感谢大家了🤞🤞🤞。
- 点赞
- 收藏
- 关注作者
评论(0)