024-Java集合-List-Set

目录

List接口

List集合特点(有序,可重复)

List接口中特有方法

ArrayList集合

Vector集合

LinkedList集合

Set接口

特点

HashSet集合

哈希表

HashSet存储自定义类型元素

LinkedHashSet

感谢关注



 

List接口

java.util.List 接口继承自Collection 接口,是单列集合的一个重要分支,习惯性地会将实现了List 接口的对象称为List集合。

在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素。

另外,List集合还有一个特点就是元素有序,即元素的存入顺序和取出顺序一致。

List集合特点(有序,可重复)

有序的集合,存储元素和取出元素的顺序是一致的(存储1,2,3 取出还是1,2,3)

它是一个带有索引的集合,通过索引就可以精确的操作集合中的元素(与数组的索引是一个道理)

集合中可以有重复的元素,通过元素的equals方法,来比较是否为重复的元素。

线程不安全,所以效率高

 

List接口中特有方法

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

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

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

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

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

注意

        操作索引的时候,一定要防止索引越界异常。

常见的越界异常

        IndexOutOfBoundsException:索引越界异常,集合会报

        ArrayIndexOutOfBoundsException:数组索引越界异常

        StringIndexOutOfBoundsException:字符串索引越界异常

 

ArrayList集合

java.util.ArrayList 集合数据存储的结构是数组结构。元素增删慢,查找快,由于日常开发中使用最多的功能为查询数据、遍历数据,所以ArrayList 是最常用的集合。

List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("a");
System.out.println(list);//[a, b, c, d, a]  不是地址重写了toString

 

Vector集合

Vector 类实现了一个动态数组。和 ArrayList 很相似,但是两者是不同的:

  • Vector 是同步访问的。
  • Vector 包含了许多传统的方法,这些方法不属于集合框架。

Vector 主要用在事先不知道数组的大小,或者只是需要一个可以改变大小的数组的情况。

Vector线程安全,相对ArrayList来讲效率低。

参考:https://www.runoob.com/java/java-vector-class.html

 

LinkedList集合

java.util.LinkedList 集合数据存储的结构是链表结构。方便元素添加、删除的集合。查询慢,增删快。

LinkedList是一个双向链表:

cpublic void addFirst(E e) :将指定元素插入此列表的开头。

public void addLast(E e) :将指定元素添加到此列表的结尾。

public E getFirst() :返回此列表的第一个元素。

public E getLast() :返回此列表的最后一个元素。

public E removeFirst() :移除并返回此列表的第一个元素。

public E removeLast() :移除并返回此列表的最后一个元素。

public E pop() :从此列表所表示的堆栈处弹出一个元素。

public void push(E e) :将元素推入此列表所表示的堆栈。

public boolean isEmpty() :如果列表不包含元素,则返回true。

        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        System.out.println(linked);//[a, b, c]

        //String first = linked.removeFirst();
        String first = linked.pop();
        System.out.println("被移除的第一个元素:"+first);
        String last = linked.removeLast();
        System.out.println("被移除的最后一个元素:"+last);
        System.out.println(linked);//[b]

 

Set接口

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

特点

无序,不可重复

HashSet集合

java.util.HashSet 是Set 接口的一个实现类,它所存储的元素是不可重复的,并且元素都是无序的(即存取顺序不一致)。java.util.HashSet 底层的实现其实是一个java.util.HashMap 支持。

HashSet 是根据对象的哈希值来确定元素在集合中的存储位置,因此具有良好的存取和查找性能。

保证元素唯一性的方式依赖于: hashCode 与equals 方法。

哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)

在Object类有一个方法,可以获取对象的哈希值, int hashCode() 返回该对象的哈希码值。

哈希表

在JDK1.8之前,哈希表底层采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当位于一个桶中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,哈希表存储采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。简单的来说,哈希表是由数组+链表+红黑树(JDK1.8增加了红黑树部分)实现的。如图:

数组table 用来存储对象的哈希值,相同哈希值的元素会通过链表的方式存储。

JDK1.8引入红黑树大程度优化了HashMap的性能,对于我们来讲保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

 

HashSet存储自定义类型元素

给HashSet中存放自定义类型元素时,必须重写对象中的hashCode和equals方法,建立自己的比较方式,才能保证HashSet集合中的对象唯一。

public class Person {
    private String name;
    private int age;

    public Person() {
    }

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

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

    @Override
    public int hashCode() {

        return Objects.hash(name, age);
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

要求:同名同年龄的人,视为同一个人,只能存储一次,于是用HashSet的元素不可重复性,来实现,重写Person的hashCode()和equals()方法。相同姓名和年龄的让系统判别为同一个人。

  public static void main(String[] args) {
        //创建HashSet集合存储Person
        HashSet<Person> set = new HashSet<>();
        Person p1 = new Person("小美女",18);
        Person p2 = new Person("小美女",18);
        Person p3 = new Person("小美女",19);
        System.out.println(p1.hashCode());//1967205423
        System.out.println(p2.hashCode());//42121758

        System.out.println(p1==p2);//false
        System.out.println(p1.equals(p2));//false
        set.add(p1);
        set.add(p2);
        set.add(p3);
        System.out.println(set);//[Person{name='小美女', age=19}, Person{name='小美女', age=18}]
    }

 

LinkedHashSet

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

    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("www");
        set.add("abc");
        set.add("abc");
        set.add("bbb");
        System.out.println(set);//[abc, www, bbb] 无序,不允许重复

        LinkedHashSet<String> linked = new LinkedHashSet<>();
        linked.add("www");
        linked.add("abc");
        linked.add("abc");
        linked.add("bbb");
        System.out.println(linked);//[www, abc, bbb] 有序,不允许重复
    }

感谢关注

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值