为了账号安全,请及时绑定邮箱和手机立即绑定

集合(4接口,9类),Iterator,增强for,可变参数,集合工具类

标签:
Java

集合继承体系:
图片描述
回忆数组的内容,引入集合的概念

数组的局限:长度是固定的,一旦确定了,就不能改变
类型也是固定的,一旦确定了,类型,就不能改变
Collection 集合:

特点:
1:Collection 是集合的根接口
2:一些 collection 允许有重复的元素,而另一些则不允许。
一些 collection 是有序的,而另一些则是无序的
3:Collection接口,提供更具体的子接口(如 Set 和 List)来实现具体的类操作

将数组存储学生的例子,改造成集合的例子

常用方法:
boolean add(Object e):向集合中添加一个Object类型的对象,并返回一个boolean类型
boolean remove(Object o):从此 collection 中移除指定元素的单个实例,如果存在的话
void clear():删除所有的集合元素
boolean contains(Object o):判断是否包含某个元素
boolean isEmpty():判断集合是否为空
int size():返回集合中的元素个数
Object[] toArray():将集合元素,转换为Object类型的数组

// 第一步:创建一个集合对象
// 父类引用指向子类对象
Collection collection = new ArrayList();

// 第二步:创建集合中要存储的元素
Student stu1 = new Student("尚文旭", 22, "中工");
Student stu2 = new Student("小可爱", 19, "中工");
Student stu3 = new Student("小泡泡", 20, "中工");
Student stu4 = new Student("123", 21, "中工");
Student stu5 = new Student("321", 18, "中工");

// 第三步,向集合中添加元素
// boolean add(Object e)
collection.add(stu1);
collection.add(stu2);
collection.add(stu3);
collection.add(stu4);
collection.add(stu5);
collection.add("10");// "10"相当于String类型的一个实例(一个对象)
collection.add(10);// 10 -> Integer Integer类是Object的子类
collection.add('a');

// 第四步:遍历集合
// Object[] toArray():返回包含此 collection 中所有元素的数组。

// for循环遍历数组
Object[] array = collection.toArray();
for (int i = 0; i < array.length; i++) {
    System.out.println(array[i]);
}

集合的常见方法:
boolean addAll(Collection c):向集合中添加 子集合
boolean removeAll(Collection c):从集合中删除子集合
boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的所有元素,则返回 true
boolean retainAll(Collection c):仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)
Iterator:
接口:迭代器,是取代 Enumeration;

方法:
boolean hasNext() :如果仍有元素可以迭代,则返回 true。
Object next() :返回迭代的下一个元素。
void remove() : 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。
NoSuchElementException,当使用next()方法从集合中返回元素时,
如果已经到集合的结尾了,那么就会抛出该异常
我们怎么来避免这个异常呢? 我们可以使用 hasNext()方法,
在调用next()之前,先判断,真,才再调用next();
java.lang.IllegalStateException:两次调用remove()方法,会抛出异常
Iterator 相当于一个指向集合首元素的指针,调用next()一次,就移动一次指针。
并且是单向的,只能往下,不能回退
List接口的常用方法:

特点:
有序的 collection(也称为序列)。
而且可以重复的
此接口的用户可以对列表中每个元素的插入位置进行精确地控制。
用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

常用方法:
void add(int index,Object element):指定索引位置,添加集合元素、
Object remove(int index):按照指定索引位置,删除集合元素;并且返回删除的集合元素
Object get(int index):按照指定索引位置,获取集合元素。
Object set(int index,Object element):按照指定索引位置,更新集合元素,并且返回更新前的集合元素(老值)
ListIterator listIterator(): 返回list即可的专属迭代器,并返回ListIterator,是Iterator的子接口。

关于ListIterator接口的常用方法:

boolean hasPrevious(): 判断回退(上一个)元素是否存在。
void previous(): 返回 上一个集合元素的内容。

ConcurrentModificationException :这个异常什么情况下发生

