Java集合(完整版)

打印 上一主题 下一主题

主题 747|帖子 747|积分 2241

集合框架

Collection集合

概念:对象的容器,界说了对多个对象进行操作的常用方法。可以实现数组的功能
和数组的区别:


  • 数组的长度固定,集合长度不固定
  • 数组可以存储基本范例和引用范例,集合只能存储引用范例
Collection体系集合

如图所示:

Collection:该体系结构的跟接口,代表一组对象,称为“集合”
List接口特点:有序,有下标,元素可重复
Set接口特点:无序,无下标,元素不可重复
Collection父接口

特点:代表一组恣意范例的对象,无序,无下标,不能重复
方法:


  • boolean add (Object obj) // 添加一个对象
  • boolean addAll (Collection c) // 将一个集合中的所有对象添加到此集合中
  • void clear () // 清空此集合中的所有对象
  • boolean contains (Object o) // 查抄此集合中是否包含o对象
  • boolean equals (Object o) // 比较此集合是否与指定对象相等
  • boolean isEmpty () // 判断此集合是否为空
  • boolean remove (Object o) // 在此集合中移除o对象
  • int size () // 返回此集合中的元素个数
  • Object [ ] toArray () // 将此集合转换成数组
    下面是保存字符串的代码验证:
    1. package com.collection.Demo01;
    2. import java.util.ArrayList;
    3. import java.util.Collection;
    4. import java.util.Iterator;
    5. public class Demo01 {
    6.     public static void main(String[] args) {
    7.         // 创建集合
    8.         // 一、 保存字符串
    9.         Collection collection = new ArrayList();
    10.         // 1. 添加元素
    11.         collection.add("苹果");
    12.         collection.add("西瓜");
    13.         collection.add("榴莲");
    14.         System.out.println("添加之后的元素个数:" + collection.size());  // 添加之后的元素个数:3
    15.         System.out.println(collection);  // [苹果, 西瓜, 榴莲]
    16.         // 2. 删除元素
    17.         // collection.remove("榴莲");
    18.         // collection.remove("西瓜");
    19.         // System.out.println("删除之后剩余的元素个数:"+ collection.size());  // 删除之后剩余的元素个数:1
    20.        // 2.1 清空元素
    21. //        collection.clear();
    22. //        System.out.println("清空元素剩余:" + collection.size());  // 清空元素剩余:0
    23.         // 3. 遍历元素
    24.         // 3.1 使用增强for
    25.         System.out.println("----------3.1 使用增强for-------------");
    26.         for (Object obj:collection
    27.              ) {
    28.             System.out.println(obj);
    29.         }
    30.         /*
    31.         ----------3.1 使用增强for-------------
    32.         苹果
    33.         西瓜
    34.         榴莲
    35.          */
    36.         // 3.2 使用迭代器(迭代器是专门用来遍历集合的一种方式)
    37.         // hasNext(); 有没有下一个元素
    38.         // next(); 获取下一个元素
    39.         // remove(); 删除当前元素
    40.         System.out.println("----------3.2 使用迭代器-------------");
    41.         Iterator it = collection.iterator();
    42.         while(it.hasNext()){
    43.             String s = (String)it.next();
    44.             System.out.println(s);
    45.             // 不能使用collection删除方法
    46.             // collection.remove(s);  // ConcurrentModificationException   并发修改异常
    47.             // it.remove();     // 迭代器提供的方法
    48.         }
    49.         System.out.println("剩余的元素个数: "+ collection.size());
    50.         /*
    51.         ----------3.2 使用迭代器-------------
    52.         苹果
    53.         西瓜
    54.         榴莲
    55.         剩余的元素个数: 3
    56.          */
    57.         // 4. 判断
    58.         System.out.println(collection.contains("xigua"));  // false
    59.         System.out.println(collection.contains("西瓜"));  // true
    60.         System.out.println(collection.isEmpty());  // false     判断是否为空// null空 为 true ; not null非空 为 false
    61.     }
    62. }
    复制代码
下面是保存学生信息的代码实现:
学生类 Student:
  1. package com.collection.Demo01;
  2. /**
  3. * 学生类
  4. */
  5. public class Student {
  6.     private String name ;
  7.     private int age ;
  8.     public Student(String name, int age) {
  9.         this.name = name;
  10.         this.age = age;
  11.     }
  12.     public Student() {
  13.     }
  14.     public String getName() {
  15.         return name;
  16.     }
  17.     public void setName(String name) {
  18.         this.name = name;
  19.     }
  20.     public int getAge() {
  21.         return age;
  22.     }
  23.     public void setAge(int age) {
  24.         this.age = age;
  25.     }
  26.     @Override        // 重写方法
  27.     public String toString() {
  28.         return "学生信息:[name=" + name + ",age="+age + "]";
  29.     }
  30.     @Override        // 重写方法
  31.     public boolean equals(Object obj) {
  32.         // 1 判断是不是同一个对象
  33.         if (this==obj){
  34.             return true;
  35.         }
  36.         // 2 判断是否为空
  37.         if (obj==null){
  38.             return false;
  39.         }
  40.         // 3 判断是否是Student类型
  41.         if(obj instanceof Student){
  42.             Student s = (Student) obj;
  43.             // 4 比较属性
  44.             if (this.name.equals(s.getName())&&this.age==s.getAge()){
  45.                 return true;
  46.             }
  47.         }
  48.         // 5 不满足条件返回false
  49.         return false;
  50.     }
  51. }
复制代码
代码验证:
  1. package com.collection.Demo01;
  2. import java.util.ArrayList;
  3. import java.util.Collection;
  4. import java.util.Iterator;
  5. public class Demo02 {
  6.     public static void main(String[] args) {
  7.         // 新建 Collection 对象
  8.         Collection collection = new ArrayList();
  9.         Student s1 = new Student("张三",18);
  10.         Student s2 = new Student("李四",17);
  11.         Student s3 = new Student("王五",19);
  12.         // 1. 添加数据
  13.         collection.add(s1);
  14.         collection.add(s2);
  15.         collection.add(s3);
  16.         System.out.println("元素个数:" + collection.size());  // 元素个数:3
  17.         System.out.println(collection);  // [学生信息:[name=张三,age=18], 学生信息:[name=李四,age=17], 学生信息:[name=王五,age=19]]
  18.         // 2. 删除数据
  19.         // collection.remove(s2);
  20.         // collection.remove(new Student("王五",19));  // 并没有删除
  21.         // collection.clear();
  22.         // System.out.println("删除之后的剩余元素:" + collection.size());  // 删除之后的剩余元素:0    // 只是删掉了地址
  23.         // 3. 遍历
  24.         // 3.1 增强for
  25.         System.out.println("--------增强for------");
  26.         for (Object obj:collection) {
  27.                 Student s = (Student) obj;
  28.             System.out.println(s.toString());
  29.         }
  30.         /*
  31.         --------增强for------
  32.         学生信息:[name=张三,age=18]
  33.         学生信息:[name=李四,age=17]
  34.         学生信息:[name=王五,age=19]
  35.          */
  36.         // 3.2 迭代器
  37.         // hasNext();   next();   remove();     迭代过程中不能使用collection的删除方法
  38.         System.out.println("--------迭代器------");
  39.         Iterator it = collection.iterator();
  40.         while (it.hasNext()){
  41.             Student s = (Student)it.next();
  42.             System.out.println(s);
  43.         }
  44.         /*
  45.         --------迭代器------
  46.         学生信息:[name=张三,age=18]
  47.         学生信息:[name=李四,age=17]
  48.         学生信息:[name=王五,age=19]
  49.          */
  50.         // 4. 判断
  51.         System.out.println(collection.contains(s1));  // true
  52.         System.out.println(collection.isEmpty());  // false
  53.     }
  54. }
