Java集合 -- Collection体系集合comparable 和 Comparator的区别集合框架底层数据结构总结如何选用集合

Posted CodeJiao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java集合 -- Collection体系集合comparable 和 Comparator的区别集合框架底层数据结构总结如何选用集合相关的知识,希望对你有一定的参考价值。

1. Collection集合体系


1.1 集合概念

对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能。


1.2 集合与数组的区别

  • 数组长度固定,集合长度不固定;
  • 数组可以存储基本类型和引用类型,集合只可以存储引用类型(如果想要存储基本数据类型,可以存储基本数据类型的包装类)。

1.3 位置

Java集合框架提供了一套性能优良,使用方便的接口和类,他们位于java.util包中。


1.4 Collection体系集合

什么叫做有序?

  • 有序指的是添加的顺序与遍历的顺序应该保持一致,比如添加的顺序为a,b,c那么遍历的时候应该是a,b,c

2. comparable 和 comparator的区别

  • comparable接口实际上是出自 java.lang 包 它有一个 compareTo(Object obj)方法用来排序
  • comparator接口实际上是出自 java.util 包它有一个compare(Object obj1, Object obj2)方法用来排序

一般我们需要对一个集合使用自定义排序时,我们就要重写compareTo()方法或compare()方法,当我们需要对某一个集合实现两种排序方式,比如一个song对象中的歌名和歌手名分别采用一种排序方法的话,我们可以重写compareTo()方法和使用自制的Comparator方法或者以两个Comparator来实现歌名排序和歌星名排序,第二种代表我们只能使用两个参数版的 Collections.sort()


2.1 comparable 具体案例


TestComparable.java

import java.util.TreeSet;

/**
 * ClassName: TestComparable
 * Description:
 *
 * @author Tianjiao
 * @date 2022/3/12 11:22
 */
public class TestComparable 
    public static void main(String[] args) 
        TreeSet<Student> treeSet = new TreeSet<>();
        for (int i = 5; i >= 1; i--) 
            treeSet.add(new Student(i));
        

        System.out.println(treeSet.toString());
    


class Student implements Comparable<Student> 
    int age;

    public Student(int age) 
        this.age = age;
    

    // 按照age的大小正序排序
    @Override
    public int compareTo(Student student) 
        return this.age - student.age;
    

    @Override
    public String toString() 
        return "Student" +
                "age=" + age +
                '';
    

运行结果:


2.2 comparator具体案例

    public static void main(String[] args) 
        TreeSet<String> treeSet = new TreeSet<>(new Comparator<String>() 
            /**
             * MethodName: compare
             * Description: 按照字符串长度排序(正序排序), 如果长度相同, 就按照字符串自带的compareTo方法排序
             *
             * @return int
             */
            @Override
            public int compare(String o1, String o2) 
                int n1 = o1.length() - o2.length();
                int n2 = o1.compareTo(o2);
                return n1 == 0 ? n2 : n1;
            
        );
        treeSet.add("Hello World!");
        treeSet.add("Java the best!");
        treeSet.add("C#");
        treeSet.add("Go");
        treeSet.add("Python");
        treeSet.add("C");
        treeSet.add("C++");
        treeSet.add("JavaWeb");
        treeSet.add("javascript");
        treeSet.add("CSS");
        treeSet.add("html");
        treeSet.add("Angular");
        System.out.println(treeSet.toString());
    

运行结果:


3. 集合框架底层数据结构总结


3.1 List

  • ArraylistObject数组
  • VectorObject数组
  • LinkedList: 双向链表(JDK1.6之前为循环链表,JDK1.7取消了循环)

3.2 Set

  • HashSet(⽆序,唯⼀): 基于 HashMap 实现的,底层采⽤ HashMap 来保存元素。
  • LinkedHashSetLinkedHashSet 继承于 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 HashMap 实现⼀样,不过还是有⼀点点区别的。
  • TreeSet(有序,唯⼀): 红⿊树(⾃平衡的排序⼆叉树)。

3.3 Map

  • HashMapJDK1.8之前HashMap数组+链表组成的,数组是HashMap的主体,链表则是主要为了解决哈希冲突⽽存在的(“拉链法”解决冲突)。JDK1.8以后在解决哈希冲突时有了较⼤的变化,当链表⻓度⼤于阈值(默认为8)时,将链表转化为红⿊树,以减少搜索时间。
  • LinkedHashMapLinkedHashMap 继承⾃ HashMap,所以它的底层仍然是基于拉链式散列结构即由数组和链表或红⿊树组成。另外,LinkedHashMap 在上⾯结构的基础上,增加了⼀条双向链表,使得上⾯的结构可以保持键值对的插⼊顺序。同时通过对链表进⾏相应的操作,实现了访问顺序相关逻辑。
  • Hashtable数组+链表组成的,数组是 HashMap 的主体,链表则是主要为了解决哈希冲突⽽存在的
  • TreeMap: 红⿊树(⾃平衡的排序⼆叉树)

4. 如何选用集合

主要根据集合的特点来选⽤:

  • 需要根据键值获取到元素值时就选⽤Map接⼝下的集合。
  • 需要排序时选择TreeMap
  • 不需要排序时就选择HashMap
  • 需要保证线程安全就选⽤ConcurrentHashMap
  • 当我们只需要存放元素值时,就选择实现Collection接⼝的集合。
  • 需要保证元素唯⼀时选择实现Set接⼝的集合⽐如TreeSetHashSet
  • 不需要就选择实现List接⼝的⽐如ArrayListLinkedLis
  • …。



以上是关于Java集合 -- Collection体系集合comparable 和 Comparator的区别集合框架底层数据结构总结如何选用集合的主要内容,如果未能解决你的问题,请参考以下文章

韩顺平循序渐进学Java零基础 第14章 集合

Java_集合初步讲解——Collection集合

Java集合框架--学习目标 & 集合概念 & Collection体系集合 & Collection接口

Java集合Collection 体系集合详解(ArrayList,LinkedList,HashSet,TreeSet...)

Java集合 -- Collection体系集合comparable 和 Comparator的区别集合框架底层数据结构总结如何选用集合

JAVA入门之Collection集合 笔记(35)