在一个迭代器 ,对一个集合进行迭代期间,如有有其他线程对该集合的元素进行删除或者增加操作
也就是对集合的size发生了变化的操作时,会抛出此异常。
举例演示:
如果一个集合中有重复的元素时,我们如何对集合中重复元素进行删除?

怎么避免这个异常的产生?
解决办法:
1:用迭代器迭代期间,如果要对集合进行增加或者删除操作,还应该使用迭代器进行。
2: 别用迭代器,用集合本身的方法。
ArrayList类的特点以及常用方法

特点:
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
允许Null值
举例:
实现向ArrayList中添加自定义的对象以及遍历

打印一个对象,就是在打印一个对象的toString()
如果该对象的类型中没用重写toString()方法,就调用的是
Object 类中的toString()的默认实现,全类名的字符串表示+@+hashcode
增强for的演示

格式:
for(数据类型 变量 : 数组或者Collection集合 对象) {
变量名就是 要遍历的元素
}
LinkedList 类的特点
底层数据结构是链表,查询慢,增删快
线程不安全,效率高
允许Null值

举例:

LinkedList类特有功能
public void addFirst(Object e)及addLast(Object e)
public Object getFirst()及getLast()
public Object removeFirst()及public Object removeLast()
Vector的特点:
底层数据结构是数组,查询快,增删慢
线程安全,效率低
允许Null值
举例:
实现向vector中添加自定义的对象以及遍历

Vector类特有功能
public void addElement(Object obj):和add(Object obj)一样,是个old方法
public Object elementAt(int index):和get(index)一样,是个old方法
public Enumeration elements():和Iterator()方法一样,返回的是一个old fashion的迭代器
Set接口的特点以及常用方法
特点:
1:Set接口 继承了Collection接口
2:Set 集合 是一个不包含重复元素的 Collection
3:能不能有null值,可以,不过只能存一个null值
4:Set是无序(存的顺序与取的顺序不一样,为什么呢?是因为 HashSet内部依赖的HashMap这个数据结构)

方法:跟Collection中的方法一样,没有什么特殊的,不再重新讲
HashSet的特点:
HashSet接口的特点以及常用方法
特点:
1:HashSet类 继承了Set接口
2:HashSet 集合 一个不包含重复元素的 Set
3:能不能有null值,可以,不过只能存一个null值
4:HashSet是无序(存的顺序与取的顺序不一样,为什么呢?是因为 HashSet内部依赖的HashMap这个数据结构)

举例:
向HashSet集合中存储字符串类型

研究一下,为什么 HashSet是不可重复的?
   底层数据结构是哈希表(元素是链表的数组)
   哈希表依赖于哈希值存储

   在HashSet的add(Object o)中 的具体实现决定了,集合不能重复这个特性

      add 方法中,存元素之前,先拿对象的hash值,然后将hash,跟 集合中已经存在的元素的hash值继续比较
      如果hash就已经存在,就认为该对象已经存在,就不再存储该对象,然后进一步,比较该对象的和已经存在的对象的equals()方法,看是否相等
            如果相等,才认为该对象真的已经存在,就不再存储该对象
            如果不相等,认为,虽然 hash值已经存在,但是呢equals 方法不为真,所以存储该对象
      如果hash值不存在,直接添加

   简单来说:
      add() 依赖于
          元素的 hashcode()和equals()方法

          先比较hashcode(),再比较equals()

   举例说明:
   HashSet<String> hs1 = new HashSet<String>();
   has1.add("尚文旭");// "尚文旭" hashcode = 1;
   has1.add("小可爱");// "小可爱" hashcode = 2;
   has1.add("尚文旭");// "尚文旭" hashcode = 1; 我们进一步拿"尚文旭"的equals()方法 跟其他对象比较

HashSet存自定义对象示意图
图片描述
HashSet存字符串示意图
图片描述
LinkedHashSet 集合的特点及特有方法
元素有序唯一
由链表保证元素有序(存取的顺序)
由哈希表保证元素唯一
TreeSet 集合的特点以及特有介绍

