Java集合类

一、Collection集合

概念:对象的容器,实现了对 对象的操作,类似数组功能

集合与数组的区别:数组长度固定,集合长度不固定

​ 数组可以存基本数据类型和引用类型,而集合只能存引用类型

Collection体系

1.1 Collection类的基本方法

案例:Collection的基本方法以及操作

public class test01Collection {public static void main(String[] args) {//1.创建一个集合,用的ArrayList 是有序的Collection collection = new ArrayList();//2.添加元素collection.add("苹果");collection.add("西瓜");collection.add("猕猴桃");System.out.println("元素个数:"+collection.size());System.out.println(collection);//3.删除其中一个collection.remove("苹果");//4.删除所有
//        collection.clear();//5.遍历集合for eachfor (Object item:collection) {System.out.println(item);}//6.使用迭代器遍历Iterator iterator = collection.iterator();while (iterator.hasNext()){String s = (String) iterator.next();System.out.println(s);}//7.判断System.out.println(collection.contains("苹果"));System.out.println(collection.isEmpty());}
}

1.2 List类的基本方法

案例:list的基本方法以及操作

public class test02_List {public static void main(String[] args) {//1.list的创建List list = new ArrayList();list.add("MMing");list.add("Aifleft");list.add("LongSkr");list.add("Forever");list.add(4,"lionkk");System.out.println(list.toString());//2.删除list.remove(4);System.out.println(list.toString());//3.遍历 fori foreach Iterator ListIterator//for ifor (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}//for eachfor (Object item: list) {System.out.println(item);}// IteratorIterator iterator = list.iterator();while(iterator.hasNext()){System.out.println(iterator.next());}// ListIterator 相对于普通的 Iterator 可以进行前驱和后继的寻找ListIterator listIterator = list.listIterator();while (listIterator.hasNext()){System.out.println(listIterator.next());}while (listIterator.hasPrevious()){System.out.println(listIterator.previous());}//4.sublist 进行区间截取List sublist = list.subList(0,2);System.out.println(sublist.toString());}
}

1.3 List实现类

1)ArrayList:实现是 数组,查询快,增删慢,运行效率快,但线程不安全

2)LinkedList:实现是 链表,查询慢,增删快

3)Vector: 实现是 数组,查询慢,增删快,运行效率慢,但线程安全

1.3.1 ArrayList

案例:ArrayList的基本方法操作

public class test02_ArrayList {public static void main(String[] args) {//1.添加数据到listArrayList arrayList = new ArrayList();Student s1 = new Student("裴珠泫",20);Student s2 = new Student("金珍妮",20);Student s3 = new Student("柳智敏",20);Student s4 = new Student("宁艺卓",20);Student s5 = new Student("李秀满",50);arrayList.add(s1);arrayList.add(s2);arrayList.add(s3);arrayList.add(s4);arrayList.add(s5);System.out.println(arrayList.toString());//2.删除元素
//        arrayList.remove(s5);
//        System.out.println(arrayList.toString());//3.删除元素(通过new 方法) 需要重写对应类的equals方法 涉及remove的源码arrayList.remove(new Student("李秀满",50));System.out.println(arrayList.toString());//4.遍历 fori foreach Iterator ListIteratorfor (int i = 0; i < arrayList.size(); i++) {System.out.println(arrayList.get(i));}for (Object o:arrayList) {System.out.println(o);}Iterator iterator = arrayList.iterator();while (iterator.hasNext()){System.out.println(iterator.next());}ListIterator listIterator = arrayList.listIterator();while (listIterator.hasNext()){System.out.println(listIterator.next());}while ((listIterator.hasPrevious())){System.out.println(listIterator.previous());}//5.判断boolean result = arrayList.contains(new Student("裴珠泫",20));System.out.println(result);//6.查找System.out.println(arrayList.indexOf(new Student("金珍妮",20)));}
}

案例:ArrayList源码分析

/*** Default initial capacity.*/
private static final int DEFAULT_CAPACITY = 10;

默认容量:10

public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;
}

ArrayList的add方法:里面调用了 ensureCapacityInternal方法,传递了一个size+1(新的ArrayList就是1)的参数

private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}