复制代码
List子接口

特点:有序,有下标,元素可以重复
方法:


  • void add (int index,Object o) // 在index位置插入对象
  • boolean addAll (int index,Collection c) 将一个集合中的元素添加到此集合中的index 位置
  • Object get (int index) // 返回集合中指定位置的元素
  • List subList (int fromIndex,int toIndex) // 返回fromIndex和toIndex之间的集合元素
下面是字符串案例:
  1. package com.collection.list;
  2. import java.util.ArrayList;
  3. import java.util.Iterator;
  4. import java.util.List;
  5. import java.util.ListIterator;
  6. public class Demo01 {
  7.     public static void main(String[] args) {
  8.         // 先创建集合对象
  9.         List list = new ArrayList();
  10.         // 1. 添加元素
  11.         list.add("小米");
  12.         list.add("华为");
  13.         list.add(0,"苹果");
  14.         System.out.println("元素个数:" + list.size());  // 元素个数:3
  15.         System.out.println(list.toString());  // [苹果, 小米, 华为]
  16.         // 2. 删除元素
  17.         // list.remove("华为");
  18.         // list.remove(1);
  19.         // System.out.println("删除之后还剩余:" + list.size());  // 删除之后还剩余:1
  20.         // System.out.println(list);  // [苹果]
  21.         // 3. 遍历
  22.         // 3.1 使用for遍历
  23.         System.out.println("--------使用for遍历--------");
  24.         for (int i = 0; i < list.size(); i++) {
  25.             System.out.println(list.get(i));
  26.         }
  27.         /*
  28.         --------使用for遍历--------
  29.         苹果
  30.         小米
  31.         华为
  32.          */
  33.         // 3.2 使用增强for
  34.         System.out.println("--------使用增强for--------");
  35.         for (Object obj:list
  36.              ) {
  37.             System.out.println(obj);
  38.         }
  39.         /*
  40.         --------使用增强for--------
  41.         苹果
  42.         小米
  43.         华为
  44.          */
  45.         // 3.3 使用迭代器
  46.         Iterator it = list.iterator();
  47.         System.out.println("--------使用迭代器--------");
  48.         while (it.hasNext()){
  49.             System.out.println(it.next());
  50.         }
  51.         /*
  52.         --------使用迭代器--------
  53.         苹果
  54.         小米
  55.         华为
  56.          */
  57.         // 3.4 使用列表迭代器,和Iterator的区别: ListIterator可以向前或者向后遍历,添加,删除,修改元素
  58.         ListIterator lit = list.listIterator();
  59.         System.out.println("--------使用列表迭代器==从前往后--------");
  60.         while(lit.hasNext()){
  61.             System.out.println(lit.nextIndex()+":" +lit.next());
  62.         }
  63.         /*
  64.         --------使用列表迭代器==从前往后--------
  65.         0:苹果
  66.         1:小米
  67.         2:华为
  68.          */
  69.         System.out.println("--------使用列表迭代器==从后往前--------");
  70.         while (lit.hasPrevious()){
  71.             System.out.println(lit.previousIndex()+": "+lit.previous());
  72.         }
  73.         /*
  74.         2: 华为
  75.         1: 小米
  76.         0: 苹果
  77.          */
  78.         // 4. 判断
  79.         System.out.println(list.contains("苹果"));  // true
  80.         System.out.println(list.isEmpty());  // false
  81.         // 5.获取位置
  82.         System.out.println(list.indexOf("苹果"));  // 0
  83.         System.out.println(list.indexOf("华为"));  // 2
  84.     }
  85. }
复制代码
下面是数字,基本范例(自动装箱):
  1. package com.collection.list;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. public class Demo02 {
  5.     public static void main(String[] args) {
  6.         // 创建集合
  7.         List list = new ArrayList();
  8.         // 1. 添加数字数据(自动装箱)
  9.         list.add(10);
  10.         list.add(20);
  11.         list.add(30);
  12.         list.add(40);
  13.         list.add(50);
  14.         System.out.println("元素个数:"+list.size());  // 元素个数:5
  15.         System.out.println(list);  // [10, 20, 30, 40, 50]
  16.         // 2. 删除操作
  17.         // list.remove(2);
  18.         // list.remove(new Integer(20));
  19.         // list.remove((Object) 40);
  20.         // System.out.println("删除元素:" + list.size());  // 删除元素:2
  21.         // System.out.println(list);  // [10, 50]
  22.         // 3. 补充方法:subList  返回子集合,左闭右开区间  [ )
  23.         List subList = list.subList(1,4);
  24.         System.out.println(subList);  // [20, 30, 40]
  25.     }
  26. }
复制代码
下面是学生信息:
学生类同上:
  1. package com.collection.list;
  2. import com.collection.Demo01.Student;
  3. import java.util.ArrayList;
  4. import java.util.Iterator;
  5. import java.util.ListIterator;
  6. public class Demo03 {
  7.     public static void main(String[] args) {
  8.         // 创建集合
  9.         ArrayList arrayList = new ArrayList();
  10.         // 1. 添加元素
  11.         Student s1 = new Student("源氏",18);
  12.         Student s2 = new Student("艾什",18);
  13.         Student s3 = new Student("狂鼠",19);
  14.         arrayList.add(s1);
  15.         arrayList.add(s2);
  16.         arrayList.add(s3);
  17.         System.out.println("元素个数:"+arrayList.size());  // 元素个数:3
  18.         System.out.println(arrayList);  // [学生信息:[name=源氏,age=18], 学生信息:[name=艾什,age=18], 学生信息:[name=狂鼠,age=19]]
  19.         // 2. 删除元素
  20.         // arrayList.remove(new Student("狂鼠",19));  // equals(this==obj)
  21.         // arrayList.remove(s2);
  22.         // System.out.println("删除之后:" + arrayList.size());  // 删除之后:1
  23.         // System.out.println(arrayList);  // [学生信息:[name=源氏,age=18]]
  24.         // 3. 遍历元素  ⭐
  25.         // 使用迭代器
  26.         System.out.println("----------使用迭代器----------");
  27.         Iterator it = arrayList.iterator();
  28.         while (it.hasNext()){
  29.             Student s = (Student) it.next();
  30.             System.out.println(s.toString());
  31.         }
  32.         /*
  33.         ----------使用迭代器----------
  34.         学生信息:[name=源氏,age=18]
  35.         学生信息:[name=艾什,age=18]
  36.         学生信息:[name=狂鼠,age=19]
  37.          */
  38.         // 使用列表迭代器
  39.         ListIterator lit = arrayList.listIterator();
  40.         System.out.println("----------使用列表迭代器==顺序----------");
  41.         while (lit.hasNext()){
  42.             Student s = (Student) lit.next();
  43.             System.out.println(s.toString());
  44.         }
  45.         /*
  46.         ----------使用列表迭代器==顺序----------
  47.         学生信息:[name=源氏,age=18]
  48.         学生信息:[name=艾什,age=18]
  49.         学生信息:[name=狂鼠,age=19]
  50.          */
  51.         System.out.println("----------使用列表迭代器==逆序----------");
  52.         while (lit.hasPrevious()){
  53.             Student s = (Student) lit.previous();
  54.             System.out.println(s.toString());
  55.         }
  56.         /*
  57.         ----------使用列表迭代器==逆序----------
  58.         学生信息:[name=狂鼠,age=19]
  59.         学生信息:[name=艾什,age=18]
  60.         学生信息:[name=源氏,age=18]
  61.          */
  62.         // 4. 判断
  63.         System.out.println(arrayList.contains(new Student("狂鼠",19)));  // true
  64.         System.out.println(arrayList.contains(s2));  // true
  65.         System.out.println(arrayList.isEmpty());  // false
  66.         // 5. 查找
  67.         System.out.println(arrayList.indexOf(new Student("狂鼠",19)));  // 2
  68.         System.out.println(arrayList.indexOf(new Student("源氏",19)));  // -1  // 年龄应为18 ,没有查找到返回-1
  69.     }
  70. }
