Java小技能:快速创建List常用几种方式

简介: 集合的概念:- 在数学意义上的概念是: 对个数据放置在一起而建立起来的模型,这些数据类型可以不同;- 在软件中的定义,一堆数据放置在一个空间中存储,将整个存储空间称为集合。

引言

集合的概念:

  • 在数学意义上的概念是: 对个数据放置在一起而建立起来的模型,这些数据类型可以不同;
  • 在软件中的定义,一堆数据放置在一个空间中存储,将整个存储空间称为集合。

本文主要介绍collection接口下的List接口和Set接口,以及迭代器Iterator。


Collection是层次结构 中的根接口,JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和List)实现。

I Collection接口

1.1 collection的主要子接口和实现类

1.2 Collection的常用API

II List接口

list接口的实现类:ArrayList和LinkedList

2.1 ArrayList

原理:变长的数组
特性:

  1. 是顺序表,方便查找
  2. 每次扩容,集合的长度在原来长度上增加一半。
  3. 集合默认的空间为10.
  4. ArrayList 是非线程安全的
  5. 在集合的遍历过程中,不能使用ArrayList本身的方法删除和添加元素。
除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出ConcurrentModificationException

ArrayList 的常用API:

2.2 LinkedList

LinkedList的特点

  1. 底层使用List 接口的链接列表实现。方便删除和插入。
  2. 默认长度为0.
  3. LinkedList是非线程安全的。
  4. 在集合的遍历过程中,不能使用ArrayList本身的方法删除和添加元素。
除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出ConcurrentModificationException

2.3 补充:List的实现类 Vector

Vector 类可以实现可增长的对象数组,Vector的特性如下:

  1. 顺序表,方便查找
  2. 每次扩容在原长度上增加一倍。
  3. 默认大小为10
  4. Vector是线程安全。

2.4 快速创建List常用几种方式

  1. 常规操作: new ArrayList<>() 创建
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
  1. Arrays工具类创建

构造静态不变的 List:

List<String> excludeFields = Arrays.asList("secretKey","privateKey","publicKey");
//这种方式构造的 List 是固定长度的,如果调用 add 方法增加新的元素时会报异常 java.lang.UnsupportedOperationException。

如果想要改变可以通过 ArrayLis t进行包装成动态。

List<Integer> list = Arrays.asList(1, 2, 3);
list = new ArrayList<>(list);
list.add(4);
  1. Stream创建
List<Integer> list = Stream.of(1, 2, 3).collect(Collectors.toList());
  1. 匿名内部类创建
List<Integer> list= new ArrayList() {{
    add(1);
    add(2);
    add(3);
}};
  1. Hutool工具类创建
List<Integer> list = CollectionUtil.newArrayList(1, 2, 3);
  1. guava工具类创建
import com.google.common.collect.Lists;
 
List<Integer> list = Lists.newArrayList(1, 2, 3);
  1. JDK9 引入的Lists创建
List<Integer> list = Lists.newArrayList(1, 2, 3);
  1. JDK9引入 List.of (不可变)
List<Integer> list = List.of(1,2,3);

III 迭代器

3.1 迭代器的特点

  1. Iterator接口,本身是一种快速遍历集合的算法。
  2. 集合可以调用iterator方法获取迭代器。
  3. 迭代器是一个带有游标的线性表,用来记录集合的元素地址。

3.2 迭代器与集合的关系

关系草图

在这里插入图片描述

相关代码片

public class IteratorDemo{
    public static void main(String[] args){
        List l=new ArrayList();
        l.add("abc");
        l.add("123");
        l.add("中国");
        Iterator it=L.iterator();
    }
}

3.3 Iterator的常用API

在这里插入图片描述

IV Set接口

特点类似于数学集合,无顺序,不可重复,与List的特点相反,他只能有一个null值。
在这里讲讲他的实现类:HashSet,和TreeSet。

4.1 HashSet

