Day_8/08(List集合和Set集合)

目录

一、List集合

        1、ArrayList集合

        2、LinkedList集合

        1、增加元素

        2、查询元素

        3、修改元素

        4、删除元素

二、Set集合

        1、HashSet集合 

        2、LinkedHashSet集合

三、总结


一、List集合

        List集合继承自Collection接口,元素是以线性方式存储的,元素有序并且可以重复,存入顺序就是取出顺序可以使用下标和迭代器或增强型for循环遍历获取元素。

常用的方法有:

  • public void add(int index, E element): 将指定的元素,添加到该集合中的指定位置上。

  • public E get(int index):返回集合中指定位置的元素。

  • public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。

  • public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。

其实就是增删改查,前面讲Collection集合的时候已经接触过ArrayList了,所以稍后使用LinkedList来测试一下。 

        1、ArrayList集合

                ArrayList是List的一个具体实现类,它以数组结构存储数据,这样的好处是方便查询和遍历元素,不过增加和删除元素相对来说慢一点,在日常开发中,查询和遍历元素使用的相对较多,所以ArrayList也是最常用的集合,不过也不要随意的使用ArrayList集合来完成任何需求,这样不严谨,不提倡使用。

前面讲Collectiong集合和iterator迭代器的时候已经使用过ArrayList集合来测试了,这里就不再演示。

        2、LinkedList集合

                LinkedList也是List集合的一个具体实现类,和ArrayList集合不同的是LinkedList集合使用的是链式结构来存储数据的,这样的好处是方便增加和删除元素,同时LinkedList集合还提供了大量首尾操作的方法,代码演示如下:

        1、增加元素

import java.util.LinkedList;

public class Test {
    public static void main(String[] args) {
        //创建LinkedList集合对象
        LinkedList<String> strLinkedList = new LinkedList<>();
        //1、LinkedList集合增加元素
        //使用add方法(默认添加在集合尾部)
        strLinkedList.add("asd");
        //添加元素到指定的下标
        strLinkedList.add(0,"sdf");
       
    }
}

 我们如何直到元素添加成功了呢?有几种办法,第一种,看集合添加元素前后的长度,如果添加一个元素之后,集合的长度增加了1,那么就说明添加成功了,第二种,在没有指定元素添加位置时,add方法是会有一个boolean值返回来的,可以通过输出查看add方法返回的值来判断是否添加成功,第三种,遍历输出;对于添加在指定位置的add方法我们可以直接查看指定下标处的值是否为我们添加的元素,后面这两种办法有一点缺陷,那就是List集合是允许元素重复的,如果恰好我们指定添加元素的位置的值和添加的元素的值相同,那么就不好判断了,所以最好还是使用返回值和集合长度来判断,看代码演示:

public class Test {
    public static void main(String[] args) {
        //创建LinkedList集合对象
        LinkedList<String> strLinkedList = new LinkedList<>();
        //1、LinkedList集合增加元素

        //添加元素前集合的长度
        System.out.println("添加元素前集合的长度为"+strLinkedList.size());

        //使用add方法(默认添加在集合尾部)
        System.out.println("元素添加的状态:"+strLinkedList.add("asd"));
        //添加元素到指定的下标
        strLinkedList.add(0, "sdf");

        //添加元素后集合的长度
        System.out.println("添加元素后集合的长度为"+strLinkedList.size());
    }
}

运行结果: 

 结果很显然,集合的长度在添加两个元素之后增加了2,不指定位置添加元素的时候add方法返回了一个true,这样即证明了元素添加成功。

下面看LinkedList集合提供的首尾操作的方法(添加元素到集合的首部和尾部):

public class Test {
    public static void main(String[] args) {
        //创建LinkedList集合对象
        LinkedList<String> strLinkedList = new LinkedList<>();
        //1、LinkedList集合增加元素

        //添加元素前集合的长度
        System.out.println("添加元素前集合的长度为"+strLinkedList.size());

        //使用add方法(默认添加在集合尾部)
        System.out.println("元素添加的状态:"+strLinkedList.add("asd"));
        //添加元素到指定的下标
        strLinkedList.add(0, "sdf");

        //添加元素到集合的首部
        strLinkedList.addFirst("dfg");
        //添加元素到集合的尾部
        strLinkedList.addLast("fgh");

        //添加元素后集合的长度
        System.out.println("添加元素后集合的长度为"+strLinkedList.size());
        
        //增强型for循环遍历输出一下,查看元素"dfg"和元素"fgh"是否分别添加在集合的首部和尾部
        for (String str : strLinkedList) {
            System.out.println(str);
        }
    }
}

