JAVA集合类汇总

Java集合类详解:ArrayList, LinkedList, HashSet, TreeSet与Map实现
本文介绍了Java集合类的重要性,对比了数组和集合类的特点。详细讲解了基于Collection接口的ArrayList、LinkedList、Vector,基于Set接口的HashSet和TreeSet,以及基于Map接口的HashMap和TreeMap的使用,包括它们的底层实现、特点、常用API。此外,还讨论了equals方法、hashCode方法和比较器接口在集合类中的作用。

为什么要使用集合类?

集合类就是用于存储多个数据的类 在Java基础中我们学习了数组,而数据时可以存储多个数据的,为什么还要使用集合?

数组的特点

  1. 用于存放多个数据

  2. 数组中的数据的数据类型是相同的

  3. 数组的长度固定

  4. 数组的操作需要开发人员自己定义相关操作算法

集合类的特点

  1. 集合类中可以存放多个数据

  2. 集合类中存放的数据的类型的任意类型(内部类型为Object类型,所以可以存放任意类型)

  3. 集合类的长度都是可变的

  4. 集合类中提供了关于这类集合的常用操作方法,开发人员可以通过这些方法实现对集合的常见操作

集合类不是一个类,而是一套接口和类的统称

Java中集合类的类结构

Java中的集合类根据存储方式不同分为两大类集合

  1. 基于Collection接口的线性集合

    Collection接口下有两个子接口,分别对应不同的线性集合

    1.List接口的特点

     1.有序的集合(进入到集合中顺序)
     2.可以存放重复数据的集合

    List接口的的实现类:

     1.ArrayList
     2.LinkedList
     3.Vector

    2.Set接口

    1.无序的集合(不保证集合中元素的顺序)
    2.不允许存放重复数据的集合

    Set接口的实现类: 1.HashSet 2.TreeSet

  2. 基于Map接口的key-value映射对集合

基于List接口的ArrayList类的使用

ArrayList底层是基于动态数组实现的

ArrayList的特点

1.ArrayList在使用时,查找其中的元素效率是比较高的,数组有下标,可以通过下标直接锁定到一个元素

  1. ArrayList在插入或移除元素时效率低(内存中要移位)

ArrayList常用API

  1. 创建ArrayList对象

    //创建ArrayList集合类对象
    ArrayList arrayList = new ArrayList();
  2. add(element):向ArrayList的尾部追加一个元素

    //向ArrayList的尾部追加元素
         arrayList.add("aaa");
         arrayList.add(20);
         arrayList.add('a');
         arrayList.add(true);
         arrayList.add(20.5);
    3.add(index,element):向集合中的某个位置插入一个元素
    
    //向ArrayList的某个位置插入元素
         arrayList.add(2,"str");

    4.get(index):根据下标获得该下标对应的元素,默认返回Object类型(根据自己的需要转换具体类型)

    //根据下标获得一个元素
         String str= (String) arrayList.get(0);
         System.out.println(str);

    5.remove(element|index):如果参数为对象类型,则根据内容移除,如果参数为int类型的基本类型则根据下标移除

    //移除元素
         arrayList.remove("aaa");
         System.out.println(arrayList);
         //如果参数为int类型,则根据下标移除,如果要移除的内容为整数则需要使用Integer类型删除
         arrayList.remove(new Integer(3));
         ystem.out.println(arrayList);

    6.遍历ArrayList集合中的所有元素

   //遍历List集合中的所有元素
//使用传统for循环遍历
        for(int i=0;i<arrayList.size();i++){
        Object obj = arrayList.get(i);
        System.out.println(obj);
        }
        System.out.println("---------------");
        //使用for循环加强版遍历
        for(Object obj : arrayList){
        System.out.println(obj);
        }
        System.out.println("---------------");
        //使用list集合中的foreach方法进行遍历
        arrayList.forEach(System.out::println);

基于List接口的实现类LinkedList

LinkedList的特点

LinkedList底层是基于链表实现

1.插入或删除元素时效率高 2.查询及遍历元素时效率低

LinkedList常用PAI

  1. add(element):尾部添加

  2. addFirst(element):首部插入

  3. addLast(element):尾部插入

  4. add(index,element):指定下标位置插入元素

  5. push(element):入栈

  6. pop():出栈

  7. toArray():将列表转换为数组