复制代码
List 实现类



  • ArrayList [重点]:
    数组结构实现,查询快,增删慢
    JDK1.2版本,运行效率快,线程不安全
  • Vector:
    数组结构实现,查询快,增删慢
    JDK1.0版本,运行效率慢,线程安全
  • LinkedList:
    链表结构实现,增删快,查询慢
ArrayList

源码分析:
DEFAULT_CAPACITY = 10 ; 默认容量
​ 留意:如果没有向集合中添加任何元素时,容量为0;
​ 添加一个元素之后,容量为10;
​ 每次扩容的巨细是原来的1.5倍
elementDate 存放元素的数组
size 实际元素个数
add () 添加元素
Vector

Vector简介
Vector 是矢量队列,它是JDK1.0版本添加的类。继承于AbstractList,实现了List, RandomAccess, Cloneable这些接口。
Vector 继承了AbstractList,实现了List;所以,它是一个队列,支持相关的添加、删除、修改、遍历等功能
Vector 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在Vector中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。
Vector 实现了Cloneable接口,即实现clone()函数。它能被克隆。
和ArrayList不同,Vector中的操作是线程安全的
(01) Vector实际上是通过一个数组去保存数据的。当我们构造Vecotr时;若利用默认构造函数,则Vector的默认容量巨细是10
(02) 当Vector容量不敷以容纳全部元素时,Vector的容量会增长。若容量增长系数 >0,则将容量的值增长“容量增长系数”;否则,将容量巨细增长一倍。
(03) Vector的克隆函数,便是将全部元素克隆到一个数组中。
  1. package com.collection.vector;
  2. import java.util.Enumeration;
  3. import java.util.Vector;
  4. public class Demo01 {
  5.     public static void main(String[] args) {
  6.         // 创建集合
  7.         Vector vector = new Vector();
  8.         // 1. 添加元素
  9.         vector.add("苹果");
  10.         vector.add("草莓");
  11.         vector.add("葡萄");
  12.         System.out.println("元素个数:"+vector.size());  // 元素个数:3
  13.         System.out.println(vector);  // [苹果, 草莓, 葡萄]
  14.         // 2. 删除元素
  15.         // vector.remove(0);
  16.         // vector.remove("葡萄");
  17.         // vector.clear();
  18.         // System.out.println("元素个数:" + vector.size());  // 元素个数:0
  19.         // 3. 遍历
  20.         // 使用枚举器
  21.         Enumeration en = vector.elements();
  22.         while (en.hasMoreElements()){
  23.             String str = (String)en.nextElement();
  24.             System.out.println(str);
  25.         }
  26.         /*
  27.         苹果
  28.         草莓
  29.         葡萄
  30.          */
  31.         // 4. 判断
  32.         System.out.println(vector.contains("葡萄"));  // true
  33.         System.out.println(vector.isEmpty());  // false
  34.         // 5. 其他方法
  35.         System.out.println(vector.firstElement());  // 苹果
  36.         System.out.println(vector.lastElement());  // 葡萄
  37.         System.out.println(vector.elementAt(1));  // 草莓
  38.     }
  39. }
复制代码
LinkedList

LinkedList官方文档
LinkedList的底层是双向链表结构,由于链表没有将元素存储在连续的空间中,而是存储在单独的节点中,然后通过引用将节点连接起来了,因此在恣意位置插入大概删除元素时,不需要搬移元素,效率比较高。
留意:
LinkedList实现了List接口
LinkedList的底层利用了双向链表
LinkedList没有实现RandomAccess接口,因此LinkedList不支持随机访问
LinkedList的恣意位置插入和删除元素时效率比较高,时间复杂度为O(1)
LinkedList比较适合恣意位置插入的场景
  1. package com.collection.vector;
  2. import java.util.Enumeration;
  3. import java.util.Vector;
  4. public class Demo01 {
  5.     public static void main(String[] args) {
  6.         // 创建集合
  7.         Vector vector = new Vector();
  8.         // 1. 添加元素
  9.         vector.add("苹果");
  10.         vector.add("草莓");
  11.         vector.add("葡萄");
  12.         System.out.println("元素个数:"+vector.size());  // 元素个数:3
  13.         System.out.println(vector);  // [苹果, 草莓, 葡萄]
  14.         // 2. 删除元素
  15.         // vector.remove(0);
  16.         // vector.remove("葡萄");
  17.         // vector.clear();
  18.         // System.out.println("元素个数:" + vector.size());  // 元素个数:0
  19.         // 3. 遍历
  20.         // 使用枚举器
  21.         Enumeration en = vector.elements();
  22.         while (en.hasMoreElements()){
  23.             String str = (String)en.nextElement();
  24.             System.out.println(str);
  25.         }
  26.         /*
  27.         苹果
  28.         草莓
  29.         葡萄
  30.          */
  31.         // 4. 判断
  32.         System.out.println(vector.contains("葡萄"));  // true
  33.         System.out.println(vector.isEmpty());  // false
  34.         // 5. 其他方法
  35.         System.out.println(vector.firstElement());  // 苹果
  36.         System.out.println(vector.lastElement());  // 葡萄
  37.         System.out.println(vector.elementAt(1));  // 草莓
  38.     }
  39. }
复制代码
ArrayList和LinkedList的区别
ArrayList的物理存储空间是连续的,LinkedList物理上不一定连续。
ArrayList支持随机访问,LinkedList不支持随机访问。
ArrayList在插入和删除的时候时间复杂度O(N),LinkedList时间复杂度O(1);所以LinkedList适合频繁插入和删除的场景。
ArrayList空间不够需要动态扩容,LinkedList不需要。
泛型

Java泛型是JDK1.5中引入的一个新特性,其本质是参数化范例,把范例作为参数传递
常见形式有:泛型类、泛型接口、泛型方法
语法: T 称为范例占位符,表示一种引用范例
长处:1 提高代码的重(chong)用性
​ 2 防止范例转换异常,提高代码的安全性
下面是泛型类:
  1. package com.collection.generic;
  2. public class Generic<T> {
  3.     // 泛型类:Generic<T>
  4.     // 语法: 类名<T>
  5.     // T是类型占位符,表示一种引用类型,如果编写多个使用逗号隔开
  6.     // 使用泛型 T
  7.     // 1. 创建变量
  8.     // 泛型不能实例化
  9.     T t ;
  10.     // 2. 泛型作为方法的参数
  11.     public void show(T t){
  12.         System.out.println("泛型作为方法的参数:" + t);
  13.     }
  14.     // 3. 泛型作为方法的返回值
  15.     public T getT(){
  16.         // return (T)("泛型作为方法的返回值" + t);
  17.          return t;
  18.     }
  19. }
复制代码
下面是泛型方法:
  1. package com.collection.generic;
  2. /**
  3. *
  4. * 泛型方法
  5. * 语法:<T>返回值类型
  6. *
  7. */
  8. public class GenericMethod {
  9.     // 泛型方法
  10.     public <T> T show(T t){
  11.         System.out.println("泛型方法 "+ t);
  12.         return t;
  13.     }
  14. }
