简单的聊一下JAVA集合(SXL),有什么不对的欢迎指正!

一、ArrayList 数组集合应用

// ArraysList 增删慢 查询快 // 根据源码 无参构造方法创建出来的是长度为0的数组{} List list = new ArrayList<>(); // 此时add方法进行源码扩容 list.add(100); System.out.println(list.get(0));

add()方法扩容源码
public boolean add(E e) { // 不需要关注 modCount++; // e对象 elementData集合数组元素 size当前数组长度 add(e, elementData, size); // 不管成功失败 均返回true return true; }private void add(E e, Object[] elementData, int s) { // 满足条件 进入扩容算法 不然就进行正常赋值操作 if (s == elementData.length) elementData = https://www.it610.com/article/grow(); elementData[s] = e; size = s + 1; }private Object[] grow() { // 至少需要加一个长度 return grow(size + 1); }private Object[] grow(int minCapacity) { return elementData = Arrays.copyOf(elementData, newCapacity(minCapacity)); }private int newCapacity(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; // 新长度加上旧长度的0.5倍 int newCapacity = oldCapacity + (oldCapacity>> 1); if (newCapacity - minCapacity <= 0) { if (elementData =https://www.it610.com/article/= DEFAULTCAPACITY_EMPTY_ELEMENTDATA) // DEFAULT_CAPACITY 默认长度10 return Math.max(DEFAULT_CAPACITY, minCapacity); // 超出最大二进制,符号会改变,会变为负数 if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return minCapacity; }// MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8 return (newCapacity - MAX_ARRAY_SIZE <= 0) ? newCapacity : hugeCapacity(minCapacity); }private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); return (minCapacity> MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }

二、LinkedList
// LinkedList: 使用双向链表结构,增删快,查找慢 // (这种结构和ArrayList的数组结构正好是互补状态) LinkedList ll = new LinkedList<>(); // 模拟栈结构 // 压栈 ll.push(100); ll.push(200); // 弹栈 Integer i = ll.pop(); // 200 System.out.println(i); // 1 System.out.println(ll.size()); // 下面注释参考 不建议使用 // 添加集合中第一个元素 // ll.addFirst(100); // ll.addFirst(200); // 移除集合中第一个元素 // Integer removeData = https://www.it610.com/article/ll.removeFirst(); // 200 // System.out.println(removeData); // 1 // System.out.println(ll.size());

三、Vector 用法和ArrayList基本一致,是线程安全的。
// 10 初始化长度 20 扩容增量 此处是相较于ArrayList不同之处 List v = new Vector<>(10, 20); v.add(100); v.add(200);

四、Iterator和ListIterator
// Iterator 迭代器 作用遍历集合 // Iterator迭代Collection下List和Set ListIterator迭代List下面的集合 List list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); Iterator iterator = list.iterator(); iterator.next(); // 必须要有值才能移除即前面调用next()方法,当然没值也会报错 iterator.remove(); ; // 4 System.out.println(list.size()); // 判断迭代器下个是否有值 while(iterator.hasNext()) { // 迭代器往下走,并取值 Integer i = iterator.next(); // 输出 2 3 4 5 System.out.println(i); }// 用法和iterator差不多 ListIterator listIterator = list.listIterator(); // 获取向上走的值 listIterator.hasPrevious(); // 添加 listIterator.add(10); // 设置 listIterator.next(); listIterator.set(200); listIterator.previous(); // 5 System.out.println(list.size()); while(listIterator.hasNext()) { // 输出 200 3 4 5 System.out.println(listIterator.next()); }

五、Set Set集合是没有重复的元素,包括null只会存在一个
5.1 HashSet
// HashSet是散列存放的数据结构(哈希表) // 本质是 map = new HashMap<>() // 由于已经存在双值存储的哈希表 所以这边重复利用了形成现在的单值存储的哈希表 Set set = new HashSet<>(); // map.put(e, PRESENT) set.add("人有悲欢离合"); set.add("月有阴晴圆缺"); set.add("但愿人长久"); set.add("但愿人长久"); set.add("千里共婵娟"); set.add("千里共婵娟"); Iterator iterator = set.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); }

5.2 TreeSet
public static void main(String[] args) { // TreeSet 使用二叉树进行存储的 有序(自然顺序) Set set = new TreeSet<>(); Person p1 = new Person("张三", 13); Person p2 = new Person("李四", 14); Person p3 = new Person("麻五", 14); set.add(p1); set.add(p2); set.add(p3); // 遍历前需制定自己的排序规则, 否则可能报错 // Person{name='张三', age=13} // Person{name='李四', age=14} // 比较规则相同的值,不被储存 for (Person p : set) { System.out.println(p); }// set.add("C"); // set.add("B"); // set.add("A"); // set.add("D"); // A B C D // Iterator iterator = set.iterator(); // while(iterator.hasNext()) { //System.out.println(iterator.next()); // } }static class Person implements Comparable【简单的聊一下JAVA集合(SXL),有什么不对的欢迎指正!】 {private String name; private int age; @Override public int compareTo(Person o) { // this与0比较 // 返回this小/0/大 if (this.age > o.age) { return 1; } else if (this.age == o.age) { return 0; } return -1; }public Person(String name, int age) { this.name = name; this.age = age; }public String getName() { return name; }public void setName(String name) { this.name = name; }public int getAge() { return age; }public void setAge(int age) { this.age = age; }@Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }

六、Map Map(Mapping 映射)集合存储的是 键值对 数据,Map的键不可重复。
影响HashMap的实例化性能的是初始容量和负载因子。
HashMap/Hashtable/ConcurrentHashMap TreeMap/LinkedHashMap使用方法基本一致。
HashMap是线程不安全,效率高。HashTable线程安全, 效率低。
ConcurrentHashMap采用分段锁机制,保证线程安全,效率较高。
TreeMap是有序的排。
LinkedHashMap存储有序。
6.1 HashMap
Map map = new HashMap<>(); // 存值 map.put("k1", "v1"); // 取值 v1 System.out.println(map.get("k1")); map.put("k2", "v2"); // 遍历 Set set = map.keySet(); for (String key : set) { // k1->v1 // k2->v2 System.out.println(key + "->" + map.get(key)); }// 转为Collection集合 Collection c = map.values(); for (String s : c) { System.out.println(s); }

HashMap源码粗解析
// 构造方法 public HashMap() { // 默认加载因子0.75f this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted }public V put(K key, V value) { // 先计算键的hash值,然后调用putVal return putVal(hash(key), key, value, false, true); }final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { // n是桶(数组)的长度 Node[] tab; Node p; int n, i; // table是默认的16个长度的数组赋值给tab if ((tab = table) == null || (n = tab.length) == 0) // resize扩容算法 n扩容之后的长度 n = (tab = resize()).length; // (n - 1) & hash 是取余后的长度数组下标没有值直接赋值 if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { Node e; K k; // key存在新值覆盖老值 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; // 判断是树节点 按红黑树套路进行存储 else if (p instanceof TreeNode) e = ((TreeNode)p).putTreeVal(this, tab, hash, key, value); // 链表套路进行赋值 else { for (int binCount = 0; ; ++binCount) { // 非重复值操作 if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); // 这边是二叉树操作 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } // 重复值操作 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } // 前面e被赋值,进入此方法 if (e != null) { // existing mapping for key V oldValue = https://www.it610.com/article/e.value; if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); return oldValue; } } // 增加修改次数 ++modCount; // 判断是否到了临界值 if (++size> threshold) // 扩容 resize(); afterNodeInsertion(evict); return null; }

总结 在文章的最后作者为大家整理了很多资料!包括java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书等等!
欢迎关注公众号:前程有光,领取!

    推荐阅读