Java常用集合梳理

集合

在java中,我们常常需要存放多个数据,这时我们常常想到用数组来存放,但如果需要存放的数据是不同类型的数据或者数据个数未知的,数组就无能为力了.这时使用集合来存放数据就解决了这些问题.
集合和数组比起来:
1.数组的长度是固定的,集合的长度是可变的.
2.数组只能存储同类型的对象,集合可以存储不同类型的对象.
3.集合只能存储对象,不能存储基本数据类型.(系统会自动将基本数据类型封装成对应的包装类型存储)

常用集合关系图

Collection

Collection是所有单列集合的父接口,在Collection中定义了单例集合(List和Set)的一些通用的方法,这些方法可以操作所有的单列集合.

常用方法:

  1. public boolean add(E e):把给定的对象添加到当前集合中.
		Collection<String> collection = new ArrayList<>();
        System.out.println(collection.add("abc")); //true
  1. public void clear():清空集合中所有的元素.
		Collection<String> collection = new ArrayList<>();
		collection.clear();
		System.out.println(collection); //[]
  1. public boolean remove(E e): 把给定的对象在当前集合中删除.
		Collection<String> collection = new ArrayList<>();
        collection.add("abc");
        collection.remove("abc");
        System.out.println(collection); //[]
  1. public boolean contains(Object obj): 判断当前集合中是否包含给定的对象.
		Collection<String> collection = new ArrayList<>();
        collection.add("abc");
        System.out.println(collection.contains("a")); //false
        System.out.println(collection.contains("abc")); //true ("abc"为一个对象)
  1. public boolean isEmpty(): 判断当前集合是否为空.
		Collection<String> collection = new ArrayList<>();
		System.out.println(collection.isEmpty()); //true
        collection.add("abc");
        System.out.println(collection.isEmpty()); //false
  1. public int size(): 返回集合中元素的个数.
		Collection<String> collection = new ArrayList<>();
        System.out.println(collection.size()); //o
        collection.add("abc");
        System.out.println(collection.size()); //1
  1. public Object[] toArray(): 把集合中的元素,存储到数组中.
		Collection<String> collection = new ArrayList<>();
        collection.add("abc");
        collection.add("123");
        collection.add("@#$%");
        System.out.println(Arrays.toString(collection.toArray())); //[abc, 123, @#$%]

Collection的遍历

  1. for增强(foreach)遍历(底层是依靠Iterator迭代器实现的)
		Collection<String>collection=new ArrayList<>();
        collection.add("a");
        collection.add("b");
        collection.add("c");
        for (String s : collection) {
            System.out.print(s+" "); //a b c
        }
  1. 迭代器遍历
		Collection<String> collection = new ArrayList<>();
        collection.add("a");
        collection.add("b");
        collection.add("c");
        Iterator<String> iterator = collection.iterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next()+" "); //a b c
        }
  1. 注意事项
    在遍历过程中不允许对集合进行增删操作,否则会出现IllegalStateException异常
		Collection<String> collection = new ArrayList<>();
        collection.add("a");
        collection.add("b");
        collection.add("c");
        Iterator<String> iterator = collection.iterator();
        for (String s : collection) {
            if(s.equals("a")){
                iterator.remove(); //IllegalStateException
            }
        }

正确对集合增删操作的方法:

		Collection<String> collection = new ArrayList<>();
        collection.add("a");
        collection.add("b");
        collection.add("c");
        Iterator<String> iterator = collection.iterator();
        while (iterator.hasNext()){
            String next = iterator.next();
            if(next.equals("a")){
                iterator.remove();
            }
        }
        System.out.println(collection); //[b, c]

