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

引言

集合的概念:

在数学意义上的概念是:对个数据放置在一起而建立起来的模型,这些数据类型可以不同;在软件中的定义,一堆数据放置在一个空间中存储,将整个存储空间称为集合。本文主要介绍collection接口下的List接口和Set接口,以及迭代器Iterator。

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

I Collection接口1.1 collection的主要子接口和实现类1.2 Collection的常用APIII List接口list接口的实现类:ArrayList和LinkedList

2.1 ArrayList原理:变长的数组 特性:

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

ArrayList 的常用API:

2.2 LinkedListLinkedList的特点

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

2.3 补充:List的实现类 VectorVector 类可以实现可增长的对象数组,Vector的特性如下:

顺序表,方便查找每次扩容在原长度上增加一倍。默认大小为10Vector是线程安全。2.4 快速创建List常用几种方式常规操作: new ArrayList<>()创建代码语言:javascript复制List list = new ArrayList<>();

list.add(1);

list.add(2);

Arrays工具类创建构造静态不变的 List:

代码语言:javascript复制List excludeFields = Arrays.asList("secretKey","privateKey","publicKey");

//这种方式构造的 List 是固定长度的,如果调用 add 方法增加新的元素时会报异常 java.lang.UnsupportedOperationException。

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

代码语言:javascript复制List list = Arrays.asList(1, 2, 3);

list = new ArrayList<>(list);

list.add(4);

Stream创建代码语言:javascript复制List list = Stream.of(1, 2, 3).collect(Collectors.toList());

匿名内部类创建代码语言:javascript复制List list= new ArrayList() {{

add(1);

add(2);

add(3);

}};

Hutool工具类创建代码语言:javascript复制List list = CollectionUtil.newArrayList(1, 2, 3);

guava工具类创建代码语言:javascript复制import com.google.common.collect.Lists;

List list = Lists.newArrayList(1, 2, 3);

JDK9 引入的Lists创建代码语言:javascript复制List list = Lists.newArrayList(1, 2, 3);

JDK9引入 List.of (不可变)代码语言:javascript复制List list = List.of(1,2,3);

III 迭代器3.1 迭代器的特点Iterator接口,本身是一种快速遍历集合的算法。集合可以调用iterator方法获取迭代器。迭代器是一个带有游标的线性表,用来记录集合的元素地址。3.2 迭代器与集合的关系关系草图

在这里插入图片描述

相关代码片

代码语言:javascript复制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 接口的实现,特点如下:

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

4.2 TreeSet特点:

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

按照自然排序存放元素V 面试题5.1 说出ArrayList和LinkedList的区别ArrayList和LinkedList都实现了List接口,但ArrayList采用动态数组的方式,而LinkedList采用双向链表的方式。对于通过下标来访问元素时ArrayList效率较高而对于删除和插入操作LinkedList效率较高。LinkedList还实现了Queue和Deque接口,可以用作队列或栈,例如:代码语言:javascript复制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 使用内部类来解决接口方法被替换的问题解决方案:回调模式

代码语言:javascript复制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方法。体现了回调功能。

}

}

Teacher接口代码语言:javascript复制package zx.callback;

public interface Teacher {

void work();//定义工作

}

Programmer类代码语言:javascript复制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。");

}

}

TeacherPro2类pro.asTeacher()由pro创建,pro.asTeacher()的work()方法调用了pro的teach方法。体现了回调功能。

代码语言:javascript复制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);

}

}