【Java】集合(一)单列集合List

简介: 【Java】集合(一)单列集合List

1.集合

可以动态保存任意多个对象,并提供了一系列的操作对象的方法:add、remove、set、get等。

2.集合框架体系

分为两大类:

单列集合和双列集合

3.List接口基本介绍

List接口是Collection接口的子接口

List集合类中元素有序可重复支持索引,List容器中的元素都对应一个整数型的序号,可以根据序号存取容器中的元素。

List 集合里添加了一些根据索引来操作集合元素的方法

1) void add(int index,Obiect ele):在index位置插入ele元素

2)boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来

3)Object get(int index):获取指定index位置的元素

4)int indexof(Obiect obi):返回obi在集合中首次出现的位置

5)int lastlndexof(Obiect obi):返回obi在当前集合中未次出现的位置

6)Object remove(int index):移除指定index位置的元素,并返回此元素

7)Object set(int index, Object ele):设置指定index位置的元素为ele相当于是替换

8)List subList(int fromIndex, int tolndex):返回从fromIndex到tolndex位置的子集合

例子

List list=new ArrayList();
        //插入
        list.add(100);
        list.add(3);
        list.add("a");
         System.out.println(list);
        //删除
         list.remove(1);//默认按索引删除,索引从0开始
        list.remove(new Integer(100));//按指定元素删除,需要传入对象才行
        System.out.println(list);
        //修改
        list.set(0,"aaa");
        System.out.println(list);

List的三种遍历方式

方式一:使用iterator

Iterator iter=list.iterator();
        while(iter.hasNext()) {
          Object o=iter.next();
          System.out.println(o);
        }

方式二:使用增强for

for(Object o:list) {
           System.out.println(o);
         }

方式三:使用普通for

for(int i=0;i<list.size();i++) {
           Object o=list.get(i);
           System.out.println(o);
         }

4.ArrayList底层结构和源码分析

基本介绍:

1)ArrayList可以加入多个null

2)ArrayList是由数组实现数据存储的

3)ArrayList是线程不安全的,原因看源码没有synchronized

ArrayList底层操作机制源码分析

1)ArrayList中维护了一个Object类型的数组elementData。

transient Object[] elementData; //transient 表示瞬间,短暂的,表示该属性不会被序列号

2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第1次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData为1.5倍。

3)如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容则直接扩容elementData为1.5倍。

5.Vector底层结构和源码解剖

基本介绍:

1) Vector底层也是一个对象数组,protected Objectl] elementData;

2) Vector 是线程同步的,即线程安全,Vector类的操作方法带有synchronized

//1. new Vector() 底层
/*
public Vector() {
this(10);
}
补充:如果是 Vector vector = new Vector(8);
走的方法:
public Vector(int initialCapacity) {
this(initialCapacity, 0);
}
2. vector.add(i)
2.1 //下面这个方法就添加数据到 vector 集合
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
2.2 //确定是否需要扩容 条件 : minCapacity - elementData.length>0
private void ensureCapacityHelper(int minCapacity) {
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
2.3 //如果 需要的数组大小 不够用,就扩容 , 扩容的算法
//newCapacity = oldCapacity + ((capacityIncrement > 0) ?
//
capacityIncrement : oldCapacity);
//就是扩容两倍.
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
capacityIncrement : oldCapacity);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}

6.LinkedList底层结构

LinkedList的全面说明

1)LinkedList底层实现了双向链表和双端队列特点

2)可以添加任意元素(元素可以重复),包括null

3)线程不安全,没有实现同步

LinkedList的底层操作机制

1)LinkedList底层维护了一个双向链表

2) LinkedList中维护了两个属性first和last分别指向 首节点和尾节点

3)每个节点 (Node对象) ,里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表

4)所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高

5)模拟一个简单的双向链表

/* 1. LinkedList linkedList = new LinkedList();
public LinkedList() {}
2. 这时 linkeList 的属性 first = null last = null
3. 执行 添加
public boolean add(E e) {
linkLast(e);
return true;
}
4.将新的结点,加入到双向链表的最后
void linkLast(E e) {
final Node<E> l = last;
final Node<E> newNode = new Node<>(l, e, null);
last = newNode;
if (l == null)
first = newNode;
else
l.next = newNode;
size++;
modCount++;
}
*/
/* linkedList.remove(); // 这里默认删除的是第一个结点
1. 执行 removeFirst
public E remove() {
return removeFirst();
}
2. 执行
public E removeFirst() {
final Node<E> f = first;
if (f == null)
throw new NoSuchElementException();
return unlinkFirst(f);
}
3. 执行 unlinkFirst, 将 f 指向的双向链表的第一个结点拿掉
private E unlinkFirst(Node<E> f) {
// assert f == first && f != null;
final E element = f.item;
final Node<E> next = f.next;
f.item = null;
f.next = null; // help GC
first = next;
if (next == null)
last = null;
else
next.prev = null;
size--;
modCount++;
return element;
}
*/