复制代码
下面是泛型接口:
  1. 接口
  2. package com.collection.generic;
  3. /**
  4. * 泛型接口
  5. * 语法:接口名<T>
  6. * 注意:不能创建静态常量
  7. * @param <T>
  8. */
  9. public interface GenericService<T> {
  10.     String name = "张三";
  11.     T server(T t);
  12. }
复制代码
  1. package com.collection.generic;
  2. public class GenericServiceImpl implements GenericService<String>{
  3.     @Override
  4.     public String server(String t) {
  5.         System.out.println(t);
  6.         return t;
  7.     }
  8. }
复制代码
  1. package com.collection.generic;
  2. public class GenericServiceImpl2<T> implements GenericService<T>{
  3.     @Override
  4.     public T server(T t) {
  5.         System.out.println(t);
  6.         return t;
  7.     }
  8. }
复制代码
泛型测试:
  1. package com.collection.generic;
  2. public class TestGeneric {
  3.     public static void main(String[] args) {
  4.         // 使用泛型类创建对象
  5.         /*
  6.         注意:
  7.         1. 泛型只能使用引用类型
  8.         2. 不同泛型类型对象之间不能相互赋值
  9.          */
  10.         Generic<String> generic = new Generic<String>();
  11.         generic.t = "Java";
  12.         generic.show("我爱学习Java,大家加油!");  // 泛型作为方法的参数:我爱学习Java,大家加油!
  13.         String string = generic.getT();
  14.         System.out.println(string);  // Java
  15.         Generic<Integer> generic1 = new Generic<>();
  16.         generic1.t = 18;
  17.         generic1.show(180);  // 泛型作为方法的参数:180
  18.         Integer integer = generic1.getT();
  19.         System.out.println(integer);  // 18
  20.         // 泛型接口
  21.         GenericService gs = new GenericServiceImpl();
  22.         gs.server("java");  // java
  23.         GenericService gs2 = new GenericServiceImpl2();
  24.         gs2.server(10086);  // 10086
  25.         // 泛型方法
  26.         GenericMethod gm = new GenericMethod();
  27.         gm.show("java is best!");  // 泛型方法 java is best!
  28.         gm.show(10086);  // 泛型方法 10086
  29.         gm.show(3.1415926);  // 泛型方法 3.1415926
  30.     }
  31. }
复制代码
泛型集合
概念:参数化范例、范例安全的集合、逼迫集合元素的范例必须同等
特点:


  • 编译时即可查抄,而非运营时抛出异常
  • 访问时,不必范例转换(拆箱)
  • 不同泛型之间引用不能相互赋值,泛型不存在多态
Set子接口


  • Set 接口是Collection的子接口,相当于数学上的集合
  • 特点:

    • 不答应元素重复,添加雷同的元素,返回false
    • 无序,无下标。不会记载元素的先后添加顺序
    • 判断俩个元素是否相等用的是equals方法

  • 方法:全部继承自Collection中的方法
Set实现类


  • HashSet 是Set 最长用的接口,底层利用Hash(散列)算法,查询和插入速度较快
  • HashSet 判断俩个对象是否相等,equals比较
  • 对象的HashCode值决定了在Hash表中的位置

    • 判断添加对象和集合元素对象HashCode值

      • 不等: 直接将新添加对象存储导对应位置
      • 相等: 再继承判断新对象和集合中对象的具体值:

        • HashCode 雷同,equals true ,则是同一个对象,则不保存hashtable中
        • HashCode 雷同,equals false,存储到同槽的链表上





  • 基于HashCode计算元素存放位置
  • 当存入元素的哈希码雷同时,会调用equals进行确认,如果为true 则拒绝后者存入
测试Set接口的利用:
  1. package com.collection.set;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. import java.util.Set;
  5. /**
  6. *
  7. * 测试Set接口的使用
  8. * 特点:无序、无下标 且 不能重复
  9. *
  10. */
  11. public class Demo01 {
  12.     public static void main(String[] args) {
  13.         // 创建集合
  14.         Set<String> set = new HashSet<>();
  15.         // 1. 添加数据
  16.         set.add("苹果");
  17.         set.add("小米");
  18.         set.add("华为");
  19.         // set.add("华为");  // 不能重复的
  20.         System.out.println("元素个数: "+ set.size());  // 元素个数: 3
  21.         System.out.println(set.toString());  // [苹果, 华为, 小米]  // 是无序的
  22.         // 2. 删除数据
  23.         // set.remove("华为");
  24.         // System.out.println(set);  // [苹果, 小米]
  25.         // 3. 遍历  ⭐
  26.         // 3.1 使用增强for
  27.         System.out.println("--------使用增强for---------");
  28.         for (Object obj:set
  29.              ) {
  30.             System.out.println(obj);
  31.         }
  32.         /*
  33.         --------使用增强for---------
  34.         苹果
  35.         华为
  36.         小米
  37.          */
  38.         // 3.2 使用迭代器
  39.         System.out.println("--------使用迭代器---------");
  40.         Iterator<String> it = set.iterator();
  41.         while (it.hasNext()){
  42.             System.out.println(it.next());
  43.         }
  44.         /*
  45.         --------使用迭代器---------
  46.         苹果
  47.         华为
  48.         小米
  49.          */
  50.         // 4. 判断
  51.         System.out.println(set.contains("苹果"));  // true
  52.         System.out.println(set.isEmpty());  // false
  53.     }
  54. }
复制代码
HashSet集合的利用 1 :
  1. package com.collection.set;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. /**
  5. *
  6. * HashSet集合的使用
  7. * 存储结构:哈希表(数组+链表+红黑树)
  8. */
  9. public class Demo02 {
  10.     public static void main(String[] args) {
  11.         // 新建集合
  12.         HashSet<String> hashSet = new HashSet<>();
  13.         // 1. 添加元素
  14.         hashSet.add("源氏");
  15.         hashSet.add("闪光");
  16.         hashSet.add("狂鼠");
  17.         hashSet.add("艾什");
  18.         hashSet.add("小美");
  19.         // hashSet.add("小美");  // 重复的不添加
  20.         System.out.println("元素个数:"+hashSet.size());  // 元素个数:5
  21.         System.out.println(hashSet.toString());  // [狂鼠, 源氏, 艾什, 小美, 闪光]
  22.         // 2. 删除
  23.         // hashSet.remove("源氏");
  24.         // System.out.println(hashSet.toString());  // [狂鼠, 艾什, 小美, 闪光]
  25.         // hashSet.clear();
  26.         // System.out.println(hashSet);  // []
  27.         // 3. 遍历
  28.         // 3.1 使用增强for
  29.         System.out.println("------使用增强for--------");
  30.         for (String s:hashSet
  31.              ) {
  32.             System.out.println(s);
  33.         }
  34.         /*
  35.         ------使用增强for--------
  36.         狂鼠
  37.         源氏
  38.         艾什
  39.         小美
  40.         闪光
  41.          */
  42.         // 3.2 使用迭代器
  43.         System.out.println("------使用迭代器--------");
  44.         Iterator it = hashSet.iterator();
  45.         while (it.hasNext()){
  46.             System.out.println(it.next());
  47.         }
  48.         /*
  49.         ------使用迭代器--------
  50.         狂鼠
  51.         源氏
  52.         艾什
  53.         小美
  54.         闪光
  55.          */
  56.         // 4. 判断
  57.         System.out.println(hashSet.contains("死神"));  // false
  58.         System.out.println(hashSet.contains("源氏"));  // true
  59.         System.out.println(hashSet.isEmpty());   // false
  60.     }
  61. }
