集合
- 概念:存储数据的容器,可变(长度、类型),存储的是对象引用地址(),不能存基本数据类型
一、Collection
-
java集合的主要分为两大类,如图所示(非常重要)
-
集合主要是两组(单列集合、双列集合)
Collection 接口有两个重要的子接口 List 、 Set ,他们实现子类都是单列集合
Map接口的实现子类是双列集合,存放的K-V
- Collection实现子类可以存放多个元素,每个元素可以是Object
- 有些Collection 的实现类,可以存放重复的元素,有些不可以
- 有些Collection 的实现类,有些是有序的(List),有些是无序的(Set)
- Collection接口没有直接的实现类,是通过它的子接口Set和List 实现的
- Collection 常见的方法,以ArrayList为例
List list = new ArrayList ();
//add 方法
list.add("java");
list.add(123);
list.add(true);
// remove 删除指定元素
list.remove(0); //删除下标为0 的元素
list.remove("java"); //指定删除元素
// contains 查找元素是否存在
list.contains("java"); //ture
//size () 获取元素个数
list.size();
// isEmpty() 判段是否为空
list.isEmpty();
// addAll 添加多个元素,可以是另一个对象
List list1 = new ArrayList ();
list1.add("javasssss");
list.addAll(list1);
// removeAll 删除多个元素
// clear() 清空所有元素
list.clear();
-
Collection接口遍历方式
- iterator 迭代器方法
所有实现了Collection接口的对象的集合类都有一个iterator() 方法,用于返回一个实现了Iterator接口对象,即返回一个迭代器;
Iterator仅用于遍历结合;
1.1. 迭代器使用方法
Iterator iterator = coll.iterator(); // 得到一个集合的迭代器;
hasNext(); 判断是否还有下一个元素;
next: 下移,将下移以后集合位置上的元素返回;
通过while循环遍历;
注意:在调用iterator.next()方法之前必须调用iterator.hasNext()进行检测。若不调用,且下一条无效,直接next()会抛出NoSuchElementException异常;
快捷键:iitit
Iterator iterator = list.iterator(); while (iterator.hasNext()) { Object next = iterator.next(); System.out.println(next); }
- 增强for循环
基本语法:
for(元素类型 元素名 : 集合名或数组名) {
访问元素
}
案例:
for(Object obj : col) { System.out.println(obj); }
二、List
- List接口是Collection接口的子接口
- List 集合类中元素有序,可以重复添加
- List集合的每个元素都有其对应的顺序索引,支持索引
- List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可根据序号存取容器中的元素
- 常用的实现类有: ArrayList、LinkedList、Vector
- List接口常用的方法
- add
- addAll(int index, Collection eles):从 index 位置开始将 eles 中的所有元素添加进来
- get(int index):获取指定 index 位置的元素
- indexOf(Object obj):返回 obj 在集合中首次出现的位置
- lastIndexOf(Object obj):返回 obj 在当前集合中末次出现的位置
- Object remove(int index):移除指定 index 位置的元素,并返回此元素
- set(int index, Object ele):设置指定 index 位置的元素为 ele , 相当于是替换.
- List subList(int fromIndex, int toIndex):返回从 fromIndex 到 toIndex 位置的子集合,相当于截取
- List 的三种遍历方式
与collection 一样 的两种遍历方式,迭代器遍历、增强for遍历,另外一种就是普通for循环遍历
普通for循环遍历: 通过get方法可以找到list数组元素
for(int i=0 ;i < list.size();i++) { System.out.println(list.get[i]); }
- 案例(排序,将图书按照价格(小–> 大)进行排序)
注释: 个人觉得这是一个非常号的例题,充分体现出了,集合的
// 测试类
package Study_01;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Collection_ {
@SuppressWarnings("all")
public static void main(String[] args) {
List list = new ArrayList();
list.add(new Book("追风筝的人","马克李维",39.9));
list.add(new Book("偷影子的人","不详",29.9));
list.add(new Book("摆渡的人","不详",19.9));
list.add(new Book("活着","余华",59.9));
for (int i = 0; i < list.size(); i++) {
for (int j=0;j< list.size()-i-1;j++) {
Book b1 = (Book)list.get(j);
Book b2 = (Book)list.get(j+1);
if(b1.getPrice()>b2.getPrice()) {
list.set(j,b2);
list.set(j+1,b1);
}
}
}
// System.out.println(list);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
Object next = iterator.next();
System.out.println(next);
}
}
}
// Book 类
package Study_01;
public class Book {
private String name;
private String author;
private double price;
public Book() {}
public Book(String name, String author, double price) {
this.name = name;
this.author = author;
this.price = price;
}
@Override
public String toString() {
return "Bookl{" +
"name='" + name + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
运行结果;
三、ArrayList 底层结构和源码分析
- ArrayList 是由数组来实现数据存储的
- ArrayList基本等同于Vector,除了ArrayList 是线程不安全(执行效率高),在多线程情况下,不建议使用ArrayList
- ArrayList 的底层操作机制源码分析
- ArrrayList 中维护 了一个 Object 类型的数组elementDate; Transient Object[] elementDate; //Transient 表示瞬间,短暂的
- 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementDate为10,如果需要再次扩容,则扩容elementDate为1.5倍
- 如果使用的是指定大小的构造器,则初始elementDate容量为指定大小,如果需要扩容,则直接扩容elementDate为1.5倍
- 自己debug运行,非常重要
- ArrayList数据结构特点
- 增删效率低,因为数组的元素在内存上地址是连续的,如果删除或者增加都会涉及到后面大量元素的位移
- 检索效率高,每个元素都有下标,且存储的数据类型都相同,通过数学表达式可以计算出某个下标的内存地址
- 实际开发中ArrayList使用频率最高,一般是调用add()向末尾增删元素,这样不影响效率