Java基础篇集合框架体系--Collection
集合框架Collection接口目录
- 1. Collection接口框架
-
- 1.1 基础性知识总结
- 1.2 Collection接口的常用方法
- 1.3 集合与数组之间的转化
- 2. List接口
-
- 2.1 List接口常用实现类
- 2.2 List接口实现类常用方法
- 2.3 迭代器(iterator)和增强for(for-each)
- 3. Set接口
-
- 3.1 Set接口常用实现类
- 3.2 Set接口添加元素过程
- 3.3 Set接口实现类排序
说明:
集合框架一个分为Collection和Map两大体系,本篇文章是对于Collection的总结
1. Collection接口框架
1.1 基础性知识总结
概述:
集合、数组都是对多个数据进行存储操作的结构,简称Java容器。此时的存储,主要是指内存层面的存储,不涉及持久化的存储,在一定程度上数组和集合是有共同点的,只是在解决实际问题的时候,使用数组操作效率低,不能满足要求,这时候就需要使用更强大的框架支持,所以普遍开发者都会选择使用集合
【了解内容】
|----Collection接口:单列集合,用于存储一个一个的对象
|----List接口:存储有序的、可重复的数据。
|----ArrayList、LinkedList、Vector
|----Set接口:存储无序的、不可重复的数据
|----HashSet、LinkedHashSet、TreeSet
|----Map接口:双列集合,用来存储一对一对(key - value)的数据。
|----HashMap、LinkedHashMap、TreeMap、Hashtable、Properties
图画形式:
1.2 Collection接口的常用方法
方法名 | 说明 |
---|---|
add(Object obj) | 添加一个元素 |
addAll(Collection coll) | 添加一个集合 |
boolean isEmpty() | 判断集合是否为空 |
boolean contains(Object obj) | 判断集合是否有obj这个元素 |
boolean remove(Object obj) | 删除指定元素 |
boolean retainAll(Collection c) | 其两个集合的交集 |
hashCode() | 获取对象的哈希值 |
iterator() | 返回迭代器对象,用于集合遍历 |
int size() | 返回集合的大小 |
void clear() | 清空集合 |
toArray() | 返回一个Object类型的数组 |
集合的创建以及部分方法的使用展示
@Test public void test(){ Collection coll = new ArrayList(); //方法测试 //1.add(Object e),可以添加任意类型的数据 coll.add("aa"); coll.add("bb"); coll.add("cc"); coll.add(123); coll.add(new Date()); //2.size()输出集合大小 System.out.println(coll.size()); System.out.println(coll); //3.addAll(Collection c)添加一个集合 Collection coll1 = new ArrayList<>(); coll1.add("dd"); coll1.add(456); coll.addAll(coll1); System.out.println(coll.size()); System.out.println(coll); //4.clear():清空集合的元素 coll.clear(); //5.isEmpty():判断集合是否为空 System.out.println(coll.isEmpty()); }
1.3 集合与数组之间的转化
数组转化为集合
使用Arrays.asList()构造器,将new出来的数组作为形参放到构造器里面,就可以实现数组转化为集合
使用样例展示:
List<String> list = Arrays.asList(new String[]{"aa", "bb"}); System.out.println(list); //对于整数集合的添加需要使用包装类Integer List<Integer> list1 = Arrays.asList(new Integer[]{123, 456}); System.out.println(list1);
集合转化为数组
调用集合的toString()方法,返回一个Object类型的数组,就可以实现集合与数组之间的转化
使用样例展示:
Object[] array = coll.toArray(); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); }
2. List接口
2.1 List接口常用实现类
概述
① 鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组
② List集合类中元素有序、且可重复,集合中的每个元素都有其对应的顺序索引。
③List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
④ JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。
最重要的特点:
存储有序的、可重复的数据,存储元素的要求:添加自定义类如:Person类时,需要重写equals()
主要实现类为以下三种:
①ArrayList
作为List的主要实现类;线程不安全,效率高;底层使用Object[] elemntData进行存储
②LinkedList
作为频繁的插入、删除操作,使用此类的效率比ArrayList高;底层使用双向链表存储
③Vector
作为List接口的古老实现类(过时);线程安全,效率低;底层使用Object[] elemntData进行存储
上述特点描述的即为三种实现类的不同点,相同点为:三个类都是实现了List接口,存储数据特点相同:存储有序的、可重复的数据
2.2 List接口实现类常用方法
方法名 | 说明 |
---|---|
add(int index, Object obj) | index位置插入ele元素 |
Object remove(int index) | 删除下标时index的元素 |
Object remove(Object obj) | 删除元素内容obj的元素 |
set(int index, Object obj) | 设置指定index位置的元素为ele |
int indexOf(Object obj) | 查找元素下表 |
addAll(int index, Collection eles) | 指定位置上添加集合 |
add(int index,Object obj) | 指定位置上添加元素 |
size() | 返回集合长度 |
Iterator | 迭代器遍历结合 |
提示
因为List是Collection下的接口,所以List的实现类,对于Collection的所有方法都可以调用
对实现类的方法调用代码展示以ArrayList为例
@Testpublic void Test1(){ ArrayList arrayList = new ArrayList(); arrayList.add(123); arrayList.add(456); arrayList.add("AA"); arrayList.add(new String("Jerry")); arrayList.add("BB"); System.out.println(arrayList); //void add(int index, Object ele):在index位置插入ele元素 arrayList.add(1,"CC"); System.out.println(arrayList); //boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来 List<Integer> list = Arrays.asList(1, 2, 3); arrayList.addAll(list); System.out.println(arrayList); //Object get(int index):获取指定index位置的元素 Object o = arrayList.get(1); System.out.println(o); System.out.println(List.indexOf("AA")); System.out.println(List.lastIndexOf("AA")); //Object remove(int index):移除指定index位置的元素,并返回此元素 List.remove(5); System.out.println(List); //Object set(int index, Object ele):设置指定index位置的元素为ele List.set(4,"AA"); System.out.println(List); //List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex java.util.List list = List.subList(1, 4); System.out.println(list); }
2.3 迭代器(iterator)和增强for(for-each)
迭代器
定义:
提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。
说明【了解内容】
①Collection接口继承了java.lang.Iterable接口,Iterator接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。
② Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力。
③集合对象每次调用iterator()方法都得到一个全新的迭代器对象。
迭代器对于集合来说主要就是配合hashnext()和next()完成对集合的遍历
使用样例:
@Testpublic void test1(){ Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add("abc"); coll.add(new Person("Tom",20)); coll.add(new String("Jerry")); //调用iterator()生成一个集合的迭代器对象 Iterator iterator = coll.iterator(); while(iterator.hasNext()){ //next():实现了两个步骤:①指针下移②将下移以后集合位置上的元素返回 System.out.println(iterator.next()); }}
增强for
说明
增强for在使用的格式上与普通for有很大的差别,在使用的情景相同
格式
for(集合元素的类型 局部变量:集合对象){
}
使用样例展示
@Testpublic void test3(){ Collection coll = new ArrayList(); coll.add(123); coll.add(456); coll.add("abc"); coll.add(new Person("Tom",20)); coll.add(new String("Jerry")); for (Object obj: coll){ System.out.println(obj); } }
3. Set接口
3.1 Set接口常用实现类
概述
①Set接口是Collection的子接口,set接口没有提供额外的方法
②Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个
Set 集合中,则添加操作失败。
③Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法
最重要的特点:
存储无序的、不可重复的数据,Set接口中没有额外定义新的方法,使用的都是Collection中声明的方法
主要实现类为以下三种:
①HashSet:作为Set接口的主要实现类;线程不安全,可以存储null值
② LinkedHashSet:作为HashSet的子类;遍历器内部数据时,可以按照添加的顺序遍历,底层使用链表
③TreeSet:可以按照添加对象的指定属性,进行排序。TreeSet 中添加的应该是同一个类的对象
特性描述:
1.无序性:不等于随机性。存储的数据在底层数组中并非按照数据索引的顺序添加,而是按照数据的哈希值添加的
2.不可重复性:保证添加的元素按照equals()判断时,不能返回true.即:相同的元素只能添加一个。
3.2 Set接口添加元素过程
【特别重要】
我们想HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,此哈希值接着通过计算某种计算方法计算出在HashSet底层数组中的存放位置,判断数组此位置上是否已有元素:
①如果此位置上没有其他元素,则元素添加成功
②如果此位置上有其他元素b,则比较元素a和b的hash值:
如果hash值不同则添加成功
如果hash值相同同则调用equals()进行判断,返回true(代表元素数据一样) 添加失败,否则添加成功
说明:
对于在查询时,此位置已有元素,并且也添加成功的情况下,以链表的形式进行存储
HashSet实现类
是根据哈希值,进行元素的存储,存储是无序的
实现类展示
@Test public void test1(){ Set set = new HashSet(); set.add(123); set.add("BB");//使用哈希值和equals()进行判断 set.add(new User("Jerry",20)); set.add(new User("Jerry",20)); //遍历集合 Iterator iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } }
LinkedHashSet的使用
LinkedHashSet作为HashSet的子类,再添加数据的同时,每个数据还维护了两个引用,记录此数据的前一个和后一个数据。好处是:对于频繁的遍历操作,LinkedHashSet效率高于HashSet
实现展示
@Test public void test2(){ LinkedHashSet list = new LinkedHashSet<>(); list.add(123); list.add("aa"); list.add(456); //执行遍历操作 Iterator iterator = list.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next());//执行结果123 aa 456 } }
3.3 Set接口实现类排序
①对于int类型,String类型,可以按照大小进行排序的,可以不重写排序方法
使用样例展示
int型
public void test2(){TreeSet set = new TreeSet<>(); //举例一 set.add(123); set.add(456); set.add(-789);Iterator iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); }}
String型
public void test2(){TreeSet set = new TreeSet<>(); //举例一 set.add("A"); set.add("C"); set.add("B");Iterator iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } }
②存储自定义类的对象时就需要在自定义类里对实现排序的方法进行重写
实现案例:
创建一个TreeSet实现类对象,添加自定义User对象,实现对添加元素进行排序并且遍历
排序要求:
按照姓名从小到达排序,如果姓名一致,按照年龄从小到大排序
重写方法展示
这里用到了,字符串的比较方法compareTo,int型的比较Integer.compare(),以及instanceof关键字
@Override public int compareTo(Object o) { if (o instanceof User){ User user = (User) o; //return this.name.compareTo(user.name); int compare = this.name.compareTo(user.name); if (compare != 0){ return compare; }else { return Integer.compare(this.age,user.age); } }else { throw new RuntimeException("输入的类型不匹配"); } }
测试方法
@Override public int compareTo(Object o) {//将自定义对象加入到TreeSet集合中时,需要时自定义类实现Compare接口 set.add(new User("Tom",22)); set.add(new User("Jack",20)); set.add(new User("Merry",18)); set.add(new User("Jerry",21)); set.add(new User("Smith",19)); set.add(new User("Jerry",22)); Iterator iterator = set.iterator(); while (iterator.hasNext()){ System.out.println(iterator.next()); } }