快速掌握Java中List和Set接口的基本使用

简介: 快速掌握Java中List和Set接口的基本使用

集合的概念


是一个工具类,作用为存储多个数据,通常用于替代数组


集合的特点


只能存放Object对象

只能存放引用类型

不能存放接口,只能存放接口实现类对象

来自java.util包

List接口


List的存储特点


有序、有下标、元素可以重复

常用实现类

ArrayList 最常用

JDK1.2 底层数组实现 查询快、增删慢 线程不安全,效率高

一般不用

JDK1.2 底层链表实现 增删快,查询慢 线程不安全,效率高

Vector 不用

JDK1.0 底层数组实现 都慢 线程安全,效率低

创建


通常使用多态


List 集合名=new 实现类名();


常用方法


集合名.方法名


boolean add(元素):将元素添加至集合末尾

void add(下标,元素):将元素添加至指定下标位置

boolean addAll(集合名):将指定集合所有元素添加至当前集合末尾

boolean addAll(下标,集合名):将指定集合所有元素添加至当前集合指定下标位置

void clear():清空集合元素

int size():获取集合长度

boolean contains(元素):判断集合中是否包含指定元素

boolean containsAll(集合名):判断集合中是否包含指定集合的所有元素

元素 get(下标):获取指定下标位置上的元素

int indexOf(元素):获取指定元素第一次出现的下标,不存在返回-1

int lastIndexOf(元素):获取指定元素最后一次出现的下标,不存在返回-1

boolean isEmpty():判断集合元素是否为空,不能判比null值

元素 remove(下标):移除指定下标的元素,返回该元素

元素 set(下标,新值):将指定下标位置的值替换为新值,返回旧值

void sort(比较器实现类对象):对集合元素按照指定规则排序

Object[] toArray():将集合转换为数组


代码示例


public class Test {
        public static void main(String[] args) {
            List list = new ArrayList();
            list.add(66);
            list.add(5);
            list.add(77);//66 5 77
            list.add(2,44);//66 5 44 77
            List list2 = new ArrayList();
            list2.add(2);
            list2.add(1);
            list.addAll(list2);//66 5 44 77 2 1
            list.addAll(1, list2);//66 2 1 5 44 77 2 1
            System.out.println("清空之前:"+list.size());
           // list.clear();
           // System.out.println("清空之后:"+list.size());
            System.out.println(list.contains(5));//t
            System.out.println(list.containsAll(list2));//t
            List list3 = new ArrayList();
            list3.add(66);
            list3.add(77);
            list3.add(88);
            System.out.println(list.containsAll(list3));//f
            System.out.println(list.get(3));//5
            System.out.println(list.indexOf(88));//-1
            System.out.println(list.lastIndexOf(2));//6
            //list.clear();
            System.out.println(list.isEmpty());
            List list4=null;
            //System.out.println(list4.isEmpty()); 空指针异常
            System.out.println(list.remove(3));//66 2 1 44 77 2 1
            // System.out.println(list.remove(2));
            list.set(1, 88);//66 88 1 44 77 2 1
            Object[] os=list.toArray();
            for(int i=0;i<os.length;i++){
                System.out.print(os[i]+" ");
            }
            System.out.println();
        }
    }


遍历方法


for+get()
 for (int i = 0; i < 集合名.size(); i++) {
       //i代表当前下标
       //通过集合名.get(i)的方式获取当前元素
   }
   如:
 for (int i = 0; i < list.size(); i++) {
        System.out.print(list.get(i)+" ");
         }
        System.out.println();


迭代器遍历

hasNext():判断是否存在下一元素
next():指针后移,获取下一元素
//获取迭代器对象
Iterator it=集合名.iterator();
while(it.hasNext()){//集合存在下一元素则继续后续操作
//通过it.next()使指针后移,得到元素
}
如:
Iterator it=list.iterator();
while(it.hasNext()){
System.out.print(it.next()+" ");
}
System.out.println();
tips:迭代过程中不允许对集合进行增删操作
外遍历forEach
for(数据类型 元素名(随便起) : 集合名){
//元素名就代表当前元素
}
如:
for (Object o: list) {
System.out.print(o+" ");
}
System.out.println();
本质也是迭代器遍历,内部不允许进行增删操作
JDK5.0
自遍历forEach
//匿名内部类
集合名.forEach(new Consumer() {
@Override
public void accept(Object o) {
//o就代表当前元素
}
});
 //lambda简化
         集合名.forEach(o-> {o就代表当前元素});
 如:
         list.forEach(new Consumer() {
             @Override
             public void accept(Object o) {
                 System.out.print(o + " ");
             }
         });
         System.out.println();
         // lambda
         list.forEach(o-> System.out.print(o+" "));