Collections常用方法

  1. public static void shuffle(List<?> list):打乱集合顺序.
		List<Integer>list=new ArrayList<>();
        list.add(10);
        list.add(20);
        list.add(30);
        Collections.shuffle(list);
        System.out.println(list); //[20, 10, 30]
  1. public static <T> void sort(List<T> list):将集合中元素按照默认规则排序.(在对应的类中已定义好默认排序规则)
		List<Integer>list=new ArrayList<>();
        list.add(20);
        list.add(30);
        list.add(10);
        Collections.sort(list);
        System.out.println(list); //[10, 20, 30]
  1. public static <T> void sort(List<T> list,Comparator<? super T> com ):将集合中元素按照指定规则排序.
		List<Integer> list = new ArrayList<>();
        list.add(20);
        list.add(30);
        list.add(10);
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer integer, Integer t1) {
                return t1 - integer; //t1 - integer 为降序
            }						 //integer - t1 为升序
        });
        System.out.println(list); //[30, 20, 10]

List

List接口是Collection接口的子接口具备Collection的所有方法.将实现了List接口的对象称为List集合.

List接口的特点:

  1. 它是一个元素存取有序的集合.取出元素的顺序跟存入元素时的顺序相同.
  2. 它带有索引.可以通过索引精确地操作集合中的元素.
  3. 它允许集合中的元素重复.

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

  1. public void add(int index, E element):将指定的元素,添加到该集合中的指定位置上.
		List<String> list = new ArrayList<>();
        list.add("a");
        list.add("c");
        list.add(1,"b");
        System.out.println(list); //[a, b, c]
  1. public E get(int index):返回集合中指定位置的元素。
		List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        System.out.println(list.get(1)); //b
  1. public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
		List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        System.out.println(list.remove(1)); //b
        System.out.println(list); //[a]
  1. public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
		List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        System.out.println(list.set(1,"c")); //b
        System.out.println(list); //[a, c]
ArrayList

ArrayList集合数据存储的结构是数组结构,所以它查询快,而在对集合进行增删操作时,由于集合是有序的,对应操作元素之后的元素都要向前或向后移动,它的底层是有一定容量的,若容量不足还会创建一个新的容量足够的ArrayList集合再将元素拷贝到新集合中.所以它增删慢.它用来查询数据、遍历数据是比较合适的.

LinkedList

LinkedList集合数据存储的结构是链表结构,在查询元素的时候底层会判断index离链头还是链尾更近,用来确定正向还是反向遍历,并找到该index对应的元素,所以它查询慢,而在对集合进行增删操作时,由于它是双向链表结构,只需要将被操作元素和它前后元素的引用关系修改就完成了.所以它增删快.如果要对集合中的数据进行大量的增删操作,用LinkedList会更好.

在这里插入图片描述

LinkedList是List的子类,List中的方法LinkedList都是可以使用,它还提供了大量首尾操作的方法.

  1. public void addFirst(E e):将指定元素插入此列表的开头.
		LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("b");
        System.out.println(linkedList); //[b]
        linkedList.addFirst("a");
        System.out.println(linkedList); //[a, b]
  1. public void addLast(E e):将指定元素添加到此列表的结尾.
		LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("b");
        System.out.println(linkedList); //[b]
        linkedList.addLast("a");
        System.out.println(linkedList); //[b, a]
  1. public E getFirst():返回此列表的第一个元素.
		LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("a");
        linkedList.add("b");
        System.out.println(linkedList.getFirst()); //a
  1. public E getLast():返回此列表的最后一个元素.
		LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("a");
        linkedList.add("b");
        System.out.println(linkedList.getLast()); //b
  1. public E removeFirst():移除并返回此列表的第一个元素.
		LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("a");
        linkedList.add("b");
        System.out.println(linkedList.removeFirst()); //a
  1. public E removeLast():移除并返回此列表的最后一个元素.
		LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("a");
        linkedList.add("b");
        System.out.println(linkedList.removeLast()); //b
  1. public E pop():从此列表所表示的堆栈处弹出一个元素.
		LinkedList<String> linkedList = new LinkedList<>();
        linkedList.add("a");
        linkedList.add("b");
        System.out.println(linkedList.pop()); //a
        System.out.println(linkedList); //[b]
  1. public void push(E e):将元素推入此列表所表示的堆栈.
    同1. public void addFirst(E e):将指定元素插入此列表的开头.
  2. public boolean isEmpty():如果列表不包含元素.则返回true.
		LinkedList<String> linkedList = new LinkedList<>();
        System.out.println(linkedList.isEmpty()); //true
        linkedList.add("a");
        System.out.println(linkedList.isEmpty()); //false

