集合类

第二十五章 集合类


提纲

  • 25.1 集合类概述
  • 25.2 List集合
    • 25.2.1 概念
    • 25.2.2 List集合的特点
    • 25.2.3 List接口
    • 25.2.4 List接口的实现类
    • 25.2.5 泛型
    • 25.2.6 List集合中常用的方法
    • 25.2.7 List集合举例
    • 25.2.8 增强for循环
  • 25.3 Set集合
    • 25.3.1 Set集合的特点
    • 25.3.2 Set接口的主要实现类
  • 25.4 Map集合
    • 25.4.1 Map集合的特点
    • 25.4.2 Map主要实现类
  • 25.5 Arrays类与Collections类
    • 25.5.1 主要方法
    • 25.5.2 举例
  • 25.6 作业

25.1 集合类概述

  1. Java.util包中提供了一些集合类,这些集合类又被称为容器。提到容器就会想到数组,它们的作用都是一样的,存储数据。
  2. 集合与数组的区别:
    1. 长度。数组的长度是固定的,集合的长度是可变的,即没有长度限制。
    2. 存放数据的类型。数组用来存放基本数据类型和对象。集合只能存放对象的引用,不能存放基本数据类型。数组创建后就只能存放规定的一种数据类型的数据,如果集合创建没有规定泛型,则可以存放任何对象。
  3. 集合类之间的关系如图:集合框架.jpg。
    集合框架

