集合(上)Collection接口,List集合,Set集合的使用

本文详细讲解了Java中的Collection接口与List(如ArrayList和LinkedList)、Set(如TreeSet和HashSet)的关系,以及它们的特点、操作方法和使用场景,强调了数组与集合的区别和集合在编程中的重要性。
摘要由CSDN通过智能技术生成

文章目录


前言

        ·集合可以看作一个没有容量限制的数组。集合还可添加各样任意类型的元素。并且集合中的每个对象,既容易从中取出,也容易将其存放到集合中,还能按照一定顺序进行摆放。Java提供不同的集合类,这些集合类具有不同的存储对象的方法;同时都提供了相应的方法对集合进行遍历、添加、删除和查找指定的对象。集合是java的必学点


一、Collection接口与List、Set集合是什么关系?

        首先,集合类Collection接口,List集合、Set集合,都处于 java.util包中,在使用集合时一定要导入java.util包

5bea4431a6fc4a01ac4fb6ce1546d8cc.png

        List集合、Set集合是Collection接口的具体实现(implements)类,这两个集合类实现Collection接口(是Set接口和List接口将图中的关系联系在一起),可以调用Collection接口中所有方法。

补充(数组与集合的区别):

        (1)数组的长度是固定的,集合的长度是可变的。

        (2)数组用来存放基本数据的数据,集合用来存放对象的引用;

二、Collection接口

        Collection接口通常不会直接使用(因为有更加完备的子集合Set类、List类、Map类),但该接口提供了添加、删除、管理数据的方法,当然这些方法都可以被List,Set集合类使用。

Collection接口的常用方法
方法功能描述
add(Object o)将指定的对象添加到该集合中
remove(Object o)将指定的对象从该集合中移除
isEmpty()返回boolean值,用于判断当前集合是否为空
iterator()返回集合类的元素,进行迭代的迭代器,用于遍历集合中的对象
size()返回int值,获取该集合中元素的个数

实操: 

import java.util.*;
public class Demo{
    public static void main(String args[]){
        //创建集合类对象
        Collection<String> list = new ArrayList<>();    //设置泛型类型为String
        list.add("a");    //向集合添加元素"a"
        list.remove(0);    //将在存储位置为0的元素从集合中移除
        if(list.isEmpty()){    //判断该集合是否为空集合
            Iterator it = list.iterator();    //创建该集合的迭代器对象
            while(it.hasNext()){    //判断迭代器中的数据是否还有下一个值
                System.out.println(it.next());    //遍历该集合的所有元素
            }
        }else{
            Syetem.out.println(list.size());    //获取并输出该集合的长度
        }
        
    }
}

        注:以上方法均可被 List集合Set集合Map集合调用。

1.List集合

        List集合包括List接口以及List接口的所有实现类。List集合中的元素允许重复可保存null值各元素的顺序就是对象插入的顺序。我们可以通过索引(元素在集合中的位置int值)来访问集合中的元素。

        List接口继承了Collection接口,具有Collection接口的所有方法,同时自身还有额外的方法。

List接口的额外方法
方法功能描述
get(int index)获得指定索引位置的元素
set(int index,Object obj)将集合中指定索引位置的原对象修改为指定对象
List<String> list = new ArrayList<>();
list.add("a");
list.add("c");
System.out.println(list.get(1));    //获取集合对应指针位置的元素
list.set(1, "b");   //更改对应指针位置的元素内容(只能更改目前集合已有范围的元素),不然会报错

List接口的实现类: ArrayList 与 LinkedList

使用List集合时通常声明为List类型,可通过不同的实现类来实例化集合

        ArrayList类:动态数组(最大容量动态变化),允许保存所有元素,包括 null值,可以保存相同元素。优势在于随机访问集合中的对象。

声明方式:

List<E> list = new ArrayList<>();
//声明ArrayList对象

实操: 

public class Demo{
    public static void main(String args[]){
        List<String> list = new ArrayList<>();
        list.add(null);    //可以添加null值
        list.add(null);    //可以添加相同的值
        list.add("666");

        int i =(int)(Math.random()*list.size());
        System.out.println("随机获取动态数组中的元素为"+i);    //对集合进行快速的随机访问
    }
}

-------------------------------------------------------------------------------------------------------------------------------- 

        LinkedList类:链表,允许保存所有元素,包括 null值,可以保存相同元素。优势在于向集合中插入或删除对象时更加高效。