复制代码
HashSet集合的利用 2 :
  1. package com.collection.set;
  2. import java.util.HashSet;
  3. import java.util.Iterator;
  4. /**
  5. * HashSet集合的使用
  6. * 存储结构:哈希表(数组+链表+红黑树)
  7. * 存储过程:
  8. *      1. 根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步
  9. *      2. 再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
  10. */
  11. public class Demo03 {
  12.     public static void main(String[] args) {
  13.         // 创建集合
  14.         HashSet<Person> people = new HashSet<>();
  15.         // 1. 添加数据
  16.         Person p1 = new Person("源氏",18);
  17.         Person p2 = new Person("艾什",19);
  18.         Person p3 = new Person("闪光",20);
  19.         Person p4 = new Person("狂鼠",21);
  20.         people.add(p1);
  21.         people.add(p2);
  22.         people.add(p3);
  23.         people.add(p4);
  24.         // people.add(p4);  // 重复 不添加
  25.         people.add(new Person("狂鼠",21));  // 重写了hashcode方法与equals方法
  26.         System.out.println("元素个数:"+ people.size());  // 元素个数:4
  27.         System.out.println(people.toString());  // [Person{name='闪光', age=20}, Person{name='艾什', age=19}, Person{name='源氏', age=18}, Person{name='狂鼠', age=21}]
  28.         // 2. 删除
  29.         // people.remove(p1);
  30.         // people.remove(new Person("狂鼠",21));  // 因为重写hashcode方法与equals方法,所以也可以
  31.         // System.out.println("删除后:"+people.size());  // 删除后:2
  32.         // System.out.println(people);  // [Person{name='闪光', age=20}, Person{name='艾什', age=19}]
  33.         // 3. 遍历  ⭐
  34.         // 3.1 使用增强for
  35.         System.out.println("------使用增强for--------");
  36.         for (Person person:people
  37.              ) {
  38.             System.out.println(person.toString());
  39.         }
  40.         /*
  41.         ------使用增强for--------
  42.         Person{name='闪光', age=20}
  43.         Person{name='艾什', age=19}
  44.         Person{name='源氏', age=18}
  45.         Person{name='狂鼠', age=21}
  46.          */
  47.         // 3.2 使用迭代器
  48.         System.out.println("------使用迭代器--------");
  49.         Iterator<Person> it = people.iterator();
  50.         while (it.hasNext()){
  51.             System.out.println(it.next());
  52.         }
  53.         /*
  54.         ------使用迭代器--------
  55.         Person{name='闪光', age=20}
  56.         Person{name='艾什', age=19}
  57.         Person{name='源氏', age=18}
  58.         Person{name='狂鼠', age=21}
  59.          */
  60.         // 4. 判断
  61.         System.out.println(people.contains(new Person("狂鼠",21)));  // true
  62.         System.out.println(people.contains(p2));  // true
  63.         System.out.println(people.isEmpty());  // false
  64.     }
  65. }
复制代码
  1. Person类
  2. package com.collection.set;
  3. import java.util.Objects;
  4. public class Person {
  5.     private String name ;
  6.     private int age;
  7.     public Person() {
  8.     }
  9.     public Person(String name, int age) {
  10.         super();
  11.         this.name = name;
  12.         this.age = age;
  13.     }
  14.     public String getName() {
  15.         return name;
  16.     }
  17.     public void setName(String name) {
  18.         this.name = name;
  19.     }
  20.     public int getAge() {
  21.         return age;
  22.     }
  23.     public void setAge(int age) {
  24.         this.age = age;
  25.     }
  26.     @Override
  27.     public String toString() {
  28.         return "Person{" +
  29.                 "name='" + name + '\'' +
  30.                 ", age=" + age +
  31.                 '}';
  32.     }
  33.     // 快捷键 快速 重写equals 和 hashCode 方法
  34.     @Override
  35.     public boolean equals(Object o) {
  36.         if (this == o) return true;
  37.         if (o == null || getClass() != o.getClass()) return false;
  38.         Person person = (Person) o;
  39.         return age == person.age && Objects.equals(name, person.name);
  40.     }
  41.     @Override
  42.     public int hashCode() {
  43.         return Objects.hash(name, age);
  44.     }
  45.    
  46.    
  47. //    @Override
  48. //    public boolean equals(Object o) {
  49. //        if (this == o)
  50. //        {
  51. //            return true;
  52. //        }
  53. //        if (o == null ){
  54. //            return false;
  55. //        }
  56. //        if (o instanceof Person){
  57. //            Person p = (Person) o;
  58. //            if (this.name.equals(p.getName())&&this.age==p.getAge()){
  59. //                return true;
  60. //            }
  61. //        }
  62. //        return false;
  63. //    }
  64. //
  65. //    @Override
  66. //    public int hashCode() {
  67. //        int n1 = this.name.hashCode();
  68. //        int n2 = this.age;
  69. //        return n1+n2;
  70. //    }
  71. }
复制代码
TreeSet



  • 基于排序顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的范例必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素
下面是TreeSet的利用
  1. package com.collection.treeset;
  2. import java.util.Iterator;
  3. import java.util.TreeSet;
  4. /**
  5. * TreeSet 的使用
  6. * 存储结构:红黑树
  7. */
  8. public class Demo01 {
  9.     public static void main(String[] args) {
  10.         // 创建集合
  11.         TreeSet<String> treeSet = new TreeSet<>();
  12.         // 1. 添加元素
  13.         treeSet.add("xyz");
  14.         treeSet.add("abc");
  15.         treeSet.add("java");
  16.         treeSet.add("c++");
  17.         treeSet.add("java");  // 元素重复不添加
  18.         System.out.println("元素个数:"+treeSet.size());  // 元素个数:4
  19.         System.out.println(treeSet.toString());  // [abc, c++, java, xyz]
  20.         // 2. 删除元素
  21. //        treeSet.remove("java");
  22. //        treeSet.remove("c++");
  23. //        System.out.println("删除元素:"+ treeSet.size());  // 删除元素:2
  24. //        System.out.println(treeSet.toString());  // [abc, xyz]
  25.         // 3. 遍历
  26.         // 3.1 使用增强for
  27.         System.out.println("---------使用增强for--------");
  28.         for (String s: treeSet) {
  29.             System.out.println(s);
  30.         }
  31.         /*
  32.         ---------使用增强for--------
  33.         abc
  34.         c++
  35.         java
  36.         xyz
  37.          */
  38.         // 3.2 使用迭代器
  39.         System.out.println("---------使用迭代器--------");
  40.         Iterator<String> it = treeSet.iterator();
  41.         while (it.hasNext()){
  42.             System.out.println(it.next());
  43.         }
  44.         /*
  45.         ---------使用迭代器--------
  46.         abc
  47.         c++
  48.         java
  49.         xyz
  50.          */
  51.         // 4. 判断
  52.         System.out.println(treeSet.contains("java"));  // true
  53.         System.out.println(treeSet.contains("php"));  // false
  54.         System.out.println(treeSet.isEmpty());  // false
  55.     }
  56. }