Set

Set接口继承了Collection接口,也继承了它的所有方法,实现了Set接口的类叫做Set集合.

Set接口的特点:
元素无索引,元素存取无序,元素不可重复.

HashSet

HashSet保证元素唯一的原理: 它的底层是哈希表结构,哈希表保证元素唯一依赖于hashCode()和equals()方法.
当HashSet集合存储元素时,就会调用该元素的hashCode方法计算哈希值,然后判断该哈希值位置上是否有相同哈希值的元素,如果没有就直接存储,如果有就产生了哈希冲突,这时就会调用该元素的equals方法与该哈希值位置上的元素一一进行比较,如果该位置上有任一元素与该元素相同,就不存储,如果该位置上所有元素都与该元素不同,就直接存储.

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

import java.util.*;

class Person {
    private String name;
    private String job;

    public Person(String name, String job) {
        this.name = name;
        this.job = job;
    }

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", job='" + job + '\'' +
                '}';
    }
}

public class Demo {
    public static void main(String[] args) {
        Person p1 = new Person("张三", "老师");
        Person p2 = new Person("李四", "医生");
        Person p3 = new Person("李四", "医生");
        HashSet<Person> hashSet = new HashSet<>();
        hashSet.add(p1);
        hashSet.add(p2);
        hashSet.add(p3);
        System.out.println(hashSet); //[Person{name='李四', job='医生'}, Person{name='张三', job='老师'}]
        System.out.println(p1.hashCode()); //25062431
        System.out.println(p2.hashCode()); //26795352
        System.out.println(p3.hashCode()); //26795352
    }
}

LinkedHashSet

LinkedHashSet是链表和哈希表组合的一个数据存储结构,使用它可以保证元素取出时的顺序和存入时相同.

		LinkedHashSet<String> linkedHashSet = new LinkedHashSet<>();
        linkedHashSet.add("a");
        linkedHashSet.add("c");
        linkedHashSet.add("b");
        for (String s : linkedHashSet) {
            System.out.print(s+" "); //a c b 
        }
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("a");
        hashSet.add("c");
        hashSet.add("b");
        for (String s : hashSet) {
            System.out.print(s+" "); //a b c 
        }
TreeSet

TreeSet集合是Set接口的一个实现类,底层依赖于TreeMap,是一种基于红黑树的实现,它元素唯一,元素没有索引,使用元素的自然顺序对元素进行排序,或者根据创建时提供的Comparator进行排序.

		TreeSet<Integer> treeSet1 = new TreeSet<>();
        treeSet1.add(3);
        treeSet1.add(1);
        treeSet1.add(2);
        System.out.println(treeSet1); //[1, 2, 3]
        TreeSet<Integer> treeSet2 = new TreeSet<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer integer, Integer t1) {
                return t1 - integer; //t1 - integer为降序
            }						 //integer - t1为升序
        });
        treeSet2.add(3);
        treeSet2.add(1);
        treeSet2.add(2);
        System.out.println(treeSet2); //[3, 2, 1]

Map

Map接口是所有双列集合的顶层父接口.Map<K,V> K用来限制键的类型,V用来限制值的类型.

  1. Map集合存储元素是以键值对的形式存储,也就是说每一个键值对都有键和值
  2. 通过键取值
  3. Map集合中的键不能重复,如果键重复了,那么值就会被覆盖.
  4. Map集合中的值是可以重复的.