目录
相关文章
|
6天前
|
存储 安全 Java
Java 集合框架中的老炮与新秀:HashTable 和 HashMap 谁更胜一筹?
嗨,大家好,我是技术伙伴小米。今天通过讲故事的方式,详细介绍 Java 中 HashMap 和 HashTable 的区别。从版本、线程安全、null 值支持、性能及迭代器行为等方面对比,帮助你轻松应对面试中的经典问题。HashMap 更高效灵活,适合单线程或需手动处理线程安全的场景;HashTable 较古老,线程安全但性能不佳。现代项目推荐使用 ConcurrentHashMap。关注我的公众号“软件求生”,获取更多技术干货!
28 3
|
23天前
|
存储 缓存 安全
Java 集合江湖:底层数据结构的大揭秘!
小米是一位热爱技术分享的程序员,本文详细解析了Java面试中常见的List、Set、Map的区别。不仅介绍了它们的基本特性和实现类,还深入探讨了各自的使用场景和面试技巧,帮助读者更好地理解和应对相关问题。
40 5
|
2月前
|
存储 缓存 安全
Java 集合框架优化:从基础到高级应用
《Java集合框架优化:从基础到高级应用》深入解析Java集合框架的核心原理与优化技巧,涵盖列表、集合、映射等常用数据结构,结合实际案例,指导开发者高效使用和优化Java集合。
45 4
|
2月前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
37 2
|
2月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
2月前
|
NoSQL Java Redis
List集合按照由小到大排序或者由大到小排序
List集合按照由小到大排序或者由大到小排序
50 0
|
2月前
|
存储 Java 开发者
Java中的集合框架深入解析
【10月更文挑战第32天】本文旨在为读者揭开Java集合框架的神秘面纱,通过深入浅出的方式介绍其内部结构与运作机制。我们将从集合框架的设计哲学出发,探讨其如何影响我们的编程实践,并配以代码示例,展示如何在真实场景中应用这些知识。无论你是Java新手还是资深开发者,这篇文章都将为你提供新的视角和实用技巧。
37 0
|
7月前
|
安全 Java
java线程之List集合并发安全问题及解决方案
java线程之List集合并发安全问题及解决方案
1070 1
|
6月前
|
Java API Apache
怎么在在 Java 中对List进行分区
本文介绍了如何将列表拆分为给定大小的子列表。尽管标准Java集合API未直接支持此功能,但Guava和Apache Commons Collections提供了相关API。
|
6月前
|
运维 关系型数据库 Java
PolarDB产品使用问题之使用List或Range分区表时,Java代码是否需要进行改动
PolarDB产品使用合集涵盖了从创建与管理、数据管理、性能优化与诊断、安全与合规到生态与集成、运维与支持等全方位的功能和服务,旨在帮助企业轻松构建高可用、高性能且易于管理的数据库环境,满足不同业务场景的需求。用户可以通过阿里云控制台、API、SDK等方式便捷地使用这些功能,实现数据库的高效运维与持续优化。