Java集合
数组和结合的区别
都是容器,可以存储多个数据
- 数组的长度是不可变的,集合的长度是可变的
- 数组可以存基本数据类型和引用类型;集合只能存引用数据类型,如果要存基本数据类型,需要存对应的包装类
集合类体系结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ldhze1im-1639583817426)(D:/OneDrive/%E7%BD%91%E6%97%B6%E4%BB%A3%E6%95%99%E8%82%B2Java/%E9%9B%86%E5%90%88%E7%AC%94%E8%AE%B0%E7%9A%84%E5%9B%BE/1639411549964.png)]
Collection集合概述和使用
- 是单例集合的顶层接口,它表示一组对象,这些对象也称为Collection的元素
- JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
- 多态的方式
- 具体的实现类ArrayList
Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可用于操作Set集合,也可用于操作List和Queue集合。
方法名 | 说明 |
---|
boolean add(Object o) | 该方法用于向集合里添加一个元素。如果集合对象被添加操作改变了,则返回true | boolean addAll(Collection c) | 该方法把集合c里的所有元素添加到指定集合里。如果集合对象被添加操作改变了,则返回true | void clear() | 清除集合里的所有元素,将集合长度变为0 | boolean contains(Object o) | 返回集合里是否包含指定元素 | boolean containsAll(Collection c) | 返回集合里是否包含集合c里的所有元素 | boolean isEmpty() | 返回集合是否为空。当集合长度为0时返回true,否则返回false | Iterator iterator() | 返回一个Iterator对象,用于遍历集合里的元素 | boolean remove(Object o) | 删除集合中的指定元素o,当集合中包含了一个或多个元素o时,该方法只删除第一个符合条件的元素,该方法将返回true | boolean removeAll(Collection c) | 从集合中删除集合c里包含的所有元素(相当于用调用该方法的集合减集合c),如果删除了一个或一个以上的元素,则该方法返回true | boolean retainAll(Collection c) | 从集合中删除集合c里不包含的元素(相当于把调用该方法的集合变成该集合和集合c的交集),如果该操作改变了调用该方法的集合,则该方法返回true | int size() | 该方法返回集合里元素的个数 | Object[] toArray() | 该方法把集合转换成一个数组,所有的集合元素变成对应的数组元素 |
依次访问集合里每一个元素的两个方式
使用Lambda表达式遍历集合
Java8为Iterator接口新增了一个forEach(Consumer action)默认方法,该方法所需参数的类型是一个函数式接口,而Iterable接口是Collection接口的父接口,因此Collection集合也可直接调用该方法。
public class 测试 {
public static void main(String[] args) {
Collection book = new HashSet<>();
book.add("轻量级JavaEE企业应用实战");
book.add("疯狂Java讲义");
book.add("疯狂Android讲义");
book.forEach(Obj -> System.out.println("迭代集合元素:"+Obj));
}
}
迭代集合元素:轻量级JavaEE企业应用实战
迭代集合元素:疯狂Android讲义
迭代集合元素:疯狂Java讲义
使用Java8增强的Iterator遍历集合元素
Iterator则主要用于遍历(即迭代访问)Collection集合中的元素,Iterator对象也被称为迭代器
- boolean hasNext(): 如果被迭代的集合元素还没有被遍历完,则返回true
- Object next(): 返回集合里的下一个元素
- void remove(): 删除集合里上一次next方法返回的元素
- void forEachRemaining(Consumer action),这是Java8为Iterator新增的默认方法,该方法可以使用Lambda表达式来遍历集合元素
public class 测试 {
public static void main(String[] args) {
Collection books = new HashSet<>();
books.add("轻量级JavaEE企业应用实战");
books.add("疯狂Java讲义");
books.add("疯狂Android讲义");
Iterator iterator = books.iterator();
while (iterator.hasNext()) {
String book = (String) iterator.next();
System.out.println(book);
if (book.equals("疯狂Java讲义")) {
iterator.remove();
}
book = "测试字符串";
}
System.out.println(books);
}
}
轻量级JavaEE企业应用实战
疯狂Android讲义
疯狂Java讲义
[轻量级JavaEE企业应用实战, 疯狂Android讲义]
当使用Iterator迭代访问Collection集合元素时,Collection集合里的元素不能被改变,只有通过Iterator的remove()方法删除上一次next()方法返回的集合元素才可以;否则将会引发java.util.ConcurrentModificationException异常
List集合的概述和特点
- 有序集合,这里的有序指的是存取顺序
- 用户可以精确控制列表中每个元素的插入位置,用户可以通过整数索引访问元素,并搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
- 存取有序
- 可以重复
- 有索引
List集合特有的方法
方法名 | 描述 |
---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 | E remove(int index) | 删除指定索引处的元素,返回被删除的元素 | E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 | E get (int index) | 返回指定索引处的元素 |
List集合的实现类
底层是数据结构实现,查询快,增删慢
底层是链表结构实现,查询慢,增删快
LinkedList集合的特有功能
方法名 | 说明 |
---|
public void addFirst(E e) | 在该列表开头插入指定的元素 | public void addLast(E e) | 将指定的元素追加到此列表的末尾 | public E getFirst() | 返回此列表中的第一个元素 | public E getLast() | 返回此列表中的最后一个元素 | public E removeFirst() | 从此列表中删除并返回第一个元素 | public E removeLast() | 从此列表中删除并返回最后一个元素 |
Set集合
它类似于一个罐子,程序可以依次把多个对象“丢进”Set集合,而Set集合通常不能记住元素的添加顺序。
Set集合不允许包含相同的元素,如果试图把两个相同的元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入
HashSet类
哈希值:
HashSet类的特点:
- 不能保证元素的排列顺序,顺序可能与添加顺序不同,顺序也有可能发生变化。
- HashSet不是同步的,如果多个线程同时访问一个HashSet,假设有两个或者两个以上线程同时修改了HashSet集合时,则必须通过代码来保证其同步。
- 集合元素值可以是null
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i1O MdqA8-1639583817426)(D:/OneDrive/%E7%BD%91%E6%97%B6%E4%BB%A3%E6%95%99%E8%82%B2Java/%E9%9B%86%E5%90%88%E7%AC%94%E8%AE%B0%E7%9A%84%E5%9B%BE/1639415221134.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pakeGzXt-1639583817426)(D:/OneDrive/%E7%BD%91%E6%97%B6%E4%BB%A3%E6%95%99%E8%82%B2Java/%E9%9B%86%E5%90%88%E7%AC%94%E8%AE%B0%E7%9A%84%E5%9B%BE/1639415560910.png)]
如果需要把某个类的对象保存到HashSet集合中,重写这个类的equals()方法和hashCode()方法时,应该尽量保证两个对象通过equals()方法比较返回true时,它们的hashCode()方法返回值也相等。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2LvVfYQ4-1639583817427)(D:/OneDrive/%E7%BD%91%E6%97%B6%E4%BB%A3%E6%95%99%E8%82%B2Java/%E9%9B%86%E5%90%88%E7%AC%94%E8%AE%B0%E7%9A%84%E5%9B%BE/1639415750105.png)]
HashSet中每个能存储元素的“槽位”通常被称为"桶",如果有多个元素的hashCode值相同,但他们通过equals()方法比较返回false,就需要在一个"桶"里放多个元素,这样会导致性能下降。
重写hashCode()方法的基本原则
- 在程序运行过程中,同一个对象多次调用hashCode()方法应该返回相同的值
- 当两个对象通过equals()方法比较返回true时,这两个对象的hashCode()方法应返回相等的值
- 对象中用作equals()方法比较标准的实例变量,都应该用于计算hashCode值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RANzXhQy-1639583817427)(D:/OneDrive/%E7%BD%91%E6%97%B6%E4%BB%A3%E6%95%99%E8%82%B2Java/%E9%9B%86%E5%90%88%E7%AC%94%E8%AE%B0%E7%9A%84%E5%9B%BE/1639416468880.png)]
LinkedHashSet类
LinkedHashSet集合也是根据元素的hashCode值来决定元素的存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。也就是说,当遍历LinkedHashSet集合里的元素时,LinkedHashSet将会按元素的添加顺序来访问集合里的元素。
TreeSet类
TreeSet集合概述和特点
- 不可以存储重复元素
- 没有索引
- 可以将元素按照规则进行排序
- TreeSet(): 根据其元素的自然排序进行排序
- TreeSet(Comparator comparator): 根据指定的比较器进行排序
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yfFMAKre-1639583817428)(D:/OneDrive/%E7%BD%91%E6%97%B6%E4%BB%A3%E6%95%99%E8%82%B2Java/%E9%9B%86%E5%90%88%E7%AC%94%E8%AE%B0%E7%9A%84%E5%9B%BE/1639416762994.png)]
TreeSet并不是根据元素的插入顺序进行排序的,而是根据元素实际值的大小来进行排序的。
与HashSet集合采用hash算法来决定元素的存储位置不同,TreeSet采用红黑树的数据结构来存储集合元素。TreeSet支持两种排序方法:自然排序和定制排序
自然排序
TreeSet会调用集合元素的compareTo(Object obj) 方法来比较元素之间的大小关系,然后将集合元素按升序排序,这种方式就是自然排序。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RU3xvWpb-1639583817428)(C:\Users\ADMINI~1\AppData\Local\Temp\1639582790799.png)]
还有一点需要指出:大部分类在实现compareTo(Object obj) 方法时,都需要将被比较对象obj强制类型转换成相同类型,因为只有相同类的两个实例才会比较大小。当试图把一个对象添加到TreeSet集合时,TreeSet会调用该对象的compareTo(Object obj)与集合中的其他元素进行比较----这就要求集合中的其他元素与该元素是同一类的实例。也就是说,向TreeSet中添加的应该是同一个类的对象,否则也会引发ClassCastException异常。
总结:如果希望TreeSet能正常运作,TreeSet只能添加同一种类型的对象
对于TreeSet集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object obj)方法比较是否返回0—如果通过compareTo(Object obj) 方法比较返回0,TreeSet则会认为它们相等;否则就认为它们不相等。
由此应该注意一个问题:当需要把对象放入TreeSet中,重写该对象对应类的equals()方法时,应保证该方法与compareTo(Object obj)方法有一致的结果,其规则是:如果两个对象通过equals()方法比较返回true时,两个对象通过compareTo(Object obj) 方法比较应返回0。如果两个对象通过compareTo(Object obj)方法比较返回0时,但它们通过equals()方法比较返回false将会很麻烦,因为两个对象通过compareTo(Object obj)方法比较相等,TreeSet不会让第二个元素添加进去,这将会与Set集合的规则产生冲突
定制排序
TreeSet的自然排序是根据集合元素的大小,TreeSet将它们以升序排列。如果需要实现定制排序,例如以降序排列,则可以通过Comparator接口的帮助。该接口包含一个int compare(T o1, T o2) 方法,该方法用于比较o1和o2的大小:如果该方法返回正整数,则表明o1大于o2,如果该方法返回0时,则表示o1等于o2.如果该方法返回负整数,则表明o1小于o2.
还未更新完,之后继续总结
|