运行结果: 

结果很明显,"dfg"添加在集合的首部了,"fgh"添加在了集合的尾部。

        2、查询元素

//2、查询元素
        System.out.println("集合的第一个元素为:"+strLinkedList.getFirst());   //获取集合的第一个元素并输出
        System.out.println("集合的最后一个元素为:"+strLinkedList.getLast());   //获取集合的最后一个元素并输出
        System.out.println("集合的第三个元素为:"+strLinkedList.get(2));  //获取集合指定位置的元素

在前面的基础上加上以上两句语句,运行结果如下: 

 这两个方法都是返回集合的元素,因为我开始存入集合的都是String对象,所以直接输出对象,就是我们要的String字符串。

        3、修改元素

现在我要把集合的第三个元素修改为"zxcv",看代码:

//3、修改元素
        System.out.println("修改的结果为:"+strLinkedList.set(2,"zxcv"));

运行结果: 

 这里怎么不对呢,我不是把第三个元素修改为"zxcv"了吗?怎么还是"asd"呢?其实它是修改成功了的,因为set方法修改元素后返回的是被修改的元素,它告诉我们哪个元素被修改了,再来查看一下第三个元素:

//3、修改元素
        System.out.println("被修改的元素为:"+strLinkedList.set(2,"zxcv"));
        System.out.println("修改后的元素为"+strLinkedList.get(2));

 运行结果:

这就是LinkedList集合中元素的修改了。 

        4、删除元素

下面再来看看删除元素,代码如下:

//4、删除元素
        System.out.println("remove方法不带参数默认删除的元素为:"+strLinkedList.remove());
        System.out.println("remove方法删除元素\"zxcv\"的状态为"+(strLinkedList.remove("zxcv")?"成功":"失败"));
        //再次遍历集合列表,看看是否删除成功
        for (String str : strLinkedList) {
            System.out.println(str);
        }

运行结果: 

 很显然,集合里面第一个元素"dfg"被不带参数的remove方法删除了,而元素"zxcv"则是被带一个参数的remove方法删除了,并且都删除成功,除此之外,LinkedList集合还提供了删除首部元素和尾部元素的方法以及清空集合的方法,代码如下:

//4、删除元素
//        System.out.println("remove方法不带参数默认删除的元素为:"+strLinkedList.remove());
//        System.out.println("remove方法删除元素\"zxcv\"的状态为"+(strLinkedList.remove("zxcv")?"成功":"失败"));
        System.out.println("集合的第一个元素:"+strLinkedList.removeFirst()+"已被删除");
        System.out.println("集合的最后一个元素"+strLinkedList.removeLast()+"已被删除");
        System.out.println("集合删除首部元素和尾部元素后"+(strLinkedList.isEmpty()?"为空":"不为空"));
        strLinkedList.clear();
        System.out.println("集合清空元素后"+(strLinkedList.isEmpty()?"为空":"不为空"));

这里演示了删除集合首部元素和尾部元素以及清空集合的方法,并且用isEmpty方法来判断集合是否为空,从而判断集合是否清空,clean方法和isEmpty方法前面都讲过了,它们都是Collection里面有的方法,LinkedList集合实现了List集合,而List集合又是Collection的子类,所以这些方法是LinkedList集合和ArraysList集合共有的。 

二、Set集合

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

        1、HashSet集合

        HashSet集合是根据对象的哈希值来确定元素在集合中的存储位置的,元素无序,存取顺序不能保证一致

代码如下:

public class Test {
    public static void main(String[] args) {
        //创建HashSet集合对象
        HashSet<String> strHashSet = new HashSet<>();

        //先添加几个元素
        strHashSet.add("qwe");
        strHashSet.add("wer");
        strHashSet.add("ert");
        strHashSet.add("rty");

        for (String str : strHashSet) {
            System.out.println(str);
        }
    }
}