基于List接口的实现类Vector

Vector的特点

1.Vector的底层也是基于动态数组实现 2.Vector中提供的操作和ArrayList基本相同

ArrayList和Vector的区别

  1. 相同点:ArrayList和Vector底层都是基于动态数组实现,而且提供了相近的API

  2. 不同点: (1) ArrayList默认创建长度为0的数组,而Vector创建的长度为10的数组 (2) Vector是线程安全的,而ArrayList是非线程安全的,在并发情况下建议使用Vector 我们可以通过外部手段让ArrayList也是线程安全的

基于Set接口的实现类HashSet

HashSet的特点 :

        1.底层基于Map集合的实现

        2.不能存放重复数据

        3.集合中的元素不保证顺序

         4.Set集合无法从集合中直接获取某一个元素

        5.Set集合没有下标

         HashSet常用API 1.add(element):向集合中添加一个元素 2.iterator():遍历集合中的所有元素

//遍历集合中元素
        Iterator<String> iterator = hashSet.iterator();
        //循环遍历集合中的每个元素
        while(iterator.hasNext()){//检测集合中是否存在要迭代的数据,true表示存在
            String str = iterator.next();//获取一个元素
            System.out.println(str);
        }

3.通过foreach循环遍历集合中所有元素

//使用foreach遍历集合中的所有元素
        for(String str : hashSet){
            System.out.println(str);
        }

4.使用foreach方法遍历集合中的元素

//通过foreach方法遍历集合中的所有元素
        hashSet.forEach(System.out::println);

基于Set接口的TreeSet实现

TreeSet是基于树状结构的Set集合,该集合可以排序,被称为可排序的Set集合

TreeSet集合的特点 1.TreeSet是一个有序的Set集合 2.TreeSet中不能存放重复数据 3.在TreeSet中存储的元素必须为可排序的元素(实现了比较器接口的对象),如果存储的元素为不可排序的元素则会报异常(ClassCastException)

基于key-value(键值对)的Map集合

Map集合中存储的元素为一个key对应一个value

Map集合的特点

1.key不允许重复,默认情况下key是Object类型,可以存放任意类型的数据 2.value是允许重复,默认情况下value是Object类型,可以存放任意类型的数据 3.Map中允许存在null的key(只能出现一次)和null的value

基于Map接口的实现类HashMap

HashMap中不允许存放重复key,如果新添加的key已存在,则使用新的value替换原有的value值

HashMap的常用API

1.put(key,val):向Map集合中添加一对key-value 2.get(key):根据key获得对应的value 3.remove(key):根据key移除Map集合中的一个元素 4.size():获得集合中元素的数量 5.keySet():获得Map集合中所有的key,返回一个包含所有key的set集合

Map<String,String> map = new HashMap<String,String>(){{
            put("key1","val1");
            put("key2","val2");
            put("key3","val3");
            put("key4","val4");
            put("key5","val5");
        }};
        //获得所有的key
        Set<String> keySet = map.keySet();
        //使用keySet遍历Map集合
        Iterator<String> it = keySet.iterator();
        while(it.hasNext()){
            String key = it.next();
            String value = map.get(key);
            System.out.println(key+"<---->"+value);
        }

6.values():获得Map集合中所有的value,返回一个Collection集合 7.entrySet():获得Map集合中每个元素的Entry集合对象,返回Set集合

for (Map.Entry<String,String> entry : map.entrySet()){
            System.out.println(entry.getKey()+"<--->"+entry.getValue());
        }

Map集合中的key不能重复,如果想Map添加一个新元素,Map集合如何判定该元素在集合中是否存在?

基于Map接口的TreeMap实现类