ensureCapacityInternal方法:保证内部的容量方法(一个缓存方法),接收了size+1(新的ArrayList就是1)参数,继续调用ensureExplicitCapacity方法,参数为calculateCapacity方法

返回的int值

private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;
}

calculateCapacity方法:用于得出真实容量的方法,需要两个参数,当前元素数据和minCapacity(size+1)的容量

方法内部进行判断,是否为空数组,如果是,返回默认容量(10)和minCapacity (size+1如果是新的ArrayList就是1)之间大的数字

如果不是空数组就返回

private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);
}

ensureExplicitCapacity方法:保证明确容量方法,参数就是calculateCapacity的返回值,里面进行了一个判断,

如果minCapacity(与DEFAULT_CAPACITY比较完会变成10)- 当前对象的长度 大于 0,就执行grow增长方法传递minCapacity参数

private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);
}

进行了一些列的比较与赋值,最后执行了Array.copyOf()方法 复制拷贝生成了新的 list对象,把对象添加了进去

1.3.2 Vector

案例:vector的常用方法(添加 删除与list都类似 下面仅写出特有的枚举器遍历

public class test02_Vector {public static void main(String[] args) {Vector vector = new Vector();vector.add("ONE");vector.add("TWO");vector.add("THREE");//重点写一下vector的 枚举器遍历Enumeration e = vector.elements();while (e.hasMoreElements()){System.out.println(e.nextElement());}}
}

1.3.3 LinkedList

用法与ArrayList基本一致,实现是用双向链表

案例:LinkedList源码

transient int size = 0;/*** Pointer to first node.* Invariant: (first == null && last == null) ||*            (first.prev == null && first.item != null)*/
transient Node<E> first;/*** Pointer to last node.* Invariant: (first == null && last == null) ||*            (last.next == null && last.item != null)*/
transient Node<E> last;

默认的容量为0, 一个头节点,一个尾节点

public boolean add(E e) {linkLast(e);return true;
}

add方法里面 调用了linklast方法

/*** Links e as last element.*/
void linkLast(E e) {final Node<E> l = last;final Node<E> newNode = new Node<>(l, e, null);last = newNode;if (l == null)first = newNode;elsel.next = newNode;size++;modCount++;
}

当添加一个元素到空链表

1.3.4 ArrayList 和 LinkedList区别

1.4 泛型

概念:泛型就是参数化类型,把类型作为参数传递

优点:提高代码的重用性,防止类型转换异常,提高代码的安全性

1.5 Set类

特点:无序,无下标,元素不重复

方法:全部继承于Collection中的方法

使用:基本方法于list类似,不可用fori 进行遍历

1.5.1 HashSet

存储结构:哈希表(数组+链表(+红黑树))

存储过程:1)根据对象的hashcode计算在数组中的保存位置,如果当前位置为空,直接保存,不为空执行下一步

​ 2)不为空,执行equals方法,如果equals方法为true,会判断重复放弃保存,为false会形成链表

案例:HashSet基本使用,以及 通过重写Student的hashcode 和 equals方法 来判断元素一致性

public class test03_HashSet {public static void main(String[] args) {//1.新建一个HashSet 存入数据HashSet<Student> hashSet = new HashSet<Student>();Student s1 = new Student("西八哥",22);Student s2 = new Student("王德发",32);Student s3 = new Student("Lolita",18);hashSet.add(s1);hashSet.add(s2);hashSet.add(s3);//2.打印目前数据,是无序的System.out.println(hashSet.toString());//3.通过重写hashcode和equals方法 来进行判定是否为一个数据对象Student s4 = new Student("王德发",32);hashSet.add(s4);System.out.println(hashSet.toString());//4.遍历 fori foreach 迭代器//5.判断}
}

重写的两个方法

@Override
public int hashCode() {//1.获取到name的hashcode,内部已包装好 就是通过name去判断的int n1 = this.name.hashCode();//2.获取到age,简便就不获取hashcode的值了,已经可以进行唯一判断了int n2 = this.age;return n1+n2;
}@Override
public boolean equals(Object obj) {//1.判断是不是为同一个对象if(this==obj){return true;}//2.判断是否为空if(obj==null){return false;}//3.判断是否为Student类if(obj instanceof Student){Student s = (Student) obj;//4.进行所需比较if(this.getName()==s.getName() && this.getAge()==s.getAge()){return true;}}//5.都不满足return false;
}

HashSet源码 其实HashSet里面用的就是一个HashMap

private transient HashMap<E,Object> map;public HashSet() {map = new HashMap<>();}public boolean add(E e) {return map.put(e, PRESENT)==null;}

1.5.2 TreeSet

存储结构:红黑树

特点:1)基于排列顺序实现元素不重复