复制代码
利用TreeSet保存数据
  1. package com.collection.treeset;
  2. import com.collection.set.Person;
  3. import java.util.Iterator;
  4. import java.util.TreeSet;
  5. /**
  6. * 使用TreeSet保存数据
  7. * 要求:
  8. *  元素必须要实现Comparable接口,compareTo();方法返回值为0,认为是重复元素
  9. */
  10. public class Demo02 {
  11.     public static void main(String[] args) {
  12.         // 创建集合
  13.         TreeSet<Person> persons = new TreeSet<>();
  14.         // 1. 添加元素
  15.         Person p1 = new Person("java",18);
  16.         Person p2 = new Person("php",19);
  17.         Person p3 = new Person("c++",20);
  18.         Person p4 = new Person("xyz",21);
  19.         Person p5 = new Person("java",1970);
  20.         persons.add(p1);
  21.         persons.add(p2);
  22.         persons.add(p3);
  23.         persons.add(p4);
  24.         persons.add(p5);
  25.         System.out.println("元素个数:" + persons.size());  // 元素个数:5
  26.         System.out.println(persons);  // [Person{name='c++', age=20}, Person{name='java', age=18}, Person{name='java', age=1970}, Person{name='php', age=19}, Person{name='xyz', age=21}]
  27.         // 2. 删除
  28. //        persons.remove(p2);
  29. //        persons.remove(new Person("xyz",21));
  30. //        System.out.println("删除元素:"+persons.size());   // 删除元素:3
  31. //        System.out.println(persons.toString());  //  [Person{name='c++', age=20}, Person{name='java', age=18}, Person{name='java', age=1970}]
  32.         // 3. 遍历
  33.         // 3.1 使用增强for
  34.         System.out.println("---------使用增强for--------");
  35.         for (Person p: persons
  36.              ) {
  37.             System.out.println(p);
  38.         }
  39.         /*
  40.         ---------使用增强for--------
  41.         Person{name='c++', age=20}
  42.         Person{name='java', age=18}
  43.         Person{name='java', age=1970}
  44.         Person{name='php', age=19}
  45.         Person{name='xyz', age=21}
  46.          */
  47.         // 3.2 使用迭代器
  48.         System.out.println("---------使用迭代器--------");
  49.         Iterator<Person> it = persons.iterator();
  50.         while (it.hasNext()){
  51.             System.out.println(it.next());
  52.         }
  53.         /*
  54.         ---------使用迭代器--------
  55.         Person{name='c++', age=20}
  56.         Person{name='java', age=18}
  57.         Person{name='java', age=1970}
  58.         Person{name='php', age=19}
  59.         Person{name='xyz', age=21}
  60.          */
  61.         // 4. 判断
  62.         System.out.println(persons.contains(p1));  // true
  63.         System.out.println(persons.contains(new Person("javase",1970)));  // false
  64.         System.out.println(persons.isEmpty());  // false
  65.     }
  66. }
  67. 引用了Person类,重写 compareTo(); 方法
  68. // 先按姓名比,然后再按年龄比
  69.     @Override
  70.     public int compareTo(Person o) {
  71.         int n1 = this.getName().compareTo(o.getName());
  72.         int n2 = this.age-o.getAge();
  73.         return  n1==0?n2:n1;
  74.     }
复制代码
TreeSet集合的利用
  1. package com.collection.treeset;
  2. import com.collection.set.Person;
  3. import java.util.Comparator;
  4. import java.util.TreeSet;
  5. /**
  6. * TreeSet 集合的使用
  7. * Comparator : 实现比较定制 (他是一个比较器)
  8. * Comparable : 可比较的
  9. */
  10. public class Demo03 {
  11.     // 创建集合
  12.     public static void main(String[] args) {
  13.         TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>() {  // new Comparator<Person>() 匿名内部类
  14.             @Override
  15.             public int compare(Person o1, Person o2) {
  16.                 int n1 = o1.getAge() - o2.getAge();
  17.                 int n2 = o1.getName().compareTo(o2.getName());
  18.                 return n1 == 0 ? n2 : n1 ;
  19.             }
  20.         });
  21.         Person p1 = new Person("java",24);
  22.         Person p2 = new Person("php",26);
  23.         Person p3 = new Person("c++",20);
  24.         Person p4 = new Person("xyz",17);
  25.         Person p5 = new Person("abc",17);
  26.         persons.add(p1);
  27.         persons.add(p2);
  28.         persons.add(p3);
  29.         persons.add(p4);
  30.         persons.add(p5);
  31.         System.out.println(persons);
  32.     }
  33. }
  34. 结果:
  35.         [Person{name='xyz', age=17}, Person{name='c++', age=20}, Person{name='java', age=24}, Person{name='php', age=26}]
  36.         先比较的age,再比较name
  37.         添加p5之后 ,age相同,比较name
  38.         [Person{name='abc', age=17}, Person{name='xyz', age=17}, Person{name='c++', age=20}, Person{name='java', age=24}, Person{name='php', age=26}]
复制代码
案例:
要求:利用TreeSet集合实现字符串按照长度进行排序
​ helloworld zhangsan lisi xian beijing nanjing haerbin
​ Comparator 接口实现定制比较
代码实现:
  1. package com.collection.treeset;
  2. import java.util.Comparator;
  3. import java.util.TreeSet;
  4. /**
  5. * 案例:
  6. * 要求:使用TreeSet集合实现字符串按照长度进行排序
  7. * helloworld   zhangsan    lisi    xian    beijing   nanjing   haerbin
  8. * Comparator 接口实现定制比较
  9. */
  10. public class Demo04 {
  11.     public static void main(String[] args) {
  12.         // 创建集合 并指定比较规则
  13.         TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() {
  14.             @Override
  15.             public int compare(String o1, String o2) {
  16.                 int n1 = o1.length() - o2.length();
  17.                 int n2 = o1.compareTo(o2);
  18.                 return n1 == 0 ? n2 : n1;
  19.             }
  20.         });
  21.         // 添加数据
  22.         treeSet.add("helloworld");
  23.         treeSet.add("zhangsan");
  24.         treeSet.add("lisi");
  25.         treeSet.add("xian");
  26.         treeSet.add("beijing");
  27.         treeSet.add("nanjing");
  28.         treeSet.add("haerbin");
  29.         System.out.println(treeSet.toString());
  30.     }
  31. }
  32. 结果:
  33.         先比较长度,长度相同,则比较name
  34.         [lisi, xian, beijing, haerbin, nanjing, zhangsan, helloworld]
复制代码
Map集合

Map体系集合


Map接口的特点:
1.用于存储恣意键值对(Key–Value)
2.键:无序、无下标、不答应重复(唯一)
3.值:无序、无下标、答应重复
Map 父接口

特点:
存储一对数据(Key–Value),无序、无下标,键不可重复,值可重复
方法:


  • V put (K key , V value) // 将对象存入到集合中,关联键值。key重复则覆盖原值
  • Object get (Object key) // 根据键获取对应的值
  • Set // 返回所有key
  • Collection values ( ) // 返回包含所有值的Collection集合
  • Set <Map.Entry<K,V>> // 键值匹配的Set集合