声明方式:

List<E> list = new LinkedArray<>();
//声明一个list链表对象

 实操:

public class Demo{
    public static void main(String args[]){
        List<String> list = new Linkedlist<>();
        list.add(null);    //可以添加null值
        list.add(null);    //可以添加相同的值
        list.add("666");

        int i =(int)(Math.random()*list.size());
        list.remove(i);    //向集合中插入或删除对象效率更高一些
    }
}

2.Set集合 

        Set集合只是简单地把对象添加到集合中,之后有比较器判断大小排序,没有比较器,则从小到大自然排序,Set集合不能包含重复的对象。Set集合由Set接口和其实现类(TreeSet类和HashSet)组成。

Set接口的实现类:TreeSet 和 HashSet

        TreeSet类:不能保存null值。该类实现了Set接口,还实现了java.util.SortedSet接口。因此,可以通过比较器对用TreeSet类实现的Set对象进行排序,可以存储null值,同时自身会有额外的方法

当创建一个TreeSet集合时,可以通过构造函数传入一个Comparator对象,该Comparator对象定义了元素的比较规则。在添加元素时,TreeSet会根据Comparator来确定元素的插入位置,保证集合中的元素始终按照指定的比较规则排序。

TreeSet类增加的方法
方法功能描述
first()返回此Set中当前第一个(最小)元素
last()返回此Set中当前最后一个(最大)元素
comparator()返回对此Set中的元素进行排序的比较器,比较器排序位置。如果此Set为自然排序,返回值为null
headSet(E toElement)返回一个新的Set集合,新集合是toElement(不包含自身)对象之前的所有对象(原集合的子集)
subSet(E formElement,E toElement)返回一个新的Set集合,新集合是从fromElement(包含自身)到toElement(不包含自身)的所有对象(原集合的子集)
tailSet(E fromElement)返回一个新的Set集合,新集合是包含对象fromElement(包含自身)之后的所有对象(原集合的子集)

实操:

        first()和last()

import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(10);
        treeSet.add(5);
        treeSet.add(20);

        // 获取TreeSet中的最第一个的元素
        System.out.println("TreeSet中的第一个元素是: " + treeSet.first());

        // 获取TreeSet中的最最后一个的元素
        System.out.println("TreeSet中的最后一个元素是: " + treeSet.last());
    }
}

 未设置比较器,treeSet集合由小到大自然排序,第一个元素是5,最后一个元素是20

3517668c225a4a4d825bcdf6b4029861.png 

         comparator()

import java.util.Comparator;
import java.util.TreeSet;

public class Main {
    public static void main(String[] args) {
        // 创建一个使用自定义比较器的TreeSet
        TreeSet<String> treeSet = new TreeSet<>(Comparator.reverseOrder());
        // 排序方式设置为降序排序
        treeSet.add("apple");
        treeSet.add("banana");
        treeSet.add("orange");

        // 获取TreeSet使用的比较器
        Comparator<String> setComparator = treeSet.comparator();

        if (setComparator == null) {
            System.out.println("TreeSet使用自然排序");
        } else {
            System.out.println("TreeSet使用自定义比较器:" + setComparator);
        }
    }
}

4b6d4e2be7144e3aaadd613bac5446c1.png 

        TreeSet元素自定义排序方法:除了创建Comparator对象,在创建TreeSet对象时调用Comparator对象,实现对已有元素的自定义排序,还可以通过元素类实现Comparable接口,实现接口中的compareTo(Object o) 方法,比较此对象与指定对象的顺序,如果该对象小于、等于或大于指定对象,则分别返回负整数、0或正整数。

         创建两个类,TreeSetDemo类和InnerPerson类,TreeDemo类向Set添加对象时,Set中所有的对象排序按照InnerPerson(实现了Comparable)类中compareTo(Object o)方法进行排序。

import java.util.*;

public class TreeSetDemo {

    public static void main(String[] args) {
    
    Set a = new TreeSet<>();

    InnerPerson p1 = new InnerPerson(1, "阿琛", 32);
    InnerPerson p2 = new InnerPerson(2, "阿明", 42);
    InnerPerson p3 = new InnerPerson(3, "阿发", 33);
    
    a.add(p1);
    a.add(p2);
    a.add(p3);
    // TreeSet集合不能添加 null值
    }
}

@SuppressWarnings("rawtypes")
class InnerPerson implements Comparable{