基于哈希表的 Map 接口的实现,特点如下:

  1. 采用hash算法的Set,相当于hashMap的Key。
  2. 默认的容量为16,加载因子75%。
  3. HashSet非线程安全。
  4. 此实现不是同步的。
  5. 在集合的遍历过程中,不能使用ArrayList本身的方法删除和添加元素。
除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出ConcurrentModificationException

4.2 TreeSet

特点:

  1. 默认的空间为0
  2. 采用二叉树算法实现的
  3. 原理为TreeMap的Key
  4. 在集合的遍历过程中,不能使用ArrayList本身的方法删除和添加元素。
除非通过迭代器自身的 remove 或 add 方法从结构上对列表进行修改,否则在任何时间以任何方式对列表进行修改,迭代器都会抛出ConcurrentModificationException
  1. 按照自然排序存放元素

V 面试题

5.1 说出ArrayList和LinkedList的区别

  1. ArrayList和LinkedList都实现了List接口,但ArrayList采用动态数组的方式,而LinkedList采用双向链表的方式。

对于通过下标来访问元素时ArrayList效率较高而对于删除和插入操作LinkedList效率较高。

  1. LinkedList还实现了Queue和Deque接口,可以用作队列或栈,例如:
package com.csuinfosoft.grammer.ListDemo;
 
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
 
/**
 * 
 * @author iOS逆向
 * @date 上午8:32:37
 * ArrayList和LinedList都实现了List接口,但LinkedList还实现了Queue和Deque接口,
 * 可以用作队列和栈。(其中在jdk6.0,LinkedList才实现Deque接口)
 */
public class LinkedListOfqueue {
    public static void main(String[] args) {
        Queue queue=new LinkedList();
        //入队
        queue.offer("A");// boolean offer(E o) 如果可能,将指定的元素插入此队列 
        queue.offer("B");
        queue.offer("C");
        //出队
        System.out.println(queue.poll());// E poll() 检索并移除此队列的头,如果此队列为空,则返回 null。
        System.out.println(queue.poll());
        Deque stack=new LinkedList();
        //入栈
        stack.push("A");//void push(E e)将一个元素推入此双端队列所表示的堆栈(换句话说,此双端队列的头部),如果可以直接这样做而不违反容量限制的话;
        //如果成功,则返回 true,如果当前没有可用空间,则抛出 IllegalStateException。 
        stack.push("B");
        stack.push("C");
        //出栈
        System.out.println(stack.pop());// E pop() 从此双端队列所表示的堆栈中弹出一个元素。
        System.out.println(stack.pop());
    }
}
 queue=new LinkedList();
        //入队
        queue.offer("A");// boolean offer(E o) 如果可能,将指定的元素插入此队列 
        queue.offer("B");
        queue.offer("C");
        //出队
        System.out.println(queue.poll());// E poll() 检索并移除此队列的头,如果此队列为空,则返回 null。
        System.out.println(queue.poll());
        Deque stack=new LinkedList();
        //入栈
        stack.push("A");//void push(E e)将一个元素推入此双端队列所表示的堆栈(换句话说,此双端队列的头部),如果可以直接这样做而不违反容量限制的话;
        //如果成功,则返回 true,如果当前没有可用空间,则抛出 IllegalStateException。 
        stack.push("B");
        stack.push("C");
        //出栈
        System.out.println(stack.pop());// E pop() 从此双端队列所表示的堆栈中弹出一个元素。
        System.out.println(stack.pop());
    }
}

5.2 使用内部类来解决接口方法被替换的问题


解决方案:回调模式

package zx.callback;
public class Test {
 
    /**
     * @param args
     * @return void
     */
    public static void main(String[] args) {
          //实例化一个讲师
        TeacherPro2 pro=new TeacherPro2("kunnan");
        //作为程序员工作
        pro.work(); //调用继承的方法
        //作为老师工作
        pro.asTeacher().work();//使用内部类来解决接口方法被替换的问题
        //pro.asTeacher()由pro创建,pro.asTeacher()的work()方法调用了pro的teach方法。体现了回调功能。
    }
 
}
  1. Teacher接口