常用方法:

  1. public V put(K key, V value):把指定的键与指定的值添加到Map集合中.
		Map<String,Integer>map=new HashMap<>();
        map.put("张三",18);
        System.out.println(map); //{张三=18}
  1. public V remove(Object key):把指定的键所对应的键值对元素在Map集合中删除,返回被删除元素的值.
		Map<String,Integer>map=new HashMap<>();
        map.put("张三",18);
        map.put("李四",19);
        System.out.println(map.remove("张三")); //18
        System.out.println(map); //{李四=19}

  1. public V get(Object key):根据指定的键,在Map集合中获取对应的值.
		Map<String,Integer>map=new HashMap<>();
        map.put("张三",18);
        map.put("李四",19);
        System.out.println(map.get("张三")); //18
  1. public boolean containsKey(Object key):判断该集合中是否有此键
		Map<String,Integer>map=new HashMap<>();
        map.put("张三",18);
        System.out.println(map.containsKey("张三")); //true
        System.out.println(map.containsKey("李四")); //false
  1. public Set<K> keySet(): 获取Map集合中所有的键,存储到Set集合中.
		Map<String,Integer>map=new HashMap<>();
        map.put("张三",18);
        map.put("李四",19);
        map.put("王五",20);
        Set<String> keys = map.keySet();
        System.out.println(keys); //[李四, 张三, 王五]
  1. public Collection<V> values() 获取Map集合中所有的值,存储到Collection集合中.
		Map<String,Integer>map=new HashMap<>();
        map.put("张三",18);
        map.put("李四",19);
        map.put("王五",20);
		Collection<Integer> values = map.values();
        System.out.println(values); //[19, 18, 20]
  1. public Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合).
		Map<String, Integer> map = new HashMap<>();
        map.put("张三", 18);
        map.put("李四", 19);
        map.put("王五", 20);
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
        System.out.println(entrySet); //[李四=19, 张三=18, 王五=20]

Map的遍历

  1. for增强(foreach)遍历(底层是依靠Iterator迭代器实现的)
		Map<String, Integer> map = new HashMap<>();
        map.put("张三", 18);
        map.put("李四", 19);
        map.put("王五", 20);
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
        for (Map.Entry<String, Integer> entries : entrySet) {
            System.out.print(entries+" "); //李四=19 张三=18 王五=20
        }
  1. 迭代器遍历
		Map<String, Integer> map = new HashMap<>();
        map.put("张三", 18);
        map.put("李四", 19);
        map.put("王五", 20);
        Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
        for (Map.Entry<String, Integer> entries : entrySet) {
            String key = entries.getKey();
            Integer value = entries.getValue();
            System.out.print(key+"="+value+" "); //李四=19 张三=18 王五=20 
        }

HashMap

键唯一,键值对存取无序, 由哈希表保证键唯一.

		HashMap<String,Integer> HashMap =new HashMap<>();
        HashMap.put("张三",18);
        HashMap.put("李四",19);
        HashMap.put("王五",20);
        System.out.println(HashMap); //{李四=19, 张三=18, 王五=20}
LinkedHashMap

键唯一,键值对存取有序(取出顺序与存入顺序一致),由哈希表保证键唯一,由链表保证键值对存取有序.

		LinkedHashMap<String,Integer>linkedHashMap=new LinkedHashMap<>();
        linkedHashMap.put("张三",18);
        linkedHashMap.put("李四",19);
        linkedHashMap.put("王五",20);
        System.out.println(linkedHashMap); //{张三=18, 李四=19, 王五=20}

TreeMap

键唯一,可以对键值对进行排序.
TreeMap集合和Map相比没有特有的功能,底层的数据结构是红黑树,可以对元素的键进行排序,排序方式有两种:自然排序比较器排序,到时使用的是哪种排序,取决于我们在创建对象的时候所使用的构造方法.

		TreeMap<Integer, String> treeMap1 = new TreeMap<>();
        treeMap1.put(1, "张三");
        treeMap1.put(2, "李四");
        treeMap1.put(3, "张三");
        System.out.println(treeMap1); //{1=张三, 2=李四, 3=张三}
        TreeMap<Integer, String> treeMap2 = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer integer, Integer t1) {
                return t1 - integer; //t1 - integer为降序
            }						 //integer - t1为升序
        });
        treeMap2.put(1, "张三");
        treeMap2.put(2, "李四");
        treeMap2.put(3, "张三");
        System.out.println(treeMap2); //{3=张三, 2=李四, 1=张三}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值