一、Collection集合类体系结构
1.Collection集合概述和使用
Collection集合概述
-
是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
-
JDK 不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
-
创建Collection集合的对象多态的方式具体的实现类ArrayList
2.Collection集合常用方法
3.分类
(1)list系列集合
添加的元素有序、可重复、有索引
包括ArrayList、LinkedList:有序、可重复、有索引
<1>ArrayList
底层结构是数组,查询快,增删慢
<2>LinkedList
底层数据结构是链表,查询慢,增删快
(2)set系列集合
set集合特点:
-
可以去除重复,元素不能重复
-
存储顺序不一致
-
没有带索引的方法,所以不能使用普通fori遍历循环,也不能通过索引来回去,删除Set集合里面的元素
(添加的元素是无序、不重复、无索引)
<1>HashSet
无序、不重复、无索引
HashSet集合概述和特点:
-
底层数据结构是哈希表
-
对集合的迭代顺序不做任何保证(不保证存储和取出的元素顺序一致)
-
没有带索引的方法,所以不能使用普通for循环遍历
-
由于是Set集合,所以元素唯一
对象的哈希值特点:
-
同一个对象多次调用hashCode()方法返回的哈希值是相同的
-
默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
<2>TreeSet
-
按照大小默认升序排序、不重复、无索引
-
树结构
(二叉树、二叉查找树、平衡二叉树、红黑树)
集合特点:
-
不包含重复元素的集合
-
没有带索引的方法
-
可以将元素按照规则进行排序(制定规则)
比较方式(重要+练习)
自然排序Comparable的使用 使用空参构造创建TreeSet集合 自定义的Student类实现Comparable接口 重写里面的compareTo方法 public int compareTo(Student o){ int r=this.age-o.age; r=(r==0?this.name.compareTo(o.getName():r)); return r; } //首先,通过比较两个学生对象的年龄(this.age - o.age)得到一个整数结果r。如果r等于0,表示两个学生对象的年龄相同,此时再通过比较姓名(this.name.compareTo(o.getName()))得到一个字符串比较结果r。最后,使用r作为比较结果返回。
比较器排序Comparator的使用 TreeSet的带参构造方法使用的是比较器排序对元素进行排序的 比较器排序,就是让集合构造方法接收Comparator的实现类对象,重写compare(T o1,T o2)方法 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
自然排序:自定义类实现Comparable接口,重写compareTo方法,根据返回值进行排序。 比较器排序:创建TreeSet对象的时候传递Comparator的实现类对象,重写compare方法,根据返回值进行排序。 在使用的时候,默认使用自然排序,当自然排序不满足现在的需求时,使用比较器排序 两种方式中,关于返回值的规则: 如果返回值为负数,表示当前存入的元素是较小值,存左边 如果返回值为0,表示当前存入的元素跟集合中元素重复了,不存 如果返回值为正数,表示当前存入的元素是较大值,存右边
4.补充内容
哈希表
(1)哈希值:
<1>哈希值是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
<2>Object类中有一个方法可以获取对象的哈希值
public int hashCode():返回对象的哈希码值
<3>对象的哈希值特点:
-
同一个对象多次调用hashCode()方法返回的哈希值是相同的
-
默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
(2)哈希表
JDK8之前,底层采用数组+链表实现,可以说是一个元素为链表的数组
JDK8以后,在长度比较长的时候,底层实现了优化,采用的是数组+二叉树
(当数组存满到16*0.75=12是,自动扩容原先的两倍即24)
-
底层结构:哈希表。(数组、链表、红黑树的结合体)。
-
当链表长度超过8的时候,自动转换为红黑树。
二、三种通用的遍历方式
1.迭代器Iterator
Iterator<E> iterator() :返回集合中迭代器对象,该迭代器对象默认指向当前集合的0索引
-
hasNext询问当前位置是否有元素存在,存在返回true,不存在返回false——>值放在判断语句中
-
next()获取当前位置的元素,并同时将迭代器对象指向下一个位置,注意防止取出越界
ArrayLiat<Integer> list=new ArrayLiat(); int[] ints ={1,2,4,6,23,8,12}; for(int i=0;i<ints.length;i++){ list.add(ints[i]); } Iterator<Integer> iteractor=list.iteractor(); //if(iteractor.hashNext()){ // Integer next= iterator.next(); // System.out.println(next); //} while(iterator.hasNext())}{ Integer next=iterator.next(); System.out.println(next); }
删除:移除元素的操作必须使用迭代器的 remove()
方法,不能使用集合自身的 remove()
方法。这是因为直接使用集合的 remove()
方法,可能会在删除元素后改变集合的大小,从而导致迭代器 next()
方法返回的元素与预期不一致,进而抛出异常。
2.增强for循环
可以遍历集合也可以遍历数组
格式 for(元素数据类型 变量名:数组或者Collection集合){ //在此处使用变量即可,该变量就是元素 } list.for
底层是迭代器,将list迭代的对象传到Integer integer
for(Integer integer : list){ System.out.println(integer); }
3.lambda表达式
4.五种遍历方式对比
-
迭代器遍历:在遍历的过程中要删除元素,请使用迭代器
-
列表迭代器:在遍历的过程中需要添加元素,请使用列表迭代器
-
增强for遍历、Lambda表达式:仅仅想遍历
-
普通for:如果遍历的时候想操作索引,可以使用普通for
三、Map集合
1.Map集合概述
Interface Map<K,V> K:键的数据类型;V:值的数据类型
-
键不能重复,值可以重复
-
键和值是一一对应的
-
键加值成为键值对或键值对对象,java中叫做Entry对象
注意:在 Java 中,Map
是一个接口,不能直接实例化。这是因为 Map
是一个抽象的数据结构,它没有具体的实现。要实例化 Map
对象,我们需要使用它的具体实现类。常见的实现类有 HashMap
、TreeMap
、LinkedHashMap
等。
(1)创建Map集合的对象:
-
多态
-
具体的实现HashMap
(2)Map集合的基本功能
(3)遍历Map集合
keyset()
Map<String, Integer> map = new HashMap<>(); map.put("A", 1); map.put("B", 2); for (String key : map.keySet()) { Integer value = map.get(key); System.out.println("Key: " + key + ", Value: " + value); }
Map.entrySet()
Map<String, Integer> map = new HashMap<>(); map.put("A", 1); map.put("B", 2); for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println("Key: " + key + ", Value: " + value); }
Map.forEach()
Map<String, Integer> map = new HashMap<>(); map.put("A", 1); map.put("B", 2); map.put("C", 3); map.forEach((key, value) -> System.out.println("Key: " + key + ", Value: " + value));
2.分类
(1)HashMap
-
HashMap是Map里面的一个实现类,直接使用Map里面的方法就可以
-
HashMap跟HashSet一样底层是哈希表结构的
-
依赖hashCode方法和equals方法保证键的唯一
-
如果键要存储的是自定义对象,需要重写hashCode和equals方法
(2)TreeMap
-
TreeMap是Map里面的一个实现类,直接使用Map里面的方法就可以
-
TreeMap跟TreeSet一样底层是红黑树结构的
-
依赖自然排序或者比较器排序,对键进行排序
-
如果键存储的是自定义对象,需要实现Comparable接口或者在创建TreeMap对象时候给出比较器排序规则