【Java】集合类

1 概述

集合是java提供的一种容器,可以存储多个数据。
集合与数组的不同:

  • 数组的长度是固定的,集合的长度是可变的
  • 数组存储同一类型的元素,存储基本数据类型;集合存储对象的引用,可以是不同的对象类型

2 常见集合类的继承关系

graph BT Collection-->Java.lang.Object Map-->Java.lang.Object HashMap-->Map TreeMap-->Map List-->Collection Set-->Collection ArrayList-->List LinkedList-->List HashSet-->Set TreeSet-->Set

3 Collection接口

常用方法:

方法 功能描述
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.1 Iterator迭代器

迭代:即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。

Collection和Map接口主要用于存储元素,Iterator主要用于迭代访问(即遍历)Collection中的元素
常用方法:

方法 功能描述
public Iterator iterator() 获取集合对应的迭代器,用来遍历集合中的元素
public boolean add(E e) 把给定的对象添加到当前集合中
public void clear() 清空集合中所有的元素
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class Test2_Iterator {
    public static void main(String[] args) {
        Collection<String> coll = new ArrayList<String>();

        coll.add("艾伦");
        coll.add("三笠");
        coll.add("阿尔敏");

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

当遍历集合时,首先通过调用t集合的iterator()方法获得迭代器对象,然后使用hashNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出,否则说明已到达了集合末尾,停止遍历元素。

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

//格式:
for(元素的数据类型  变量 : Collection集合or数组){ 
  	//写操作代码
}

3.2 List接口

在List集合中的元素允许重复,所有的元素线性方式存储,在程序中可以通过索引访问集合中的指定元素。各元素的存储顺序就是插入的顺序。
常用方法:

方法 功能描述
public void add(int index, E element) 将指定的元素,添加到该集合中的指定位置上
public E get(int index) 返回集合中指定位置的元素
public E remove(int index) 移除列表中指定位置的元素, 返回的是被移除的元素
public E set(int index, E element) 用指定元素替换集合中指定位置的元素,返回值是更新前的元素
  • ArrayList集合:数据存储的结构是数据结构。元素查找快,增删慢,是最常用的集合
  • LinkedList集合:数据存储的结构是链表结构。便于元素添加、删除。

3.3 Set接口

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

💎Set的构造有一个约束条件,传入的Collection对象不能有重复值

3.3.1 HashSet

java.util.HashSet 是 Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。保证元素唯一性的方式依赖于: hashCode 与 equals 方法。

在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的,JDK1.8引入红黑树大程度优化了HashMap的性能,那么对于我们来讲保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

给HashSet中存放自定义类型元素时,需要重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一:

import java.util.Objects;

public class Student {
    private String name;
    private int age;

    public Student(){}
    public Student(String name,int age){
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public boolean equals(Object o){
        if(this == o){
            return true;
        }
        if(o == null || getClass() != o.getClass()){
            return false;
        }
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name,student.name);
    }

    @Override
    public int hashCode(){
        return Objects.hash(name,age);
    }
}


import java.util.HashSet;

public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<Student> stuSet = new HashSet<Student>();

        Student stu = new Student("于谦", 43);
        stuSet.add(stu);
        stuSet.add(new Student("郭德纲", 44));
        stuSet.add(new Student("于谦", 43));
        stuSet.add(new Student("郭麒麟", 23));
        stuSet.add(stu);

        for (Student stu2 : stuSet) {
            System.out.println("name=" + stu2.getName() + ",age=" + stu2.getAge());
        }
    }
}
执行结果:
name=郭德纲,age=44
name=于谦,age=43
name=郭麒麟,age=23

3.3.2 LinkHashSet

要保证有序,在HashSet下面有一个子类 java.util.LinkedHashSet ,它是链表和哈希表组合的一个数据存储结构。

3.4 Collections

java.utils.Collections 是集合工具类,用来对集合进行操作。部分方法如下:

方法 功能描述
public static boolean addAll(Collection c, T... elements) 往集合中添加一些元素
public static void shuffle(List<?> list) 打乱集合顺序
public static void sort(List list) 将集合中元素按照默认规则排序
public static void sort(List list,Comparator<? super T> ) 将集合中元素按照指定规则排序

4 Map集合

Collection接口定义的是单列集合
而Map集合没有继承Collection接口,定义的是双列集合,提供Map <key,value>的映射关系,Map集合不能包含相同的键key,每个键key只能映射一个键值value

常用子类:

  • HashMap:存储数据采用的哈希表结构,元素的存取顺序不能保证一致。由于要保证键的唯一、不重复,需要重写键的hashCode()方法、equals()方法。
  • LinkedHashMap:HashMap下有个子类LinkedHashMap,存储数据采用的哈希表结构+链表结构。通过链表结构可以保证元素的存取顺序一致;通过哈希表结构可以保证的键的唯一、不重复,需要重写键的hashCode()方法、equals()方法

💎Map接口中的集合都有两个泛型变量,在使用时,要为两个泛型变量赋予数据类型。两个泛型变量的数据类型可以相同,也可以不同。

常用方法:

方法 功能描述
public V put(K key, V value) 把指定的键与指定的值添加到Map集合中
public V remove(Object key) 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值
public V get(Object key) 根据指定的键,在Map集合中获取对应的值
boolean containsKey(Object key) 判断集合中是否包含指定的键
public Set keySet() 获取Map集合中所有的键,存储到Set集合中
public Set<Map.Entry<K,V>> entrySet() 获取到Map集合中所有的键值对对象的集合(Set集合)

map的遍历1(键找值):

    HashMap<String, String> map = new HashMap<String, String>();

    map.put("name","bob");
    map.put("age","20");
    map.put("job","designer");

    Set<String> keys = map.keySet();
    for(String key: keys){
          String value = map.get(key);
          System.out.println(key + ":" + value);
    }

map的遍历2(Entry键值对):
Map 中存放的是两种对象,一种称为key(键),一种称为value(值),它们在在 Map 中是一一对应关系,这一对对象又称做 Map 中的一个 Entry(项) 。Entry 将键值对的对应关系封装成了对象。即键值对对象,这样我们在遍历 Map 集合时,就可以从每一个键值对( Entry )对象中获取对应的键与对应的值。
方法:

方法 功能描述
public K getKey() 获取Entry对象中的键
public V getValue() 获取Entry对象中的值
public Set<Map.Entry<K,V>> entrySet() 获取到Map集合中所有的键值对对象的集合(Set集合)
    HashMap<String,String> map = new HashMap<String, String>();

    map.put("木玛","木马乐队");
    map.put("华东","重塑雕像的权利");
    map.put("李剑","大波浪乐队");   
    
    Set<Map.Entry<String,String>> entrySet = map.entrySet();
    for(Map.Entry<String,String> entry : entrySet){
          String key = entry.getKey();
          String value = entry.getValue();
          System.out.println(key + ":" + value);
    }
posted @ 2020-09-17 16:39  KJee  阅读(144)  评论(0编辑  收藏  举报