25.2 List集合

  • 25.2.1 概念:Collecttion接口是层次结构中的根接口,JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。包 (bag) 或多集合 (multiset)(可能包含重复元素的无序 collection)应该直接实现此接口。

  • 25.2.2 List集合的特点:

    1. List集合包括List接口以及List接口的所有实现类。
    2. List集合中的元素允许重复,集合中的元素是有顺序的,各元素的顺序就是对象插入的顺序。
    3. 类似数组,可通过使用索引(元素在集合中的位置)来访问集合中的元素。
  • 25.2.3 List接口:List接口继承了Collection接口,因此包含Collection接口中的所有方法。此外,List接口中还定义了两个非常重要的方法。

    • get(int index):获得指定索引位置的元素。
    • set(int index, E element):将集合中指定索引位置的对象修改为指定的对象。
  • 25.2.4 List接口的实现类:List接口的常用实现类有ArrayList与LinkedList。

    1. ArrayList类实现了List接口,允许保存所有对象,包括null。
      • 优点:可以根据索引位置对集合进行快速的随机访问。
      • 缺点:向指定的索引位置插入对象或删除对象的速度较慢。
    2. LinkedList类采用链表结构保存。
      • 优点:便于向集合中插入和删除对象。执行效率高。
      • 缺点:随机访问集合中的对象时,效率较低。
  • 25.2.5 泛型:为了指定确定的对象,防止在强制转换的过程中出现错误,增加安全性。

      List<E> list = new ArrayList<E>();
      List<E> list2 = new LinkedList<E>();
      //上面的代码中,E就是泛型,可以写引用数据类型,不能写基本数据类型。
      //例如:如果集合中的元素为字符串类型,那么E可以修改为String。
    
  • 25.2.6 List集合中常用的方法:

    • add(E e):将指定的元素添加到此列表的尾部。E代表任何对象元素。返回值:boolean
    • add(int index, E element):将指定的元素插入此列表中的指定位置。index:代表要插入的位置。E代表插入的元素。返回值:void
    • addAll(Collection<? extends E> c):将另一个集合的所有元素加入到此集合的尾部。c代表另一个集合。返回值:boolean
    • clear():移除此列表中的所有元素。返回值:void
    • contains(Object o):如果此列表中包含指定的元素,则返回 true。返回值:boolean
    • get(int index):返回此列表中指定位置上的元素。返回值:E
    • indexOf(Object o):返回此列表中首次出现的指定元素的索引,或如果此列表不包含元素,则返回 -1。返回值:int
    • isEmpty():如果此列表中没有元素,则返回 true。返回值:boolean
    • lastIndexOf(Object o):返回此列表中最后一次出现的指定元素的索引,或如果此列表不包含索引,则返回 -1。返回值:int
    • remove(int index):移除此列表中指定位置上的元素。返回值:E
    • remove(Object o):移除此列表中首次出现的指定元素(如果存在)。返回值:boolean
    • set(int index, E element):用指定的元素替代此列表中指定位置上的元素。返回值: E,泛型所指定的对象类型。
    • size():返回此列表中的元素数。返回值: int
  • 25.2.7 List集合举例:

      public static void main(String[] args) {
      	List<String> list = new ArrayList<String>();
      	list.add("a");
      	list.add("b");
      	list.add("c");
      	list.add(1, "你");
      	System.out.println("list的长度:"+list.size());
      	List<String> list2 = new ArrayList<String>();
      	list.add("d");
      	list.add("e");
      	list.add("f");
      	list.addAll(list2);
      	System.out.println("是否包含a:"+list.contains("a")+",是否包含m:"+list.contains("m"));
      	System.out.println("第三个位置的字符为:"+list.get(2));
      	System.out.println("c首次出现所在的索引为:"+list.indexOf("c"));
      	//list.clear();
      	System.out.println("集合是否为空:"+list.isEmpty());
      	list.remove(0);//移除第一个位置上的元素
      	list.remove("c");//移除首次出现的c元素
      	list.set(0, "我");//用字符“我”代替第一个位置的元素
      	for (int i = 0; i < list.size(); i++) {
      		System.out.print(list.get(i)+" ");
      	}
      }
      //执行结果
      list的长度:4
      是否包含a:true,是否包含m:false
      第三个位置的字符为:b
      c首次出现所在的索引为:3
      集合是否为空:false
      我 b d e f 
    
  • 25.2.8 增强for循环:For-Each循环也叫增强型的for循环,或者叫foreach循环。

    • 语法

        //遍历数组
        for(Type value : array){
        	//直接使用value
        }
        //遍历集合
        for (Type value : Iterable) {
           //直接使用value
        }
      
    • 举例

        public static void main(String[] args) {
        	List<Integer> list = new ArrayList<Integer>();
        	list.add(1);
        	list.add(2);
        	list.add(3);
        	list.add(4);
        	System.out.print("普通for循环结果:");
        	for (int i = 0; i < list.size(); i++) {
        		System.out.print(list.get(i)+" ");
        	}
        	System.out.print("\n"+"增强for循环结果:");
        	for (Integer integer : list) {
        		System.out.print(integer+" ");
        	}
        }
        //执行结果
        普通for循环结果:1 2 3 4 
        增强for循环结果:1 2 3 4 
      
      • 优缺点
        • 优点:写法简单,便于使用
        • 缺点:丢掉了索引信息。当遍历集合或数组时,如果需要访问集合或数组的下标,那么最好使用旧式的方式来实现循环或遍历,而不要使用增强的for循环,因为它丢失了下标信息。

25.3 Set集合

  • 25.3.1 Set集合的特点:

    1. 长度可变。
    2. 集合中的对象无序且不重复。
    3. 没有get(int index)方法获取元素,只能使用迭代器或者增强for循环。
  • 25.3.2 Set接口的主要实现类:HashSet类与TreeSet类

      public static void main(String[] args) {
      	Set<String> set = new HashSet<String>();
      	set.add("a");
      	set.add("你好");
      	set.add("c");
      	set.add("jack");
      	set.add("!");
      	//遍历set集合的方法
      	//方法一:
      	Iterator<String> iterable = set.iterator();//先将HashSet集合交给迭代器
      	System.out.print("iterable方式遍历HashSet集合:");
      	while(iterable.hasNext()){//迭代器判断是否有下一个元素
      		System.out.print(iterable.next()+" ");//获取下一个元素
      	}
      	//方法二:
      	System.out.print("\n"+"增强for循环方式遍历HashSet集合:");
      	for (String string : set) {
      		System.out.print(string+" ");
      	}
      	//使用treeSet遍历
      	Set<String> set2 = new TreeSet<String>();
      	set2.addAll(set);
      	System.out.print("\n"+"增强for循环方式遍历TreeSet集合:");
      	for (String string : set2) {
      		System.out.print(string+" ");
      	}
      }
      //执行结果
      iterable方式遍历HashSet集合:d e b c a 
      增强for循环方式遍历HashSet集合:d e b c a 
      增强for循环方式遍历TreeSet集合:a b c d e 
    

    结论:两个类之间的主要区别是TreeSet集合会按照降序排序,而HashMap是无序的。按照阿斯克码排序。