package zx.callback;
 
public interface Teacher {
   void work();//定义工作
}
  1. Programmer类
package zx.callback;
 
/**
 * 程序员
 * 
 * @author zhang_kn
 *
 */
public class Programmer {
    private String name;
 
    public Programmer() {
 
    }
 
    public Programmer(String name) {
        super();
        this.name = name;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public void work() {
        System.out.println("天天写代码,天天需求被改。。ios。");
    }
}
  1. TeacherPro2类
pro.asTeacher()由pro创建,pro.asTeacher()的work()方法调用了pro的teach方法。体现了回调功能。
package zx.callback;
 
public class TeacherPro2 extends Programmer {
    // 定义一个方法作为教师的职责授课,使用private修饰
    private void teach() {
        System.out.println("讲课。。。");
    }
    // 提供内部类,使用private修饰
    private class Coust implements Teacher {
        public void work() {//避免与TeacherPro2 继承的work方法重复
            teach();//执行教师的职责。使用TeacherPro2 的资源teach。体现了回调模式。
        }
    }
    public Teacher asTeacher() {//提供给外界获取包含老师功能的实现类的接口
        return new Coust();
    }
    
    public TeacherPro2() {
        super();
    }
    public TeacherPro2(String name) {
        super(name);
 
    }
}
目录
相关文章
|
3月前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。
|
3月前
|
Java
【Java集合类面试二十三】、List和Set有什么区别?
List和Set的主要区别在于List是一个有序且允许元素重复的集合,而Set是一个无序且元素不重复的集合。
|
3月前
|
存储 Java
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
|
3月前
|
安全 Java 调度
解锁Java并发编程高阶技能:深入剖析无锁CAS机制、揭秘魔法类Unsafe、精通原子包Atomic,打造高效并发应用
【8月更文挑战第4天】在Java并发编程中,无锁编程以高性能和低延迟应对高并发挑战。核心在于无锁CAS(Compare-And-Swap)机制,它基于硬件支持,确保原子性更新;Unsafe类提供底层内存操作,实现CAS;原子包java.util.concurrent.atomic封装了CAS操作,简化并发编程。通过`AtomicInteger`示例,展现了线程安全的自增操作,突显了这些技术在构建高效并发程序中的关键作用。
69 1
|
23天前
|
缓存 前端开发 JavaScript
9大高性能优化经验总结,Java高级岗必备技能,强烈建议收藏
关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。本文介绍了9种性能优化方法,涵盖代码优化、数据库优化、连接池调优、架构层面优化、分布式缓存、异步化、Web前端优化、服务化、硬件升级、搜索引擎和产品逻辑优化。欢迎留言交流。
|
25天前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
52 5
|
24天前
|
Java 程序员 编译器
Java|如何正确地在遍历 List 时删除元素
从源码分析如何正确地在遍历 List 时删除元素。为什么有的写法会导致异常,而另一些不会。
18 3
|
23天前
|
前端开发 Java API
过时Java技术的退役:这些技能你不再需要掌握!
【10月更文挑战第22天】 在快速变化的技术领域,一些曾经流行的Java技术已经逐渐被淘汰,不再适用于现代软件开发。了解这些过时的技术对于新手开发者来说尤为重要,以避免浪费时间和精力学习不再被行业所需的技能。本文将探讨一些已经或即将被淘汰的Java技术,帮助你调整学习路径,专注于那些更有价值的技术。
31 1
|
24天前
|
Java 程序员
Java|List.subList 踩坑小记
不应该仅凭印象和猜测,就开始使用一个方法,至少花一分钟认真读完它的官方注释文档。
20 1
|
22天前
|
存储 Java
在Java编程的世界里,标识符命名是一项基础且至关重要的技能
在Java编程的世界里,标识符命名是一项基础且至关重要的技能
10 0