​ 2)实现了SortedSet接口,对元素进行了排序

​ 3)元素对象必须实现Compareable接口,指定排序规则

​ 4)通过Compareto方法确定是否为重复元素

案例:进行添加重复元素,观察TreeSet结果

public class test03_TreeSet {public static void main(String[] args) {TreeSet<Student> treeSet = new TreeSet<Student>();Student s1 = new Student("西八哥",22);Student s2 = new Student("王德发",32);Student s3 = new Student("Lolita",18);Student s4 = new Student("Lolita",18);treeSet.add(s1);treeSet.add(s2);treeSet.add(s3);treeSet.add(s4);System.out.println(treeSet.toString());}
}

注意:通过TreeSet存储引用类型,必须要实现Comparable的CompareTo方法

Student类中重写的CompareTo方法 (进行数据排序)

@Override
public int compareTo(Student o) {int n1 = this.getName().compareTo(o.getName());int n2 = this.getAge()-o.getAge();return n1==0?n2:n1;
}

对于实现Comparable接口的另一种实现方法,在创建TreeSet的时候,使用Compartor 匿名内部类直接重写CompareTo方法

TreeSet<Student> treeSet = new TreeSet<Student>(new Comparator<Student>() {@Overridepublic int compare(Student o1, Student o2) {int n1 = o1.getName().compareTo(o2.getName());int n2 = o1.getAge()-o2.getAge();return n1==0?n2:n1;}
});

案例:通过TreeSet判定字符串的大小

public class test03_TreeSetDemo {public static void main(String[] args) {TreeSet<String> treeSet = new TreeSet<String>(new Comparator<String>() {@Overridepublic int compare(String o1, String o2) {int n1 = o1.length()-o2.length();int n2 = o1.compareTo(o2);return n1==0?n2:n1;}});treeSet.add("helloworld");treeSet.add("pingguo");treeSet.add("lisi");treeSet.add("zhangsan");treeSet.add("beijing");treeSet.add("cat");System.out.println(treeSet.toString());}
}

二、Map集合类

特点:1)存储任意键值对,key-value

​ 2)键 :无序、无下标、不可重复

​ 3)值:无序、无下标、可重复

​ 4)如果存入相同的key,且识别为同一个对象,那对应的value会被新的value覆盖

案例:使用Map 进行数据增加 删除 和 遍历