25.4 Map集合

  • 25.4.1 Map集合的特点:
    1. Map集合没有继承Collection接口,是一个单独的接口
    2. Map集合提供的是key到value的映射,即是一个键值对。一个键对应一个值。
    3. 一个Map集合中不能包含相同的key,后面相同的key的值会覆盖前面的相同key的值。
    4. 不同的key是可以有相同的值的。
  • 25.4.2 Map主要实现类:HashMap类与TreeMap类
    1. 类中的常用方法
      • containsKey(Object key):如果此映射包含对于指定键的映射关系,则返回 true。
      • containsValue(Object value):如果此映射将一个或多个键映射到指定值,则返回 true。
      • get(Object key):返回指定键所映射的值;如果对于该键来说,此映射不包含任何映射关系,则返回 null。
      • keySet():返回此映射中所包含的键的 Set 视图。
      • put(K key, V value):在此映射中关联指定值与指定键。
      • putAll(Map<? extends K,? extends V> m):将指定映射的所有映射关系复制到此映射中,这些映射关系将替换此映射目前针对指定映射中所有键的所有映射关系。
      • remove(Object key):从此映射中移除指定键的映射关系(如果存在)。
      • size():返回此映射中的键-值映射关系数。
      • values():返回此映射所包含的值的 Collection 视图。
    2. 举例:
      • 例1:

          Map<String, Object> map = new HashMap<String, Object>();//Map
          map.put("admin", "123456");//键值对map.put(键, 值);
          map.put("lpm", "654321");
          map.put("lpm", "123456");
          map.put("lpm", "654321");
          System.out.println("admin对应的值:"+map.get("admin"));//通过键来获取值
          System.out.println("lpm对应的值:"+map.get("lpm"));
          //键不可重复,后面相同的键的值会覆盖前面的相同键的值。值可以重复
          //执行结果
          admin对应的值:123456
          lpm对应的值:654321
        
      • 例2:

          public static void main(String[] args) {
          	Map<String, Object> map = new HashMap<String, Object>();//Map
          	map.put("admin", "123456");
          	map.put("lpm", "654321");
          	map.put("xxx", "aaa");
          	map.put("yyy", "bbb");
          	Map<String, Object> map2 = new HashMap<String, Object>();//Map
          	map.put("admin", "ADMIN");
          	map.put("lpm", "LPM");
          	map.put("mmm", "aaa");
          	map.put("nnn", "bbb");
          	map.putAll(map2);
          	//遍历map集合的两种方法
          	//方法一:迭代器
          	//1.获取所有的key,并交给set集合
          	Set<String> set = map.keySet();
          	//2.直接遍历set集合
          	Iterator<String> iterator = set.iterator();
          	System.out.println("map集合包含key为admin吗:"+map.containsKey("admin")+
          				",map集合包含key为aaa吗:"+map.containsKey("aaa"));
          	System.out.println("map集合包含value为aaa吗:"+map.containsValue("aaa")+
          				",map集合包含value为qqq吗:"+map.containsValue("qqq"));
          	System.out.println("HashMap所打印的值:");
          	while(iterator.hasNext()){
          		String key = iterator.next();
          		Object value = map.get(key);
          		System.out.println("key:"+key+",value:"+value);
          	}
          	System.out.println("TreeMap所打印的值:");
          	Map<String, Object> map3 = new TreeMap<String, Object>();
          	map3.putAll(map);
          	Set<String> set2 = map3.keySet();
          	Iterator<String> iterator2 = set2.iterator();
          	while(iterator2.hasNext()){
          		String key = iterator2.next();
          		Object value = map3.get(key);
          		System.out.println("key:"+key+",value:"+value);
          	}
          }
          //执行结果
          map集合包含key为admin吗:true,map集合包含key为aaa吗:false
          map集合包含value为aaa吗:true,map集合包含value为qqq吗:false
          HashMap所打印的值:
          key:xxx,value:aaa
          key:lpm,value:LPM
          key:admin,value:ADMIN
          key:mmm,value:aaa
          key:nnn,value:bbb
          key:yyy,value:bbb
          TreeMap所打印的值:
          key:admin,value:ADMIN
          key:lpm,value:LPM
          key:mmm,value:aaa
          key:nnn,value:bbb
          key:xxx,value:aaa
          key:yyy,value:bbb
        
    结论:TreeMap会按照键key的降序排序。