代码演示:
  1. package com.collection.map;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.Set;
  5. /**
  6. * Map 接口的使用
  7. * 特点:
  8. * 1. 存储 键值对 (一对一对的数据)
  9. * 2. 键 不能重复,值 可以重复
  10. * 3. 无序 没有下标
  11. */
  12. public class Demo01 {
  13.     public static void main(String[] args) {
  14.         // 创建 Map 集合
  15.         Map<String,String> map = new HashMap<>();
  16.         // 1. 添加元素
  17.         map.put("cn" , "中国");
  18.         map.put("uk" , "英国");
  19.         map.put("usa" , "美国");
  20.         map.put("cn" , "zhongguo");  // k 相同,覆盖掉 v
  21.         System.out.println("元素个数:" + map.size());  // 元素个数:3
  22.         System.out.println(map.toString());  // {usa=美国, uk=英国, cn=zhongguo}
  23.         // 2. 删除
  24.         // map.remove("usa","美国");
  25.         // map.remove("usa");
  26.         // System.out.println("删除:"+map.size());  // 删除:2
  27.         // System.out.println(map);  // {uk=英国, cn=zhongguo}
  28.         // 3. 遍历
  29.         // 3.1 使用 keySet();
  30.         System.out.println("-----------keySet()---------");
  31.         Set<String> keySet = map.keySet();
  32.         for (String key:map.keySet()
  33.              ) {
  34.             System.out.println(key+"-----"+map.get(key));
  35.         }
  36.         /*
  37.         -----------keySet()---------
  38.         usa-----美国
  39.         uk-----英国
  40.         cn-----zhongguo
  41.          */
  42.         // 3.2 使用 entrySet();
  43.         System.out.println("-----------entrySet()---------");
  44.         Set<Map.Entry<String, String>> entries = map.entrySet();
  45.         for (Map.Entry<String,String> entry:
  46.              map.entrySet()) {
  47.             System.out.println(entry.getKey()+"-----"+entry.getValue());
  48.         }
  49.         /*
  50.         -----------entrySet()---------
  51.         usa-----美国
  52.         uk-----英国
  53.         cn-----zhongguo
  54.          */
  55.         // 4. 判断
  56.         System.out.println(map.containsKey("cn"));  // true
  57.         System.out.println(map.containsValue("意大利"));  // false
  58.     }
  59. }
复制代码
HashMap集合

在Java中,HashMap 是一个常用的数据结构,它实现了Map接口,答应我们通过键值对的形式存储和快速查找数据。HashMap的底层是基于哈希表(hash table)的实现,它的高效性和灵活性使其在各种编程场景中广受欢迎。
HashMap是Map接口的一个实现类(HashMap实现了Map的接口),它具有Map的特点。HashMap的底层是哈希表结构。
在 JDK 1.2版本中,线程不安全,运行效率快;答应用null 作为 key 或 value
下面是代码展示:
  1. package com.collection.map;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import java.util.Set;
  5. /**
  6. * HashMap集合的使用
  7. * 存储结构:哈希表(数组+链表+红黑树)
  8. * 使用key 可以hashcode和equals作为重复
  9. */
  10. public class Demo02 {
  11.     public static void main(String[] args) {
  12.         // 创建集合
  13.         HashMap<Student, String> students= new HashMap<Student,String>();
  14.         // 刚创建 hashMap之后没有添加元素  table = null   size = 0 目的:节省空间
  15.         // 1. 添加元素
  16.         Student s1 = new Student("小李", 00001);
  17.         Student s2 = new Student("小王", 00002);
  18.         Student s3 = new Student("小赵", 00003);
  19.         Student s4 = new Student("小孙", 00004);
  20.         students.put(s1,"北京");
  21.         students.put(s2,"天津");
  22.         students.put(s3,"南京");
  23.         students.put(s4,"上海");
  24.         // students.put(s4,"杭州");  // 不会新添加,会覆盖
  25.         System.out.println("元素个数:"+students.size());  // 元素个数:4
  26.         System.out.println(students);  // {Student{name='小赵', stId=3}=南京, Student{name='小王', stId=2}=天津, Student{name='小李', stId=1}=北京, Student{name='小孙', stId=4}=杭州}
  27.         // 2. 删除
  28. //        students.remove(s1);
  29. //        students.remove(new Student("小孙", 00004));
  30. //        System.out.println("删除之后:"+students.size());  // 删除之后:3
  31. //        System.out.println(students);  // {Student{name='小赵', stId=3}=南京, Student{name='小王', stId=2}=天津, Student{name='小孙', stId=4}=上海}
  32.         // 3. 遍历
  33.         // 3.1 使用 keySet();
  34.         System.out.println("-----------使用 keySet()---------------");
  35.         Set<Student> keySet = students.keySet();
  36.         for (Student s:
  37.              keySet) {
  38.             System.out.println(s+"----"+students.get(s));
  39.         }
  40.         /*
  41.         -----------使用 keySet()---------------
  42.         Student{name='小赵', stId=3}-----南京
  43.         Student{name='小王', stId=2}-----天津
  44.         Student{name='小李', stId=1}-----北京
  45.         Student{name='小孙', stId=4}-----上海
  46.          */
  47.         // 3.2 使用 entrySet();
  48.         System.out.println("-----------使用entrySet()--------------");
  49.         Set<Map.Entry<Student, String>> entries = students.entrySet();
  50.         for (Map.Entry<Student, String> s :
  51.                 entries) {
  52.             System.out.println(s.getKey()+"-----"+s.getValue());
  53.         }
  54.         /*
  55.         -----------使用entrySet()--------------
  56.         Student{name='小赵', stId=3}-----南京
  57.         Student{name='小王', stId=2}-----天津
  58.         Student{name='小李', stId=1}-----北京
  59.         Student{name='小孙', stId=4}-----上海
  60.          */
  61.         // 4. 判断
  62.         System.out.println(students.containsKey(s1));  // true
  63.         System.out.println(students.containsKey(new Student("小赵", 00003)));  // true
  64.         System.out.println(students.containsValue("新疆"));  // false
  65.         System.out.println(students.isEmpty());  // false
  66.     }
  67. }
复制代码
学生类:
  1. package com.collection.map;
  2. import java.util.Objects;
  3. public class Student implements Comparable<Student>{
  4.     private String name ;
  5.     private int stId;
  6.     public Student() {
  7.     }
  8.     public Student(String name, int stId) {
  9.         this.name = name;
  10.         this.stId = stId;
  11.     }
  12.     public String getName() {
  13.         return name;
  14.     }
  15.     public void setName(String name) {
  16.         this.name = name;
  17.     }
  18.     public int getStId() {
  19.         return stId;
  20.     }
  21.     public void setStId(int stId) {
  22.         this.stId = stId;
  23.     }
  24.     @Override
  25.     public String toString() {
  26.         return "Student{" +
  27.                 "name='" + name + '\'' +
  28.                 ", stId=" + stId +
  29.                 '}';
  30.     }
  31.     @Override
  32.     public boolean equals(Object o) {
  33.         if (this == o) return true;
  34.         if (o == null || getClass() != o.getClass()) return false;
  35.         Student student = (Student) o;
  36.         return stId == student.stId && Objects.equals(name, student.name);
  37.     }
  38.     @Override
  39.     public int hashCode() {
  40.         return Objects.hash(name, stId);
  41.     }
  42.     @Override
  43.     public int compareTo(Student o) {
  44.         int n = this.stId - o.getStId();
  45.         return n;
  46.     }
  47. }
复制代码
源码分析:
  1. 源码分析:
  2.     1. static final int DEFAULT_INTTIAL_CAPACITY = 1 << 4 ;
  3.     hashMap的初始容量大小
  4.     2. static final int MAXIMUM_CAPACITY = 1 << 30 ;
  5.     hashMap的数组最大容量
  6.     3. static final float DEFAULT_LOAD_FACTOR = 0.75f ;
  7.     默认加载因子
  8.     4. static final int TREEIFY_THRESHOLD = 8 ;
  9.     JDK 1.8 当链表长度大于8时,调整成红黑树
  10.     5. static final int UNTREEIFY_THRESHOLD = 6 ;
  11.     JDK 1.8 当链表长度大于6时,调整成链表
  12.     6. static final int MIN_TREEIFY_CAPACITY = 64 ;
  13.     JDK 1.8 当链表长度大于8时,并且集合元素个数大于等于64时,调整成红黑树
  14.     7. transient Node<K,V>[] table ;
  15.     哈希表中的数组
  16.     8. size ;
  17.     元素个数