JDK8.0

泛型

作用


用于集合中,可以约束集合存储的数据类型


语法


List<数据类型> 集合名=new 实现类名<数据类型>();

1

使用


1. 如果集合中存放基本类型,则泛型必须声明为其包装类型

2. 声明泛型之后,集合中不允许存放其他类型的数据

3. 前后类型声明必须一致

4. 等号后边的泛型不声明,语法不规范

5. 等号前边的泛型不声明,泛型无意义


List<Integer> list = new ArrayList<Integer>();
        list.add(66);
        list.add(88);
       /* list.add("abc");
        list.add(5.5);*/
        list.forEach(new Consumer<Integer>() {
            @Override
            public void accept(Integer i) {
                System.out.println(i);
            }
        });


Set接口

Collection


是一个接口

是List和Set的父接口

所有集合都由Collection或Map派生

特点


存放着List和Set的共有方法

没有自己的直接实现类

Set的存储特点

无序、无下标、元素不可重复

常用实现类

HashSet

JDK1.2 底层哈希表实现(数组+链表 又名散列表) 线程不安全,效率高

LinkedHashSet

JDK1.2 是HashSet的子类,底层哈希表实现 线程不安全,效率高

TreeSet

JDK1.2 是SortedSet的实现类,底层红黑树实现 线程不安全,效率高

创建


利用多态


Set<泛型类型> 集合名 = new 实现类名<泛型类型>();


常用方法


全部继承自Collection

遍历方法

Iterator迭代器遍历

外遍历forEach

自遍历forEach

哈希表的去重过程


先通过调用元素的hashCode()方法得到哈希码值

然后通过哈希码值%数组长度得到存放下标

若该下标位置未存放元素,则直接存放

若已存有元素,则调用当前元素的equals()方法与其位置的所有元素进行值的比较

都不相同,则链表存放

若有相同,舍弃当前元素


注意事项

当集合中存放的为自定义类型时,必须重写hashCode和equals才能保证去重

LinkedHashSet能够保证元素存入和取出顺序一致

TreeSet可以实现对元素进行默认的升序排序

如果存放的为自定义类型,必须重写排序规则

两种排序方式:

实现Comparable接口,重写compareTo方法

要对谁排,就让谁实现

原理:让当前对象与参数对象进行比较

返回值规则:

从小到大:this的值>o的值,返回正数

从大到小:this的值>o的值,返回负数

相等返回0

实现Comparator接口,重写compare方法

在集合创建处的小括号内传入该接口的实现类对象


 

public class Test2 {
            public static void main(String[] args) {
                Set<Student> set = new TreeSet<Student>(new Comparator<Student>() {
                    @Override
                    public int compare(Student o1, Student o2) {
                        //根据学生年龄从大到小排序
                        return o2.getAge()-o1.getAge();
                    }
                });
                set.add(new Student("张三", 20));
                set.add(new Student("lisi", 21));
                set.add(new Student("lisi", 21));
                set.add(new Student("wangwu", 22));
                set.add(new Student("maliu", 19));
                set.forEach(s-> System.out.println(s));
            }
        }


默认识别第一种排序方式

第二种排序方式优先级高于第一种

List和set的区别

基本概念的区别

List 接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序的对象。


Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。


1.Set 接口实例存储的是无序的, 不重复的数据, List 接口实例存储的是有序的,可以重复的元素;

2.Set检索效率低下, 删除和插入效率高, 插入和删除不会引起元素位置改变

3.List和数组类似, 可以动态增长, 根据实际存储的数据的长度自动增长List的长度, 查找元素效率高, 插入删除效率低, 因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> ;