TreeMap和TreeSet一样都是一个可排序的集合 TreeMap中根据key进行排序的 进入到TreeMap中的元素(key)必须为可排序的元素(key) ###equals方法 ==也是用于判断两个对象是否相等:用于判断两个对象是否为同一个对象的 equals方法用于判断两个对象的值是否相等

        String s1 = "abc";
        String s2 = "abc";
        //s1和s2两个变量都指向“abc”字符串对象,他们两个是同一个对象
        System.out.println(s1 == s2);
        /**
         * Java中每次使用new关键字创建对象时,在JVM的堆区都会自动创建一个新对象
         * 只不过两个对象的值都是"abc"字符串
         * 这两个对象不是同一个对象,但他们的值是相等
         * 所以“==”的结果为false,他们两个不是同一个对象
         * 如果要判断两个对象的值是否相等使用equals方法
         */
        String str = new String("abc");
        String str1 = new String("abc");
        System.out.println(str == str1);//false
        System.out.println(str.equals(str1));

equals方法在任意对象中都存在,该方法在Object类中定义的,他们默认定位为

 public boolean equals(Object obj) {
        return this == obj;
    }

从Object类中的源码可以看出,equals方法默认的定义为判断两个对象是否为同一个对象的 所以为了能够判断两个对象的值是否相等,我们在自己定义的实体类中都会重写该方法 String重写equals方法,JDK中大多数类都重写了该方法...

hashCode方法

hashCode方法在任意类中都存在,该方法也是在Object类中定义的 hashCode方法用于获得当前对象所对应的内存地址的hash码 如果两个对象的hash相等,则表示当前的两个对象肯定为同一个对象(默认情况) 开发人员可以根据实际需要重写hashCode,重写后不同对象的hashCode就有可能相等

在开发中一般会重写equals方法和hashCode方法以改变他们的默认行为

Map集合如何判断新添加的元素的key在集合中是否存在

1.先判断hashCode是否相等,如果hashCode不相等则认为没有相同的对象,直接将新元素添加到map集合中 2.如果hashCode的值存在相等的,则无法确定是否存在相同对象,进而继续判断equals方法,如果equals返回值为true,则认为存在相等元素 使用新元素替换原有的元素,如果equals判断是不相等,则认为不存在相同对象直接将新元素添加到map集合中

比较器接口

比较器是用于定义比较规则,有了比较规则后,就可以对这些数据按照比较规则进行排序 Java中定义比较规则的方式有两种:

(1) 实现Comparable接口:Comparable在java.lang包下 - Comparable用于实现对象的默认比较规则,默认比较规则只有一种 - Comparable中存在一个compareTo方法,该方法用于定义比较规则 - 方法的返回值为正整数表示当前对象大于比较对象 - 方法的返回值等于0两个对象相等 - 方法的返回值为负整数表示当前对象小于比较对象

@Override
    public int compareTo(User user) {
​
        return this.userId - user.getUserId();
    }

(2) 实现Comparator接口:Comparator在java.util包下 - Comparator用于定义对象的扩展比较规则的,可以定义多个 - Comparator接口中有一个定义比较规则的方法compare(obj1,obj2) - 方法的返回值为正整数表示obj1大于obj2 - 方法的返回值等于0两个对象相等 - 方法的返回值为负整数表示obj1小于obj2

/**
 * 使用内部类定义扩展规则
 * 1.根据积分升序排序
 */
    static class sortByScoreASC implements Comparator<User>{
​
​
    @Override
    public int compare(User user1, User user2) {
        return user1.getUserScore() - user2.getUserScore();
    }
}
​
/**
 * 2.根据积分降序排序
 */
​
static class sortByScoreDESC implements Comparator<User>{
​
​
    @Override
    public int compare(User user1, User user2) {
        return user2.getUserScore() - user1.getUserScore();
    }
}
​
​
    /**
     * 2.根据学号降序排序
     */
​
    static class sortByUserIdDESC implements Comparator<User>{
​
​
        @Override
        public int compare(User user1, User user2) {
            return user2.getUserId() - user1.getUserId();
        }
    }
    
    //调用
    TreeSet<User> users = new TreeSet<>();//使用user对象中的默认排序规则进行排序
       //使用User内定义的内部类指定排序规则
    TreeSet<User> users = new TreeSet<>(new User.sortByUserIdDESC());
       //使用匿名内部类定义排序规则
    TreeSet<User> users = new TreeSet<>(new Comparator<User>() {
       //使用匿名内部类实现比较器接口
       @Override
       public int compare(User user1, User user2) {
          return user1.getRegDate().compareTo(user2.getRegDate());
       }
    });
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值