public class test04_Map {public static void main(String[] args) {//1.Create a new mapMap<String,String> map = new HashMap<String,String>();//2.Add data to mapmap.put("one","XBOX");map.put("two","PS5");map.put("three","SWITCH");map.put("four","SWITCH");System.out.println(map.toString());//3.Delete datamap.remove("two");System.out.println(map.toString());//ps: If the same key,the value will be coveredmap.put("four","SWITCHHHHHHHHHHHH");//4.Print map - two way - keySet - EntrySet//keySetSystem.out.println("--------------By Key Set-----------------");Set<String> keySet = map.keySet();for (String key:keySet) {System.out.println(key+"--->"+map.get(key));}//EntrySetSystem.out.println("--------------By EntrySet-----------------");for (Map.Entry<String,String> set:map.entrySet()) {System.out.println(set.getKey()+"---->"+set.getValue());}}
}

2.1 HashMap

特点:线程不安全,运行效率快,允许使用null作为key、或者value

案例:使用Student类作为key , String类型作为value进行HashMap的操作

public class test04_HashMap {public static void main(String[] args) {//1.Create a new HashMap, key is Student - value is StringHashMap<Student,String> hashMap = new HashMap<>();hashMap.put(new Student("一花",20),"老大");hashMap.put(new Student("二乃",20),"老二");hashMap.put(new Student("三玖",20),"老三");System.out.println(hashMap.toString());//2.override hashcode and equals method to distinct the datahashMap.put(new Student("三玖",20),"忙内");System.out.println(hashMap.toString());//3. Delete、Print、ergodic、the same with Map}
}

注意:如果想要程序把新的Student对象 识别为已有,需要重写Student类的hashcodeequals方法

案例:Has和Map源码分析

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16   ---默认初始化大小
static final int MAXIMUM_CAPACITY = 1 << 30;                 ----最大的容量
static final float DEFAULT_LOAD_FACTOR = 0.75f;                     ---默认加载因子,到总大小的75%进行扩容
static final int TREEIFY_THRESHOLD = 8;                         ---当链表长度大于8,转换为红黑树
static final int UNTREEIFY_THRESHOLD = 6;                   ---当链表长度小于6  转化为链表
static final int MIN_TREEIFY_CAPACITY = 64;                     ---数组长度大于链表长度大于8,集合元素大于64转换红黑树
transient Node<K,V>[] table;                               ---哈希表中的 数组
transient int size;                                          ---元素个数

put方法源码

//1.调用putVal方法-->传对应值进去
public V put(K key, V value) {return putVal(hash(key), key, value, false, true);
}//2.进行数组resize,resize完毕后,把当前节点放入对应位置final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);
//3.resize完后,返回resize完后大小的数组final Node<K,V>[] resize() {Node<K,V>[] oldTab = table;int oldCap = (oldTab == null) ? 0 : oldTab.length;int oldThr = threshold;int newCap, newThr = 0;//中间代码省略Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];table = newTab;
//4.resize的扩容,当到达装载因子的边界,会进行扩容,是原来的两倍else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&oldCap >= DEFAULT_INITIAL_CAPACITY)newThr = oldThr << 1; // double threshold

过程解析:

1)HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16

2)当元素个数大于(16*0.75=12时),会进行扩容,扩容后会变为原来的2倍

3)JDK1.8之前是头插法,1.8之后是尾插法

2.2 TreeMap

特点:实现了SortedMap接口,可以对key自动排序,泛型对象要实现Comparable接口 同TreeSet

三、Collections工具类

案例:Collections工具类的方法使用

public class test05_Collections {public static void main(String[] args) {List<Integer> list = new ArrayList<>();list.add(10);list.add(156);list.add(121);list.add(1);//sortSystem.out.println(list.toString());Collections.sort(list);System.out.println(list.toString());//binarySearch return indexSystem.out.println(Collections.binarySearch(list,156));//copy ps:the length must sameList<Integer> list2 = new ArrayList<>();for (int i = 0; i < list.size(); i++) {list2.add(0);}Collections.copy(list2,list);System.out.println(list2.toString());//reverseCollections.reverse(list);System.out.println(list.toString());//shuffle break the orderCollections.shuffle(list);System.out.println(list.toString());//list convert to arrayInteger[] array = list.toArray(new Integer[10]);System.out.println(Arrays.toString(array));//array convert to listString[] names = {"A","B","C"};List<String> list3 = Arrays.asList(names);System.out.println(list3.toString());//ps: as int、byte type data need to use Integer、ByteInteger[] nums = {3,2,45};List<Integer> list4 = Arrays.asList(nums);System.out.println(list4.toString());}
}

【Java集合类】- Java集合类相关推荐

  1. JDK源码解析 迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的。

    JDK源码解析 迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的. 看完这段代码是不是很熟悉,与我们上面代码基本类似.单列集合都使用到了迭代器,我们以Arr ...

  2. Java多线程之集合类(线程安全和不安全)

    Java多线程之集合类(浅析线程安全和不安全) 本文目录: 1.线程不安全之ArrayList,HashSet,HashMap和线程安全之CopyOnWriteArrayList,CopyOnWrit ...

  3. Java程序设计4——集合类

