List集合与Set集合(ArrayList,LinkedList,Vector,HashSet,LinkedHashSet,可变参数)

简介: List集合介绍及常用方法 import java.util.ArrayList; import java.util.Iterator; import java.util.List; /* java.util.List接口 extends Collection接口 List接口的特点: 1.有序的集

List集合介绍及常用方法


import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/*
java.util.List接口 extends Collection接口
List接口的特点:
    1.有序的集合,存储元素和取出元素的顺序是一致的(存储123 取出123)
    2.有索引,包含了一些带索引的方法
    3.允许存储重复的元素
List接口中带索引的方法(特有)
    -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:字符串索引越界异常
 */
public class Demo01List {
    public static void main(String[] args) {
        //创建一个List集合对象,多态
        List<String> list = new ArrayList<>();
        //使用add方法往集合中添加元素
        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方法
        //public void add(int index, E element):将指定的元素,添加到该集合中的指定位置上
        //在c和d之间添加一个itheima
        list.add(3,"itheima");
        System.out.println(list);
        //public E remove(int index):移除列表中指定位置的元素,返回的是被移除的元素
        //移除元素
        String removeE = list.remove(2);
        System.out.println("被移除的元素:"+removeE);//被移除的元素:c
        System.out.println(list);//[a, b, itheima, d, a]
        //public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前元素
        //把最后一个a,替换为A
        String setE = list.set(4,"A");
        System.out.println("被替换的元素:"+setE);//被替换的元素:a
        System.out.println(list);//[a, b, itheima, d, A]
        //List集合遍历有3种方式
        //使用普通的for循环
        for (int i = 0; i < list.size(); i++) {
            //public E get(int index):返回集合中指定位置的元素
            String s = list.get(i);
            System.out.println(s);
        }
        System.out.println("==============================================");
        //使用迭代器
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);
        }
        System.out.println("===============================================");
        //使用增强for
        for (String s : list) {
            System.out.println(s);
        }
        String r = list.get(5);
        System.out.println(r);//IndexOutOfBoundsException
    }
}


ArrayList集合


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


LinkedList集合


import java.util.LinkedList;
/*
java.util.LinkedList集合  implements  List接口
LinkedList集合的特点:
    1.底层是一个链表结构:查询慢,增删快
    2.里边包含了大量操作首尾元素的方法
    注意:使用LinkedList集合特有的方法,不能使用多态
    - public void addFirst(E e):将指定元素插入此列表的开头
    - public void addLast(E e):将指定元素添加到此列表的结尾
    - public void push(E e):将元素推入此列表所表示的堆栈
    - public E getFirst():返回此列表的第一个元素
    - public E getLast():返回此列表的最后一个元素
    - public E removeFirst():移除并返回此列表的第一个元素
    - public E removeLast():移除并返回此列表的最后一个元素
    - public E pop():从此列表所表示的堆栈处弹出一个元素
    - public boolean isEmpty():如果列表不包含元素,则返回true
 */
public class Demo02LinkedList {
    public static void main(String[] args) {
        show01();
        show02();
        show03();
    }
    /*
    - public E removeFirst():移除并返回此列表的第一个元素
    - public E removeLast():移除并返回此列表的最后一个元素
    - public E pop():从此列表所表示的堆栈处弹出一个元素。此方法相当于removeFirst()
     */
    private static void show03() {
        //创建LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        System.out.println(linked);
        //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]
    }
    /*
    - public E getFirst():返回此列表的第一个元素
    - public E getLast():返回此列表的最后一个元素
     */
    private static void show02() {
        //创建LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        //linked.clear();//清空集合中的元素   再获取集合中的元素会抛出NoSuchElementException
        //public boolean isEmpty():如果列表不包含元素,则返回true
        if (!linked.isEmpty()){
            String first = linked.getFirst();
            System.out.println(first);//a
            String last = linked.getLast();
            System.out.println(last);//c
        }
    }
    /*
    - public void addFirst(E e):将指定元素插入此列表的开头
    - public void addLast(E e):将指定元素添加到此列表的结尾
    - public void push(E e):将元素推入此列表所表示的堆栈。此方法等效于addFirst(E)。
     */
    private static void show01() {
        //创建LinkedList集合对象
        LinkedList<String> linked = new LinkedList<>();
        //使用add方法往集合中添加元素
        linked.add("a");
        linked.add("b");
        linked.add("c");
        System.out.println(linked);//[a, b, c]
        //public void addFirst(E e):将指定元素插入此列表的开头
        //linked.addFirst("www");
        linked.push("www");//[www, a, b, c]
        System.out.println(linked);//[www, a, b, c]
        //public void addLast(E e):将指定元素添加到此列表的结尾。此方法等效于add()
        linked.addLast("com");
        System.out.println(linked);//[www, a, b, c, com]
    }
}


