Java集合

一、集合概述

1、集合的定义

集合:集合是Java中提供的一种容器,可以用来存储多个数据。

2、集合和数组的比较

相同点:都是容器,可以用来存储多个数据。

不同点

(1)数组的长度是固定的;集合的长度是可变的。

(2)数组中存储的是同一类型的元素,可以存储基本数据类型值。集合中存储的都是对象,而且对象的类型可以不一致。在开发中一般当对象多的时候,使用集合进行存储。

3、集合的分类

集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map

二、Iterator迭代器

1、Iterator接口

​ 在程序开发中,经常需要遍历集合中的所有元素。针对这种需求,JDK专门提供了一个接口java.util.IteratorIterator接口也是Java集合中的一员,但它与CollectionMap接口有所不同,Collection接口与Map接口主要用于存储元素,而Iterator主要用于迭代访问(即遍历)Collection中的元素,因此Iterator对象也被称为迭代器。

2、使用迭代器遍历Collection集合

​ 首先要获取集合对应的迭代器,用来遍历集合中的元素。接着在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续再判断,如果还有就再取出来。一直把集合中的所有元素全部取出为止。

举例:

Collection<String> c = ...;
Iterator<String> it = c.iterator();
while(it.hasNext()){
	String element = it.next();
	System.out.println(element);
}

3、使用增强for循环遍历数组和Collection集合

​ 增强for循环(也称for each循环)是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合。它的内部原理其实也是一个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。

举例:

for(String element : c){
	System.out.println(element);
}

三、单列集合Collection接口

1、Collection接口概述

Collection接口是单列集合的根接口。在Collection接口定义着单列集合框架中最最共性的内容。它有两个重要的子接口,分别是java.util.Listjava.util.Set。其中,List的特点是元素有序、元素可重复。Set的特点是元素无序,而且不可重复。List接口的主要实现类有java.util.ArrayListjava.util.LinkedListSet接口的主要实现类有java.util.HashSetjava.util.TreeSet

2、Collection接口常用方法

​ 在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合。方法如下:

  • public boolean add(E e): 把给定的对象添加到当前集合中 。
  • public void clear() :清空集合中所有的元素。
  • public boolean remove(E e): 把给定的对象在当前集合中删除。
  • public boolean contains(E e): 判断当前集合中是否包含给定的对象。
  • public boolean isEmpty(): 判断当前集合是否为空。
  • public int size(): 返回集合中元素的个数。
  • public Object[] toArray(): 把集合中的元素,存储到数组中。

3、List接口

(1)List接口的特点

​ 1)它是一个元素存取有序的集合。例如,存元素的顺序是11、22、33。那么集合中,元素的存储就是按照 11、 22、33的顺序完成的。

​ 2)它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)。

​ 3)集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

(2)List接口的常用方法

​ List接口作为Collection接口的子接口,不但继承了Collection接口中的全部方法,而且还增加了一些根据元素索引来操作集合的特有方法,如下:

  • public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。

  • public E get(int index) :返回集合中指定位置的元素。

  • public E remove(int index) : 移除列表中指定位置的元素, 返回的是被移除的元素。

  • public E set(int index, E element) :用指定元素替换集合中指定位置的元素,返回的是更新前的元素。

(3)List接口的实现类
1)ArrayList集合

​ ArrayList集合实现的数据结构是数组。

2)LinkedList集合

​ LinkedList集合实现的数据结构是双向链表。(在Java中,所有的链表实际上都是双向链表)

​ 在实际开发中对一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方 法,如下:

  • public void addFirst(E e) :将指定元素插入此列表的开头。

  • public void addLast(E e) :将指定元素添加到此列表的结尾。

  • public E getFirst() :返回此列表的第一个元素。

  • public E getLast() :返回此列表的最后一个元素。

  • public E removeFirst() :移除并返回此列表的第一个元素。

  • public E removeLast() :移除并返回此列表的最后一个元素。

  • public E pop() :从此列表所表示的堆栈处弹出一个元素。

  • public void push(E e) :将元素推入此列表所表示的堆栈。

  • public boolean isEmpty() :如果列表不包含元素,则返回true。

【注】在开发时,LinkedList集合也常作为堆栈,队列的结构来使用。

4、Set接口

(1)Set接口的特点

java.util.Set 接口和 java.util.List 接口一样,同样继承自 Collection 接口,它与 Collection 接口中的方法基本一致,并没有对 Collection 接口进行功能上的扩充,只是比 Collection 接口更加严格了。与 List 接口不同的是,Set 接口中元素无序,并且都会以某种规则保证存入的元素不出现重复。

(2)Set接口的实现类
1)HashSet集合

​ HashSet 是根据对象的哈希值 来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元 素唯一性的方式依赖于: hashCode 与 equals 方法。

​ 【注】如果我们往集合中存放的是自定义的对象,那么要保证其唯一,就必须重写hashCode和equals方法建立 属于当前对象的比较方式。(在IDEA中可以使用快捷方式直接生成代码)

底层原理:

java.util.HashSet 底层的实现其实是一个 java.util.HashMap 的支持。HashSet集合实现的数据结构是 哈希表。在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的元素都存储在 一个链表里。 但是当位于一个链表中的元素较多时,即hash值相等的元素较多时,通过key值依次查找的效率 降低。而在JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红 黑树,这样大大减少了查找的时间。

2)LinkedHashSet集合

​ 我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,就需要使用在 HashSet下面有的一个子类 java.util.LinkedHashSet ,它是链表和哈希表组合的一个数据存储结构。

四、集合工具类Collections

1. 常用方法
  • public static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素。

  • public static void shuffle(List<?> list) :打乱顺序 :打乱集合顺序。

  • public static <T> void sort(List<T> list) :将集合中元素按照默认规则排序。

  • public static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序。

2. 使用Comparator比较器实现自定义排序

举例:

public class CollectionsDemo3 { 
	public static void main(String[] args) { 
		ArrayList<String> list = new ArrayList<String>(); 
		list.add("cba"); 
		list.add("aba"); 
		list.add("sba"); 
		list.add("nba"); 
		//排序方法 按照第一个单词的降序
		Collections.sort(list, new Comparator<String>() {
			//@Override 
			public int compare(String o1, String o2) { 
				return o2.charAt(0) ‐ o1.charAt(0); 
			} 
		}); 
		System.out.println(list); 
	} 
} 

结果如下

[sba, nba, cba, aba]

五、双列集合Map接口

1. Map接口概述

​ 现实生活中,我们常会看到这样的一种集合:IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等, 这种一一对应的关系,就叫做映射。Java提供了专门的集合类用来存放这种对象关系的对象,即 java.util.Map 接口。

2. Map接口和Collection接口的比较
  • Collection 中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。

  • Map 中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的 值。

  • Collection 中的集合称为单列集合, Map 中的集合称为双列集合。

  • 需要注意的是, Map 中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

3. Map接口的常用方法
  • public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。

  • public V remove(Object key) : 把指定的键所对应的键值对元素在Map集合中删除,返回被删除元素的值。

  • public V get(Object key) :根据指定的键,在Map集合中获取对应的值。

  • public Set<K> keySet() : 获取Map集合中所有的键,存储到Set集合中。

  • public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。

4. Map集合的遍历

​ (1)键找值方式

​ 步骤:

​ 1. 获取Map中所有的键,由于键是唯一的,所以返回一个Set集合存储所有的键。方法提示: keyset() 。

​ 2. 遍历键的Set集合,得到每一个键。

​ 3. 根据键,获取键所对应的值。方法提示: get(K key) 。

​ 举例:

public class MapDemo01 { 
	public static void main(String[] args) { 
		//创建Map集合对象 
        HashMap<String, String> map = new HashMap<String,String>(); 
        //添加元素到集合 
        map.put("胡歌", "霍建华"); 
        map.put("郭德纲", "于谦"); 
        map.put("薛之谦", "大张伟"); 
        //获取所有的键 获取键集
        Set<String> keys = map.keySet(); 
        // 遍历键集 得到每一个键 
        for (String key : keys) { 
        	//key 就是键 
        	//获取对应值 
            String value = map.get(key); 
            System.out.println(key+"的CP是:"+value); 
        } 
    } 
}

​ (2)利用Entry键值对对象

​ 步骤:

​ 1. 获取Map集合中,所有的键值对(Entry)对象,以Set集合形式返回。方法提示: entrySet() 。

​ 2. 遍历包含键值对(Entry)对象的Set集合,得到每一个键值对(Entry)对象。

​ 3. 通过键值对(Entry)对象,获取Entry对象中的键与值。 方法提示: getkey() 、getValue() 。

​ 举例:

public class MapDemo02 { 
	public static void main(String[] args) { 
		// 创建Map集合对象 
		HashMap<String, String> map = new HashMap<String,String>(); 
		// 添加元素到集合 
		map.put("胡歌", "霍建华"); 
		map.put("郭德纲", "于谦"); 
		map.put("薛之谦", "大张伟"); 
		// 获取所有的entry对象 entrySet 
		Set<Entry<String,String>> entrySet = map.entrySet(); 
		// 遍历得到每一个entry对象 
		for (Entry<String, String> entry : entrySet) { 
			// 解析 
			String key = entry.getKey(); 
			String value = entry.getValue(); 
			System.out.println(key+"的CP是:"+value); 
		} 
	} 
}
5. Map接口的实现类
1)HashMap集合

​ 存储数据采用的哈希表结构,元素的存取顺序不能保证一致。

​ 【注】当给HashMap中存放自定义对象时,如果自定义对象作为key存在,这时要保证对象唯一,必须重写对 象的hashCode和equals方法(回忆HashSet存放自定义对象)。

2)LinkedHashMap集合

​ HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素 的存取顺序一致;通过哈希表结构可以保证键的唯一、不重复。

posted @ 2020-05-07 20:04  Java程序员的进阶之路  阅读(151)  评论(0编辑  收藏  举报