List集合、Set集合、可变参数

1、List集合

1.1、List接口介绍

java.util.List接口继承自Collection接口,是单列集合的一个重要分支,习惯性的将实现了List接口的对象称为List集合。在List集合中允许出现重复的元素,所有的元素是以一种线性方式进行存储的,在程序中可以通过索引来访问集合中的指定元素,另外,List集合还有一个特点就是有序,即元素的存入顺序和取出顺序一致。

1.2、List接口中常用方法

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

  1. public void add(int index, E element):将指定的元素,添加到集合中指定的位置上
  2. public E get(int index):返回集合中指定位置上的元素
  3. public E remove(int index):移除列表中指定位置上的元素,返回的是被移除的元素
  4. public E set(int index,E element):用指定的元素替换集合中指定位置上的元素,返回值是更新前的元素。

1.3、List的实现类—ArrayList集合

java.uitl.ArrayList集合数据存储的结构是数组结构,而且是一个动态的数组,数组的容量会随着集合中元素的个数,自动的扩大或缩小。

  1. 添加到ArrayList集合中的元素,都会有一个整数的序号(索引、下标)从0开始
  2. 查找元素快,根据索引快速定位
  3. 增,删元素慢,因为添加一个或删除一个元素,都要把该位置以后的元素进行索引的调整。
  4. 日常开发中它是使用最多的一个用来查询的集合类。
package com.bdit;

import java.util.ArrayList;
import java.util.Iterator;

public class Test1 {
    
    
    public static void main(String[] args) {
    
    
        ArrayList<String> list=new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("c");
        list.add("d");
        list.add(0,"wangwu");
        list.add("a");
        //迭代
        Iterator<String> it=list.iterator();
        while(it.hasNext()){
    
    
            System.out.println(it.next());
        }
        list.set(0,"李四");
        list.remove(0);
        System.out.println("================================");
        for(int i=0;i<list.size();i++){
    
    
            System.out.println(list.get(i));
        }
    }
}

1.4 LinkedList集合

java.util.LinkedList集合数据存储的结构是链表结构,方便元素添加,删除的集合
LinkedList是一个双向链表结构的集合

实际开发中一个集合元素的添加与删除经常涉及到首尾操作,而LinkedList提供了大量首尾操作的方法:

package com.bdit;

import java.util.LinkedList;

public class Test2 {
    
    
    public static void main(String[] args) {
    
    
        LinkedList<String> list=new LinkedList<>();
        list.push("a");
        list.push("b");
        list.push("c");
        list.push("d");
        list.push("e");
        System.out.println("-----------"+list.pollFirst());
        System.out.println("===================================");
        for(int i=0;i<list.size();i++){
    
    
            System.out.println(list.get(i));
        }

    }
}

2、Set接口

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

2.1、HashSet集合

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

package com.bdit;

import java.util.HashSet;
import java.util.Iterator;

/*
HashSet
 */
public class Test4 {
    
    
    public static void main(String[] args) {
    
    
        HashSet<String> hs=new HashSet<>();
        hs.add("zhangsan");
        hs.add("lisi");
        hs.add("wangwu");
        hs.add("zhangsan");
        Iterator<String> it=hs.iterator();
        while(it.hasNext()){
    
    
            System.out.println(it.next());
        }
        System.out.println("===============================");
        for(String s:hs){
    
    
            System.out.println(s);
        }
    }
}

2.2、HashSet集合存储数据的结构(哈希表)

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

往set集合储存数据时,会调用它们的hashCode方法,获得哈希码值,然后通过固定的算法获取这个元素储存的内存地址,set采用的是哈希表的方式储存数据的如果这个内存地址已经有元素,便会调用equals方法和内容进行对比,如果一直便会直接使用已存在的,如果不一致,便会进行散列存放。

package com.bdit;

import java.util.HashSet;

/*
HashSet存放自定义对象
 */
public class Test5 {
    
    
    public static void main(String[] args) {
    
    
        HashSet<Student> hs=new HashSet<>();
        hs.add(new Student(1001,"zhangsan"));
        hs.add(new Student(1001,"zhangsan"));
        hs.add(new Student(1001,"zhangsan"));
        hs.add(new Student(1001,"zhangsan"));
        for(Student stu:hs){
    
    
            System.out.println(stu);
        }
    }
}

package com.bdit;

import java.util.Objects;

public class Student {
    
    
    private int id;
    private String name;

    public Student(){
    
    

    }

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

    public int getId() {
    
    
        return id;
    }

    public void setId(int id) {
    
    
        this.id = id;
    }

    public String getName() {
    
    
        return name;
    }

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

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

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

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

【如果两个对象相同,则他们的hashCode值就一定相同;但是两个对象的hashCode值相同,但是这两个对象不一定相同】

2.3、LinkedHashSet

HashSet是元素无序的,如果说我们想要Set集合存储的元素时有序的呢?
在HashSet下面有一个类java.util.LinkedHashSet,它可以记录元素存储的顺序,并且能够按照所记录的顺序进行输出。

package com.bdit;

import java.util.HashSet;
import java.util.LinkedHashSet;

/*

 */
public class Test6 {
    
    
    public static void main(String[] args) {
    
    
        LinkedHashSet<String> set=new LinkedHashSet<>();
        set.add("a");
        set.add("b");
        set.add("c");
        set.add("d");
        set.add("d");
        for(String s:set){
    
    
            System.out.println(s);
        }

    }
}

3、可变参数

在JDK5.0以后,如果我们定义一个方法需要接收多个参数,并且多个参数类型一致,我们可以对其简化成如下格式:

修饰符 返回值类型 方法名(参数类型… 参数名){
    
    

}

其实这个格式等价于:

修饰符 返回值类型 方法名(参数类型[] 数组名){
    
    

}

只是后面这种定义,在调用时必须传递数组,而前者可以直接传递数据即可。
JDK1.5后,出现的这种简化操作,…用在参数上,称为可变参数。

package com.bdit;
/*
可变参数
 */
public class Test7 {
    
    
    public static void main(String[] args) {
    
    
        display(7,8,9,1,7,5,6,3);
    }

    public static void display(int... nums){
    
    
        for(int n:nums){
    
    
            System.out.println(n);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/vlucky_long/article/details/108588630