Vector集合


与ArrayList集合类似,底层是数组,但是是单线程同步的,速度要慢


HashSet


HashSet集合介绍

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*
java.util.Set接口 extends Collection接口
Set接口的特点:
    1.不允许存储重复的元素
    2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
java.util.HashSet集合 implements Set接口
HashSet特点:
    1.不允许存储重复的元素
    2.没有索引,没有带索引的方法,也不能使用普通的for循环遍历
    3.是一个无序的集合,存储元素和取出元素的顺序有可能不一致
    4.底层是一个哈希表结构(查询速度非常快)
 */
public class Demo01Set {
    public static void main(String[] args) {
        Set<Integer> set = new HashSet<>();
        //使用add方法往集合中添加元素
        set.add(1);
        set.add(3);
        set.add(2);
        set.add(1);
        //使用迭代器遍历set集合
        Iterator<Integer> it = set.iterator();
        while (it.hasNext()){
            Integer n = it.next();
            System.out.println(n);//1,2,3
        }
        //使用增强for遍历set集合
        System.out.println("======================================");
        for (Integer i : set) {
            System.out.println(i);//1,2,3
        }
    }
}


哈希值


public class Person extends Object{
    //重写hashCode方法
    @Override
    public int hashCode() {
        return 1;
    }
}
======================================================
/*
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到的地址,不是数据实际存储的物理地址)
在Object类有一个方法,可以获取对象的哈希值
int hashCode() 返回该对象的哈希码值
hashCode方法的源码:
    public native int hashCode();
    native:代表该方法调用的是本地操作系统的方法
 */
public class Demo01HashCode {
    public static void main(String[] args) {
        //Person类继承了Object类,所以可以使用Object类的hashCode方法
        Person p1 = new Person();
        int h1 = p1.hashCode();
        System.out.println(h1);//460141958      |1
        Person p2 = new Person();
        int h2 = p2.hashCode();
        System.out.println(h2);//1163157884     |1
        /*
        toString方法的源码:
            return getClass().getName() + "@" + Integer.toHexString(hashCode());
         */
        System.out.println(p1);//com.collection.demo03_hashCode.Person@1b6d3586
        System.out.println(p2);//com.collection.demo03_hashCode.Person@4554617c
        System.out.println(p1==p2);//false
        /*
        String类的哈希值
            String类重写了Object类的hashCode方法
         */
        String s1 = new String("abc");
        String s2 = new String("abc");
        System.out.println(s1.hashCode());//96354
        System.out.println(s2.hashCode());//96354
        System.out.println("重地".hashCode());//1179395
        System.out.println("通话".hashCode());//1179395
    }
}


HashSet集合存储数据的结构


微信图片_20220426131219.png


Set集合存储元素不重复的原理


微信图片_20220426131223.png


HashSet存储自定义类型元素


import java.util.HashSet;
/*
HashSet存储自定义类型元素
Set集合保证元素唯一:
    存储的元素(String,Integer,...Student,Person...),必须重写hashCode方法和equals方法
要求:
    同名同年龄的人,视为同一个人,只能存储一次
 */
public class Demo03HashSetSavePerson {
    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());//460141958
        System.out.println(p2.hashCode());//1163157884
        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);
    }
}
=========================================================
import java.util.Objects;
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;
    }
}


LinkedHashSet集合


import java.util.HashSet;
import java.util.LinkedHashSet;
/*
java.util.LinkedHashSet集合 extends HashSet集合
LinkedHashSet集合特点:
    底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序
 */
public class Demo04LinkedHashSet {
    public static void main(String[] args) {
        HashSet<String> set = new HashSet<>();
        set.add("www");
        set.add("abc");
        set.add("abc");
        set.add("itcast");
        System.out.println(set);//[abc, www, itcast]无序,不允许重复
        LinkedHashSet<String> linked = new LinkedHashSet<>();
        linked.add("www");
        linked.add("abc");
        linked.add("abc");
        linked.add("itcast");
        System.out.println(linked);//[www, abc, itcast]有序,不允许重复
    }
}


可变参数


/*
可变参数:是JDK1.5之后出现的新特性
使用前提:
    当方法的参数列表数据类型已经确定但是参数的个数不确定,就可以使用可变参数
使用格式:定义方法时使用
    修饰符 返回值类型   方法名(数据类型...变量名){}
可变参数的原理:
    可变参数底层就是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
    传递的参数个数,可以是0个(不传递),1,2...多个
 */