    1 JAVA集合概述 Java集合封装了一系列数据结构比如链表.二叉树.栈.队列等,然后提供了针对这些数据结构的一系列算法比如查找.排序.替换,使编程难度大大降低.(这句话有可能是非法的,因为个人对算 ...

  4. java中的集合_你真的了解Java中的集合类么?

    Java中的集合类很多,有各种List,各种Map,各种Set.那么这么多类,我们怎么来区分它们呢? 我们来看某个集合类是以什么结尾的,如果以List结尾,那说明这个集合类的本质就是一个List,Li ...

  5. java学习笔记 - 集合类综合案例 斗地主

    集合类方法 最近学到java的各个集合类,常用的有List,Set,Map,这三个都是接口,其中List和Set继承了Collections. 为了锻炼实际掌握各种常用方法的案例,自己写了个斗地主案例 ...

  6. Java工程师 Java基础面试题集合类(Day06)

    1 Java中有哪些容器(集合类)? 参考答案 Java中的集合类主要由Collection和Map这两个接口派生而出,其中Collection接口又派生出三个子接口,分别是Set.List.Queu ...

  7. Java中的集合类——HashMap中的并发死链

    Java中的集合类--HashMap中的并发死链 ReHash过程 正常的ReHash过程: 并发的Rehash过程 解决办法 ReHash过程 正常的ReHash过程: 并发的Rehash过程 (1 ...

  8. java,java基础面试笔试题

    我总结出了很多互联网公司的面试题及答案,并整理成了文档,以及各种学习的进阶学习资料,免费分享给大家. 扫描二维码或搜索下图红色VX号,加VX好友,拉你进[程序员面试学习交流群]免费领取.也欢迎各位一起 ...

  9. [JAVA]全新java初学者实践教程(全)

    [JAVA]全新java初学者实践教程(全) 本教程适合初学者,高手飘过. 1.全新java初学者实践教程1(Java SE5.0版)--配置环境变量 2.全新java初学者实践教程2(Java SE ...

  10. 当年我们一起追过的Java,Java SE 个人笔记

    目录 JDK的安装和配置运行Java程序 java基本语法 面向对象 异常 多线程l API(Application Programming Interface)各种功能的类说明 集合类 IO输入输出 ...

最新文章

  1. ResNet最强改进版来啦!ResNest在多项任务中达到SOTA
  2. 架构师之路 — 分布式系统 — RPC 远程过程调用
  3. PHP网站开启gzip压缩,php中开启gzip压缩的2种方法代码
  4. 那些年我们一起写过的Python爬虫
  5. PHP——0128练习相关2——js点击button按钮跳转到另一个新页面
  6. 提升写作效率,让 Word 更好地为你所用
  7. ElasticSearch 5学习(2)——Kibana+X-Pack介绍使用(全)
  8. android随机摇号代码,抽奖摇号系统随机性算法介绍
  9. JAVA学习笔记 || 使用Point 类的注意事项
  10. 随机过程知识点学习与总结
  11. 今天不开心 和话痨机器人聊一会
  12. P3840蜗牛一期--虚拟局域网VLAN
  13. IT架构师_隽语集(Design Thinking _0101)
  14. jenkins下载插件慢
  15. 怎么把html设置桌面壁纸,win7系统怎么把桌面更换成自己喜欢的桌面背景?
  16. 切比雪夫多项式c语言csdn,切比雪夫多项式
  17. dz论坛在线咨询使用不了,解决办法
  18. Android 62 自制域名解析 服务 花生壳太贵
  19. C++ has-a关系之包含
  20. 69节入门python_第69天:Selenium详解

热门文章

  1. 已经有几百个制造企业的痛点问题在这了,你的在哪?
  2. 软件测试面试,一定要准备的7个高频面试题(附答案,建议收藏)
  3. 《解读基金我的投资观与实践》读后感
  4. 谈谈一些感触——自我反思和总结
  5. 鼎新图书馆结束使用计算机时,新生导航•【学习篇】| 学霸从图书馆开始
  6. 互联网基础与应用复习
  7. 八字取名,你应该要考虑的7个实用建议
  8. InnoDB:page_cleaner:1000ms intended loop 解决
  9. 华为云物联网平台创建产品与设备(含MQTT.fx测试)
  10. JAVA毕业设计web唐院寻人表白系统计算机源码+lw文档+系统+调试部署+数据库