特点:
1:TreeSet 实现了Set接口,元素不重复,内部基于 TreeMap 的 NavigableSet 实现
2:使用元素的自然顺序(举例:2一定比1大)对元素进行排序(这里 是对元素进行比较大小的排序)。这个调用了无参构造
TreeSet ts = new TreeSet();
3:根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。调用了 一个参数的构造方法
Comparator cp = new Comparator(){方法重写}
TreeSet ts = new TreeSet(cp);
4:实现不是同步的,线程不安全的
5:不能存储null值

构造方法:
1:无参构造 TreeSet() :构造一个新的空 set,该 set 根据其元素的自然顺序进行排序。
2:有参构造 TreeSet(Comparator<? super E> comparator):构造一个新的空 TreeSet,它根据指定比较器进行排序。
TreeSet 存储Integer类型示意图
图片描述
TreeSet存储自定义对象示意图
图片描述
整数可以比大小
Integer怎么比大小?intValue() 返回具体的整数值
Integer这个类型 实现了Comparable接口,重写compareTo(T o)方法

换言之
如果想让自定义的类型,具备自然排序,就必须要实现Comparable接口,重写compareTo(T o)方法
Map的特点以及常用方法

特点:
1:将键映射到值的对象

举例:

存储键值对

常用方法:
V put(K key,V value):添加键值对,并返回null或者key对应之前的value值
V remove(Object key):删除键值对,并返回null或者key关联的value值
void clear():清空Map集合
boolean containsKey(Object key):判断map中是否包含指定的键
boolean containsValue(Object value):判断map中是否包含指定的值
boolean isEmpty():判断Map集合是否为空
int size():返回map集合中键值对的个数
V get(Object key):按照指定的键,返回关联的值,如果找不到,返回null
Set<K> keySet():返回map集合中,所有的键组成的 set集合
Collection<V> values():返回map集合中,所有的值组成的Collection集合
Set<Map.Entry<K,V>> entrySet():返回一个set集合。该集合中存放的是 Map.Entry<k,v>类型的元素,也就是一个键值对的对象
遍历集合. 如何遍历Map集合?
A:通过 keySet()方法获取所有的键的集合对象,遍历Set集合,然后再通过 V get(Object key)方法,查找对应的值
B: Set<Map.Entry<K,V>> entrySet() 这是一个Set集合,可以对Set集合遍历
这个Set中存储的的元素(entry:条目 内部类 映射项(键-值对))
然后通过 Map.Entry<K,V> 再进一步的调用
K getKey() 返回与此项对应的键。
V getValue() 返回与此项对应的值。
获取各自的 键和值
map的两种遍历示意图
图片描述
HashMap类型 的特点:
键唯一:使用hash表来保证的
LinkedHashMap
哈希表和链接列表实现,具有可预知的迭代顺序。
由hash保证 键的唯一性
由linkedlist保证 有序性(存取顺序一致)

LinkedHashMap 是HashMap 类的子类,
TreeMap集合的特点:
Tree:红黑数,平衡二叉树, 特点:按自然排序,并且不能重复。不能又null值
TreeMap 中键具有排序和唯一性
可变参数
我们在定义方法的时候,我们也无法确定具体有多少个参数的时候,我们可以用可变参数

修饰符 返回值类型 方法名(数据类型… 变量名){}
注意:
这里的变量其实是一个数组
如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个

集合工具类 Collections 的常用方法

public static <T> void sort(List<T> list):对集合进行排序
public static <T> int binarySearch(List<?> list,T key):二分查找
public static <T> T max(Collection<?> coll):求最大值
public static void reverse(List<?> list):反转集合中的元素
public static void shuffle(List<?> list):洗牌,随机的位置置换

点击查看更多内容
2人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
软件工程师
手记
粉丝
51
获赞与收藏
617

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消