    //定义人的属性
    int id;
    String name;
    int age;
    
    public InnerPerson(int id,String name,int age){
        super();
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String toString(){
        return "Person [id="+id+", age="+age+", name="+name+"]";
    }

    public int compareTo(Object o){
        InnerPerson p;
        if(o instanceof InnerPerson){
            p = (InnerPerson)o;
        }else{
            return -1;
        }

        int diff = this.id - p.id;
        if(diff!=0){
            diff = diff/Math.abs(diff);
        }
        return diff;
    }
    
}

        代码说明:此compareTo()方法将TreeSet中的元素排序顺序设置为了id排序, 

当调用`compareTo()`方法时,传入元素(Object o)之间的比较结果会返回以下三种情况:

1. 负数:表示当前元素应该排在传入元素的前面。换句话说,当前元素在排序中应该位于传入元素之前。

2. 0:表示当前元素和传入元素是相等的,在排序中它们的顺序可以是任意的。

3. 正数:表示当前元素应该排在传入元素的后面。换句话说,当前元素在排序中应该位于传入元素之后。

这意味着,如果一个元素的`compareTo()`方法返回一个负数,那么它会被排序到前面;如果返回0,那么它可以和其他相等的元素的顺序任意;如果返回正数,那么它会被排序到后面。

         subSet(E formElement,E toElement)

import java.util.TreeSet;

public class Tree {
    public static void main(String[] args) {
        TreeSet<Integer> treeSet = new TreeSet<>();
        treeSet.add(10);
        treeSet.add(20);
        treeSet.add(30);
        treeSet.add(40);
        treeSet.add(50);

        // 使用subSet方法获取子集视图
        TreeSet<Integer> subSet = (TreeSet<Integer>) treeSet.subSet(20, 40);

        // 遍历并输出子集视图中的元素
        for (Integer element : subSet) {
            System.out.println(element);
        }
    }
}

 treeSet.sub(20,40);  获取一个新的子集合,对象个数从20(包含自身)到40(不包含自身)

255736a48eef48eb8a74f37de910de3b.png


        HashSet类: 

        HashSet类,由哈希表支持,允许保存一个null值,它不能保证Set的迭代顺序,特别不能保证所有元素的排列顺序保持不变,使用HashSet类,需要覆写hashCode()和equals(Object o)方法,以确保对象的相等判断是正确的。

import java.util.*;
public class HashSetDemo {
    
    public static void main(String[] args) {
        Set set = new HashSet<>();
        Person a = new Person(1,"小明");
        Person b = new Person(2,"小强");
        Person c = new Person(3,"小乐");
        
        set.add(null);//HashSet集合可以添加null值

        set.add(a);
        set.add(b);
        set.add(c);

        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }

}

    /*HashSet存放数据的三种情况
        1.向集合空哈希地址直接插入新对象
        2.集合不会保存相同的对象(通过与equals方法对比原储存元素object哈希值是否相同)
        3.同一个哈希值,可以存放多个不同的对象(例如在存入第二个相同哈希值对象前,更改第一个已存入该存储位置的对象的哈希值)
    */
class Person{
    int id;
    String  name;

    public Person (int id, String name){
        super();
        this.id=id;
        this.name = name;
    }

    public String toString(){
        return "Person [id="+id+", name="+name+"]";
    }

    public int hashCode(){  //返回值result为每个元素在equals方法中对比是否相同的关键值
        final int prime = 31;
        int result = 1;
        result = prime*result+id;
        return result;
    }

    public boolean equals(Object obj){  //对应哈希地址的储存元素(this)与obj新元素的对比HashCode返回数据是否为同一对象,返回true值不保存obj,返回false值在相同的哈希地址下保存这两个对象()
        if(this == obj){
            return true;
        }else if(obj == null){
            return false;
        }
        
        Person other = (Person)obj;
        
        if(id!=other.id){
            return false;
        }
        
        return true;
    }
}

覆写hasCode()的原因:        

  1. 相等的对象应该具有相等的哈希码。
  2. 尽可能地将不相等的对象映射到不同的哈希码,以提高哈希表的效率。
  3. 添加的对象,与该位置已有的对象(或者null值),通过equals()方法对比HashCode值,不同返回false,则保存在该集合的hashCode位置上。

总结

        以上就是关于集合的部分内容,本文仅仅简单介绍了Collection接口与List、Set集合的使用,集合是我们学习java的必须掌握的内容。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵果森森

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值