运行结果: 

代码很简单,就是添加几个元素,之后遍历输出,但是这里有一个问题,输出的结果顺寻并不是我存数据的顺序,这里就体现出了Set集合元素无序,存取顺序不能保证一致。

数据不能重复,使用hashCode()和equals()方法保证数据唯一性

代码如下:

//先添加几个元素
        strHashSet.add("qwe");
        strHashSet.add("wer");
        strHashSet.add("ert");
        strHashSet.add("qwe");

运行结果: 

你看,这里我添加了两次元素"qwe",但是只添加进一个,所以当集合里面添加一个集合中已经有的元素时,是添加不进去的,因为hashCode方法和equals方法保证了数据的唯一性。 

元素无序,没有下标和get方法,不能使用下标访问元素,只能使用增强型for循环和迭代器访问

//迭代器访问元素
        Iterator iter = strHashSet.iterator();
        while(iter.hasNext()){
            System.out.println(iter.next());
        }
        System.out.println("--------迭代器访问和增强型for循环访问分界线---------");
        //增强型for循环访问元素
        for (String str : strHashSet) {
            System.out.println(str);
        }

运行结果: 

存储数据类型为自定义类的时候,必须重写自定义类里面的hashCode和equals方法

 看一段代码:

public class Test {
    public static void main(String[] args) {
        //创建HashSet集合对象
        HashSet<Animal> strHashSet = new HashSet<>();

        //先添加几个元素
        strHashSet.add(new Animal("大黄","黄色"));
        strHashSet.add(new Animal("大黑","黑色"));
        strHashSet.add(new Animal("大黄","黄色"));

        for (Animal animal : strHashSet) {
            System.out.println("名字是:"+animal.name+",颜色是"+animal.color);
        }
    }
}
class Animal{
    String name;
    String color;

    public Animal(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public Animal() {
    }
}

运行结果: 

这里好奇怪啊,Set类集合里面怎么可以村相同的元素进去了呢?前面说过, Set集合是通过hashCode()和equals()方法来保证数据唯一性,现在我们在集合里面存放的是自己定义的数据类型,必须要重写hashCode()和equals()方法才可以,看代码:

PS:在ldea里面我们直接使用Alt+Insert组合键就可以自动生成了

public class Test {
    public static void main(String[] args) {
        //创建HashSet集合对象
        HashSet<Animal> strHashSet = new HashSet<>();

        //先添加几个元素
        strHashSet.add(new Animal("大黄","黄色"));
        strHashSet.add(new Animal("大黑","黑色"));
        strHashSet.add(new Animal("大黄","黄色"));

        for (Animal animal : strHashSet) {
            System.out.println(animal);
        }
    }
}
class Animal{
    String name;
    String color;

    public Animal(String name, String color) {
        this.name = name;
        this.color = color;
    }

    public Animal() {
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Animal)) return false;
        Animal animal = (Animal) o;
        return Objects.equals(name, animal.name) && Objects.equals(color, animal.color);
    }

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

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

运行结果:

 此时发现,重写了hashCode()和equals()方法之后元素就不能重复了,这里我也重写了toString方法,这样就可以通过输出元素名来输出元素里面的值了。 

        2、LinkedHashSet集合

我们知道HashSet保证元素唯一,可是元素存放进去是没有顺序的,那么我们要保证有序,怎么办呢?

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

代码演示如下:

public class Test {
    public static void main(String[] args) {
        //创建LinkedHashSet集合对象
        LinkedHashSet<String> strLinkedHashSet = new LinkedHashSet<>();

        //添加几个元素
        strLinkedHashSet.add("qaz");
        strLinkedHashSet.add("wsx");
        strLinkedHashSet.add("edc");
        strLinkedHashSet.add("qaz");
        
        //遍历输出
        for (String str : strLinkedHashSet) {
            System.out.println(str);
        }
    }
}

运行结果: 

三、总结

        1、List集合允许元素重复,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。

        2、Set集合不允许元素重复,使用hashCode和equals方法来保证元素的唯一性,元素无序,不能保证存入顺序和取出顺序一致,没有下标,只能通过迭代器或增强型for循环来访问。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值