public class Demo01VarArgs {
    public static void main(String[] args) {
        //int i = add();
        //int i = add(10);
        int i = add(10,20);
        //int i = add(10,20,30,40,50,60,70,80,90,100);
        System.out.println(i);
        method("abc",5.5,10,1,2,3,4);
    }
    /*
    可变参数的注意事项
        1.一个方法的参数列表,只能有一个可变参数
        2.如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
     */
    /*public static void method(int...a,String...b){
    }*/
    /*public static void method(String b,double c,int d,int...a){
    }*/
    //可变参数的特殊(终极)写法
    public static void method(Object...obj){
    }
    /*
    定义计算(0-n)整数和的方法
    已知:计算整数的和,数据类型已经确定int
    但是参数的个数不确定,不知道要计算几个整数的和,就可以使用可变参数
    add();就会创建一个长度为0的数组,new int[0]
    add(10);就会创建一个长度为1的数组,存储传递过来的参数,new int[]{10};
    add(10,20);就会创建一个长度为2的数组,存储传递过来的参数,new int[]{10,20};
    add(10,20,20,40,50,60,70,80,90,100);就会创建一个长度为10的数组,存储传递过来的参数,new int[]{10,20,20,40,50,60,70,80,90,100};
     */
    public static int add(int...arr){
        //System.out.println(arr);//[I@1b6d3586 int类型数组的地址,底层是一个数组
        //System.out.println(arr.length);//0,1,2,10
        //定义一个初始化的变量,记录累加求和
        int sum = 0;
        //遍历数组,获取数组中的每一个元素
        for (int i : arr) {
            //累加求和
            sum += i;
        }
        //return 0;
        //把求和返回
        return sum;
    }
    //定义一个方法,计算三个int类型整数的和
    //public static int add(int a,int b,int c){
    //    return a+b+c;
    //}
    //定义一个方法,计算两个int类型整数的和
    //public static int add(int a,int b){
    //    return a+b;
    //}
}


相关文章
|
2月前
|
存储 NoSQL 关系型数据库
Redis 集合(Set)
10月更文挑战第17天
42 5
|
1月前
set集合
HashSet(无序,唯一): 基于 HashMap 实现的,底层采用 HashMap 来保存元素。 LinkedHashSet: LinkedHashSet 是 HashSet 的子类,并且其内部是通过 LinkedHashMap 来实现的。 TreeSet(有序,唯一): 红黑树(自平衡的排序二叉树)。
|
1月前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
1月前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
1月前
|
Java 开发者
|
18天前
|
算法
你对Collection中Set、List、Map理解?
你对Collection中Set、List、Map理解?
53 18
你对Collection中Set、List、Map理解?
|
12天前
|
存储 缓存 安全
只会“有序无序”?面试官嫌弃的List、Set、Map回答!
小米,一位热衷于技术分享的程序员,通过与朋友小林的对话,详细解析了Java面试中常见的List、Set、Map三者之间的区别,不仅涵盖了它们的基本特性,还深入探讨了各自的实现原理及应用场景,帮助面试者更好地准备相关问题。
49 20
|
29天前
|
存储 C++ 容器
【C++】map、set基本用法
本文介绍了C++ STL中的`map`和`set`两种关联容器。`map`用于存储键值对,每个键唯一;而`set`存储唯一元素,不包含值。两者均基于红黑树实现,支持高效的查找、插入和删除操作。文中详细列举了它们的构造方法、迭代器、容量检查、元素修改等常用接口,并简要对比了`map`与`set`的主要差异。此外,还介绍了允许重复元素的`multiset`和`multimap`。
30 3
【C++】map、set基本用法
|
29天前
|
存储 算法 C++
【C++】unordered_map(set)
C++中的`unordered`容器(如`std::unordered_set`、`std::unordered_map`)基于哈希表实现,提供高效的查找、插入和删除操作。哈希表通过哈希函数将元素映射到特定的“桶”中,每个桶可存储一个或多个元素,以处理哈希冲突。主要组成部分包括哈希表、哈希函数、冲突处理机制、负载因子和再散列,以及迭代器。哈希函数用于计算元素的哈希值,冲突通过开链法解决,负载因子控制哈希表的扩展。迭代器支持遍历容器中的元素。`unordered_map`和`unordered_set`的插入、查找和删除操作在理想情况下时间复杂度为O(1),但在冲突较多时可能退化为O(n)。
22 5
|
2月前
|
存储 JavaScript 前端开发
Set、Map、WeakSet 和 WeakMap 的区别
在 JavaScript 中,Set 和 Map 用于存储唯一值和键值对,支持多种操作方法,如添加、删除和检查元素。WeakSet 和 WeakMap 则存储弱引用的对象,有助于防止内存泄漏,适合特定场景使用。