25.5 Arrays类与Collections类

  • 25.5.1 主要方法

    1. Arrays.sort(a):升序排序,其中a为数组
    2. Collections.sort(list):升序排序,其中list为集合
    3. Collections.max(list):求集合中的最大值
    4. Collections.min(list):求集合中的最小值
  • 25.5.2 举例:

      public class FFF {
      	public static void printArr(int[] a){
      		for (int i = 0; i < a.length; i++) {
      			System.out.print(a[i]+" ");
      		}
      	}
      	
      	public static void printList(List<?> list){
      		for (int i = 0; i < list.size(); i++) {
      			System.out.print(list.get(i)+" ");
      		}
      	}
      	
      	public static void main(String[] args) {
      		int[] a = {5,66,0,3,11,900,1,12};
      		System.out.print("数组排序前:");
      		FFF.printArr(a);
      		Arrays.sort(a);//排序
      		System.out.print("\n"+"数组排序后:");
      		FFF.printArr(a);
      		List<Integer> list = new ArrayList<Integer>();
      		list.add(1);
      		list.add(66);
      		list.add(2);
      		list.add(99);
      		list.add(1000);
      		list.add(0);
      		System.out.println("\n"+"集合中的最大值:"+Collections.max(list));//求最大值
      		System.out.println("集合中的最小值:"+Collections.min(list));//求最小值
      		System.out.print("集合排序前:");
      		FFF.printList(list);
      		Collections.sort(list);//排序
      		System.out.print("\n"+"集合排序后:");
      		FFF.printList(list);
      	}
      }
      //执行结果
      数组排序前:5 66 0 3 11 900 1 12 
      数组排序后:0 1 3 5 11 12 66 900 
      集合中的最大值:1000
      集合中的最小值:0
      集合排序前:1 66 2 99 1000 0 
      集合排序后:0 1 2 66 99 1000 
    

25.6 作业

  1. 创建一个控制台应用程序,创建一个类型为ArrayList的集合对象,名为al,用集合对象al中记录1,2,3,4,5 这5个数字,请打印出集合对象al中第5个元素减去第1个元素的值的差。
  2. 创建一个控制台应用程序,创建一个猫类,名为Cat,为其定义名字和年龄字段,分别定义构造方法和属性。为其定义一个名为SayHy的方法,实现自我介绍的行为(打印我是**的猫,年龄**岁)。
    1. 在Main中创建一个ArrayList的集合对象al,在Main中创建3只猫对象cat1(“小黑猫”,1),cat2(”小白猫”,2),cat3(“小花猫”,3)。
    2. 用集合对象al添加上述3只猫对象, 并循环调用每只猫的SayHy方法。
    3. 删除一只小花猫。
  3. 编写学生,创建两个集合表示班级,一个班级可以存放多个学生。
    1. 增加一个学员。
    2. 方法 remove()方法,删除一个学员。删除有二种方式,第一种,可以传入下标,第二种,可以传入对象。
    3. 一个班级与另一个班级联宜,addAll()将两个班级的学员合并成一个班级。
  4. 把任意的10个的数字,写入一个ArrayList集合类,先求出10个数中的最大数、最小数,以及10个数的和、平均数。然后在任意位置上添加一个数。
  5. 利用上面的猫类和猪类,写一个程序:循环生成10个对象放入队列中,根据随机数为0表示放入一只猫,1为放入一头猪;采用循环显示每个对象的信息,并统计出10个对象中有多少猫,多少头猪。
  6. 创建一个Set集合,放入10个字符串对象,然后通过两种方法对其进行遍历。
  7. 创建一个Map集合,放入5个账号密码,再对其进行遍历。
posted @ 2021-05-14 14:00  64one  阅读(275)  评论(0)    收藏  举报