复制代码
总结:
  1. 1. HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
  2. 2. 当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数
  3. 3. jdk 1.8 当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的是提高执行效率
  4. 4. jdk 1.8 当链表长度小于6时,调整成链表
  5. 5. jdk 1.8 以前是链表头插入,1.8 以后是尾插入
复制代码
Hashtable与Properties

Hashtable :
​ JDK1.0版本,线程安全,运行效率慢,不答应null作为key或是value
Properties:
​ Hashtable 的子类,要求key和value都是String。通常用于配置文件的读取
TreeMap

实现了SortedMap接口(是Map的子接口),可以对key自动排序
代码演示:
  1. package com.collection.map;
  2. import java.util.Map;
  3. import java.util.TreeMap;
  4. /**
  5. * TreeMap 的使用
  6. * 存储结构: 红黑树
  7. */
  8. public class Demo03 {
  9.     public static void main(String[] args) {
  10.         // 新建集合 (也可以使用定制)
  11.         TreeMap<Student, String> treeMap = new TreeMap<>();
  12.         // 1. 添加元素
  13.         Student s1 = new Student("小李", 00001);
  14.         Student s2 = new Student("小王", 00002);
  15.         Student s3 = new Student("小赵", 00003);
  16.         Student s4 = new Student("小孙", 00004);
  17.         treeMap.put(s1,"北京");
  18.         treeMap.put(s2,"上海");
  19.         treeMap.put(s3,"广州");
  20.         treeMap.put(s4,"深圳");
  21.         // treeMap.put(s3,"香港");  // 无法插入数据,但会把value值替换掉
  22.         System.out.println("元素个数:"+treeMap.size());  // 元素个数:4
  23.         System.out.println(treeMap);  // {Student{name='小李', stId=1}=北京, Student{name='小王', stId=2}=上海, Student{name='小赵', stId=3}=香港, Student{name='小孙', stId=4}=深圳}
  24.         // 2. 删除
  25. //        treeMap.remove(s1);
  26. //        treeMap.remove(new Student("小孙", 00004));
  27. //        System.out.println("删除之后:"+treeMap.size());  // 删除之后:2
  28. //        System.out.println(treeMap);  // {Student{name='小王', stId=2}=上海, Student{name='小赵', stId=3}=广州}
  29.         // 3. 遍历
  30.         // 3.1 使用 keySet();
  31.         System.out.println("-------使用 keySet()---------");
  32.         for (Student key:
  33.              treeMap.keySet()) {
  34.             System.out.println(key+"-----"+treeMap.get(key));
  35.         }
  36.         /*
  37.         -------使用 keySet()---------
  38.         Student{name='小李', stId=1}-----北京
  39.         Student{name='小王', stId=2}-----上海
  40.         Student{name='小赵', stId=3}-----广州
  41.         Student{name='小孙', stId=4}-----深圳
  42.          */
  43.         // 3.2 使用 entrySet();
  44.         System.out.println("-------使用 entrySet()---------");
  45.         for (Map.Entry<Student, String> entry :
  46.                 treeMap.entrySet()) {
  47.             System.out.println(entry.getKey()+"----"+entry.getValue());
  48.         }
  49.         /*
  50.         -------使用 entrySet()---------
  51.         Student{name='小李', stId=1}----北京
  52.         Student{name='小王', stId=2}----上海
  53.         Student{name='小赵', stId=3}----广州
  54.         Student{name='小孙', stId=4}----深圳
  55.          */
  56.         // 4. 判断
  57.         System.out.println(treeMap.containsKey(s2));  // true
  58.         System.out.println(treeMap.containsKey(new Student("小王", 00002)));  // true
  59.         System.out.println(treeMap.containsValue("南京"));  // false
  60.         System.out.println(treeMap.isEmpty());  // false
  61.     }
  62. }
复制代码
Collections工具类

概念:集合工具类,界说了除了存取以外的集合常用方法
方法:


  • public static void reverse (List<?> list) // 反转集合中元素的顺序
  • public static void shuffer (List<?> list) // 随机重置集合元素的顺序
  • public static void sort (List<?> list) // 升序顺序(元素范例必须实现Comparable接口)
代码演示:
  1. package com.collection.map;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.Collections;
  5. import java.util.List;
  6. /**
  7. * Collections工具类的使用
  8. */
  9. public class Demo04 {
  10.     public static void main(String[] args) {
  11.         List<Integer> list = new ArrayList<>();
  12.         list.add(58);
  13.         list.add(41);
  14.         list.add(77);
  15.         list.add(26);
  16.         list.add(18);
  17.         // sort 排序
  18.         System.out.println("----------sort---------");
  19.         System.out.println("排序之前:"+list);  // 排序之前:[58, 41, 77, 26, 18]
  20.         Collections.sort(list);
  21.         System.out.println("排序之后:"+list);  // 排序之后:[18, 26, 41, 58, 77]
  22.         // binarySearch 二分查找
  23.         System.out.println("--------binarySearch----------");
  24.         int i = Collections.binarySearch(list,25);  // -2
  25.         int i1 = Collections.binarySearch(list,58);  // 3
  26.         System.out.println(i);
  27.         System.out.println(i1);
  28.         // copy 复制
  29.         System.out.println("------copy------");
  30.         List<Integer> dest = new ArrayList<>();
  31.         for (int j = 0 ; j < list.size() ; j++){
  32.             dest.add(0);
  33.         }
  34.         Collections.copy(dest,list);
  35.         System.out.println(dest);  // [18, 26, 41, 58, 77]
  36.         // reverse 反转
  37.         System.out.println("-------reverse-------------");
  38.         Collections.reverse(list);
  39.         System.out.println("反转之后:"+list);  // 反转之后:[77, 58, 41, 26, 18]
  40.         // shuffle 打乱
  41.         System.out.println("--------shuffle--------");
  42.         Collections.shuffle(list);
  43.         System.out.println("打乱之后:"+list);  // 打乱之后:[41, 77, 58, 26, 18]
  44.         // 补充:
  45.         // list转数组
  46.         System.out.println("--------list转数组-------");
  47.         Integer[] arr = list.toArray(new Integer[2]);
  48.         Integer[] arr1 = list.toArray(new Integer[10]);
  49.         System.out.println(arr.length);  // 5
  50.         System.out.println(Arrays.toString(arr));  // [77, 41, 58, 26, 18]
  51.         System.out.println(Arrays.toString(arr1));  // [18, 41, 58, 26, 77, null, null, null, null, null]
  52.         // 数组转集合
  53.         System.out.println("---------数组转集合----------");
  54.         String[] names = {"张三","李四","王五","赵六"};
  55.         // 集合是一个受限集合,不能添加和删除
  56.         List<String> list2 = Arrays.asList(names);
  57.         // list2.add("小李");  UnsupportedOperationException
  58.         // list2.remove(2);  UnsupportedOperationException
  59.         System.out.println(list2);  // [张三, 李四, 王五, 赵六]
  60.         // 把基本类型数组转成集合时,需要修改为包装类型
  61.         Integer[] nums = {100,200,300,400,500,600};
  62.         List<Integer> list3 = Arrays.asList(nums);
  63.         System.out.println(list3);  // [100, 200, 300, 400, 500, 600]
  64.     }
  65. }
复制代码
集合总结



  • 集合的概念:

    • 对象的容器,和数组类似,界说了对多个对象进行操作的常用方法

  • List集合

    • 有序、有下标、元素可以重复。(Arraylist、LinkedList、Vector)

  • Set集合

    • 无序、无下标、元素不可重复。(HashSet、TreeSet)

  • Map集合

    • 存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap、HashTable、TreeMap)

  • Collections

    • 集合工具类,界说了除了存取以外的集合常用方法。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

一给

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表