使用场景

List


常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。

set


Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。

相关文章
|
消息中间件 缓存 前端开发
从资损百万到零事故:Java 接口幂等设计的艺术与实践
在分布式系统中,重复请求常引发严重资损,如支付双扣、库存超卖等问题,其根源在于接口缺乏幂等性设计。本文通过真实案例揭示幂等性的重要性,并详解8种主流解决方案,涵盖唯一请求ID、乐观锁、悲观锁、状态机等,帮助开发者构建稳定系统,保障业务一致性。无论你是架构师还是开发工程师,都能从中获得实战指导,有效规避重复调用带来的风险。
1331 2
|
数据采集 JSON Java
Java爬虫获取1688店铺所有商品接口数据实战指南
本文介绍如何使用Java爬虫技术高效获取1688店铺商品信息,涵盖环境搭建、API调用、签名生成及数据抓取全流程,并附完整代码示例,助力市场分析与选品决策。
|
12月前
|
算法 安全 Java
除了类,Java中的接口和方法也可以使用泛型吗?
除了类,Java中的接口和方法也可以使用泛型吗?
302 11
|
11月前
|
Java Go 开发工具
【Java】(9)抽象类、接口、内部的运用与作用分析,枚举类型的使用
抽象类必须使用abstract修饰符来修饰,抽象方法也必须使用abstract修饰符来修饰,抽象方法不能有方法体。抽象类不能被实例化,无法使用new关键字来调用抽象类的构造器创建抽象类的实例。抽象类可以包含成员变量、方法(普通方法和抽象方法都可以)、构造器、初始化块、内部类(接 口、枚举)5种成分。抽象类的构造器不能用于创建实例,主要是用于被其子类调用。抽象类中不一定包含抽象方法,但是有抽象方法的类必定是抽象类abstract static不能同时修饰一个方法。
399 1
|
存储 缓存 安全
Java集合框架(二):Set接口与哈希表原理
本文深入解析Java中Set集合的工作原理及其实现机制,涵盖HashSet、LinkedHashSet和TreeSet三大实现类。从Set接口的特性出发,对比List理解去重机制,并详解哈希表原理、hashCode与equals方法的作用。进一步剖析HashSet的底层HashMap实现、LinkedHashSet的双向链表维护顺序特性,以及TreeSet基于红黑树的排序功能。文章还包含性能对比、自定义对象去重、集合运算实战和线程安全方案,帮助读者全面掌握Set的应用与选择策略。
1444 23
|
安全 Java 开发者
Java集合框架:详解Deque接口的栈操作方法全集
理解和掌握这些方法对于实现像浏览器后退功能这样的栈操作来说至关重要,它们能够帮助开发者编写既高效又稳定的应用程序。此外,在多线程环境中想保证线程安全,可以考虑使用ConcurrentLinkedDeque,它是Deque的线程安全版本,尽管它并未直接实现栈操作的方法,但是Deque的接口方法可以相对应地使用。
568 12
|
存储 安全 Java
Java集合框架(一):List接口及其实现类剖析
本文深入解析Java中List集合的实现原理,涵盖ArrayList的动态数组机制、LinkedList的链表结构、Vector与Stack的线程安全性及其不推荐使用的原因,对比了不同实现的性能与适用场景,帮助开发者根据实际需求选择合适的List实现。
1333 0
|
Java API 网络架构
java调用api接口自动判断节假日信息
java调用api接口自动判断节假日信息
3947 0
|
安全 Java API
Java 抽象类与接口在 Java17 + 开发中的现代应用实践解析
《Java抽象类与接口核心技术解析》 摘要:本文全面剖析Java抽象类与接口的核心概念与技术差异。抽象类通过模板设计实现代码复用,支持具体方法与状态管理;接口则定义行为规范,实现多态支持。文章详细对比了两者在实例化、方法实现、继承机制等方面的区别,并提供了模板方法模式(抽象类)和策略模式(接口)的典型应用示例。特别指出Java8+新特性为接口带来的灵活性提升,包括默认方法和静态方法。最后给出最佳实践建议:优先使用接口定义行为规范,通过抽象类实现代码复用,合理组合两者构建灵活架构。
504 2