目录
1、集合的概述
2、Collection(单列)
1. 单个集合的方法
2. 多个集合之间
3. 集合转数组
3、List集合概述
1. ArrayList
1. 添加元素的过程和扩容机制
2. 常用方法
3. removeRange()方法
4. 比较器
2. LinkedList
3. Vorter
4. List集合的遍历(ArrayLIst为例)
1. for循环
2. 增强for循环
3. Iterator (迭代器)
1、集合的概述
在程序运行的过程中,数据的数量随时发生改变,需要的存储结构也随之改变,以解决一些特殊的需求, 但是因为数组长度不变且类型固定的不足,以此我们引用集合,来满足数组的不足。
2、Collection(单列)
java中集合类默认使用泛型,如果没有定义集合中存储的数据类型,默认数据类型为object。
创建方式:
Callection c = new ArrayList(); // 多态:运行看右,编译看左
c.add("a"); c.add(1); c.add(true);
使用泛型:
Callection<T> c = new ArrayList<T>(); // T 可以使用任何类型,如String、Integer、Double等
Callection<String> c = new ArrayList<String>();
使用泛型,来为集合指明数据类型,类型统一就不会出现转型问题。
注:<E>类型的参数化或参数的类型化
常用方法
1. 单个集合的方法
添加元素(一次添加一个)c.add();
清空(所有元素) c.clear();
是否包含指定元素(如a) c.contains("a'); 返回值 boolean
是否为空 c.isEmpty(); 返回值 boolean
删除指定元素 c.remove("a"); 返回值 boolean
集合长度 c.size(); 返回值 int
public class Demo1 {
public static void main(String[] args) {
// Collection c = new ArrayList();
Collection<String> c = new ArrayList<String>();
//向集合添加元素
c.add("a");
c.add("b");
c.add("c");
c.add("d");
/*c.add(1);
c.add(true);*/
//清空集合
//c.clear();
//是否包含指定元素
System.out.println(c.contains("c"));//true 返回值:boolean
//判断是否为空
System.out.println(c.isEmpty());//false
//删除指定元素
System.out.println(c.remove("a"));//true
//集合长度
System.out.println(c.size());//3
System.out.println(c);//[b, c, d]
//添加c1集合的所有元素(包括重复的元素)
}
}
2. 多个集合之间
将c2集合中的元素添加到c1集合中去(可添加重复的元素)
c1.addAll(c2);
c1集合中是否包含c2集合中的元素
c1.containsAll(c2);
删除c1集合中c2集合中的元素
c1.removeAll(c2);
c1集合和c2集合中的交集(内容改变为true,无交集也返回true;内容不变返回false,当c1集合中的元素完全等于c2集合中的元素时,为false。)
c1.retainAll(c2);
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class Demo2 {
public static void main(String[] args) {
Collection<String> c1 = new ArrayList<String>();
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d");
Collection<String> c2 = new ArrayList<String>();
c2.add("g");
c2.add("e");
c2.add("f");
//向c1中添加c2中的元素,可重复。
c1.addAll(c2);
System.out.println(c1);//[a, b, c, d, g, e, f]
//c1集合中是否包含c2中的元素
System.out.println(c1.containsAll(c2)); //true
System.out.println(c1);//[a, b, c, d, g, e, f]
//删除c1中c2的元素
System.out.println(c1.removeAll(c2)); //true
System.out.println(c1);//[a, b, c, d]
//c1和c2集合中交集部分
System.out.println(c1.retainAll(c2)); //true
System.out.println(c1);//[]
}
}
3. 集合转数组
默认转数组:object类型
object[] obj = c1.toArray();
String[] str = c1.toArray(new String[c1.size()]); String类型
//集合转数组
c1.add("a");
c1.add("b");
c1.add("c");
c1.add("d");
Object[] obj = c1.toArray();
System.out.println(Arrays.toString(obj));//[a, b, c, d]
System.out.println(obj.length);//4
String[] str = c1.toArray(new String[c1.size()]);
System.out.println(Arrays.toString(str));//[a, b, c, d]
System.out.println(str.length);//4
3、List集合概述
ArrayList
数组列表(存储连续,长度可变)
特点:查询快,对中间插删操作效率低,可以存储重复的元素。
LinkedList
链表列表
特点:查询慢,从头结点或尾节点开始查询,但是对中间进行插删操作效率高
Vector
数组列表、线程安全(使用同步锁)
特点:查询快,对中间插删操作效率低,可以存储重复的元素
1. ArrayList
ArrayList<String> alist = new ArrayList<String>();
创建对象时,不会创建数组,第一次添加时默认创建一个容量为10的数组。
ArrayList<String> alist = new ArrayList<String>(20);
创建对象时,创建一个指定容量的数组
transient object[] elementDate; 底层存储数据的数组
1. 添加元素的过程和扩容机制
add(E e) 向末尾添加元素进来
概述:
ArrayList在创建对象是不会创建数组,当第一次添加元素时,这时会创建一个容量为10的数组,(默认创建,也可以在创建对象时,创建指定容量的数组),继续添加的前会判断元素添加进来后,元素是否能够放下,如果可以,则可以直接进入数组,如果不可以,则会创建一个新的数组,并且将新数组的容量是原来数组容量的1.5 倍(使用grow())。
源码:
public boolean add(E e) {
ensureCapacityInternal(size + 1); // 检测容量
elementData[size++] = e;
return true;
}
if (minCapacity - elementData.length > 0) 添加后的长度-数组长度>0
grow(minCapacity); 数组扩容方法
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);//扩容为原来的1.5倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0) 最大上限 int最大值-8
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
2. 常用方法
- 向指定位置添加元素(指定位置小于等于alist.size()) alist.add(1, "D");
- 判断集合是否存在指定元素 alist.contains("a");
- 指定元素第一次出现在集合的位置 alist.indexOf("b");
- 指定元素最后一次出现的位置 alist.lastIndexOf("b");
- 判断集合是否为空 alist.isEmpty();
- 删除指定位置的元素 alist.remove(2);
- 删除指定元素 alist.remove("a");
- 将指定索引替换成指定元素 alist.set(3, "F");
- 获取指定索引的内容 alist.get(2));
- 集合大小的长度 alist.size();
- 集合转数组 String[] str = alist.toArray(new String[alist.size()]);
public class Demo {
public static void main(String[] args) {
// ArrayList<String> alist = new ArrayList();
ArrayList<String> alist = new ArrayList<String>(9);
alist.add("a");
alist.add("b");
alist.add("c");
alist.add("d");
alist.add("b");
alist.add("a");
System.out.println(alist);//[a, b, c, d, b, a]
//向指定位置添加内容
alist.add(1, "D");
System.out.println(alist);//[a, D, b, c, d, b, a]
//判断集合是否存在指定元素
System.out.println(alist.contains("a"));//true
//指定元素第一次出现在集合的位置
System.out.println(alist.indexOf("b"));//2
//指定元素最后一次出现的位置
System.out.println(alist.lastIndexOf("b"));//5
// 判断集合是否为空
System.out.println(alist.isEmpty());//false
//删除指定位置的元素
alist.remove(2);
System.out.println(alist);//[a, D, c, d, b, a]
//删除指定元素
alist.remove("a");
System.out.println(alist);//[D, c, d, b, a]
//将指定索引替换成指定元素
alist.set(3, "F");
System.out.println(alist);//[D, c, d, F, a]
//获取指定索引的内容
System.out.println(alist.get(2));//d
//集合大小的长度
System.out.println(alist.size());//5
System.out.println(alist);//[D, c, d, F, a]
//集合转数组
String[] str = alist.toArray(new String[alist.size()]);
System.out.println(Arrays.toString(str));//[D, c, d, F, a]
}
}
3. removeRange()方法
删除指定区间的集合元素
public class MyArrayList<E> extends ArrayList{
public static void main(String[] args) {
MyArrayList<String> alist = new MyArrayList<String>();
alist.removeRange(0, 5);//受保护的方法,在不同的子类访问
}
}
4. 比较器
(1)new + 接口() 创建了一个匿名内部类对象,Comparator 传递一个比较器。
alist.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getId() - o2.getId();
}
});
(2)自定义比较器(例:用户比较器)
//用户类
public class User {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Usre{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
public User(int id, String name) {
this.id = id;
this.name = name;
}
}
import java.util.Comparator;
//用户比较器:
public class UserComparator<U> implements Comparator<User>{
@Override
public int compare(User o1,User o2) {
return o1.getId() - o2.getId();
}
}
//Test类
public class Test {
public static void main(String[] args) {
ArrayList<User> alist = new ArrayList<>();
User user1 = new User(1,"张三1");
User user2 = new User(2,"张三2");
User user3 = new User(3,"张三3");
User user4 = new User(4,"张三4");
User user5 = new User(5,"张三5");
alist.add(user5);
alist.add(user3);
alist.add(user1);
alist.add(user4);
alist.add(user2);
//new + 接口() 创建了一个匿名内部类对象,Comparator 传递一个比较器
/* alist.sort(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return o1.getId() - o2.getId();
}
});*/
alist.sort(new UserComparator());
}
}
2. LinkedList
特点:存储重复元素,按照添加顺序进行排放
创建: LinkedList<String> llist = new LinkedList<>();
Node 节点 E item; 数据 Node<E> next; 后指针 Node<E> prev; 前指针
源码:
Node<E> node(int index) { // assert isElementIndex(index); if (index < (size >> 1)) { //索引小于长度的一半, 从头结点向后找 Node<E> x = first; for (int i = 0; i < index; i++) x = x.next; return x; } else { //从尾节点向前找 Node<E> x = last; for (int i = size - 1; i > index; i--) x = x.prev; return x; } }
3. Vorter
底层也是数组实现,是线程安全(使用同步锁),方法与ArrayList类似。
源码:
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
创建:
Vector<String> v = new Vector<String>();
4. List集合的遍历(ArrayLIst为例)
1. for循环
支持在遍历操作中进行删除集合中的元素,注意所以的变化(会发生数组的越界)
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList<String> alist = new ArrayList<>();
alist.add("a");
alist.add("b");
alist.add("c");
alist.add("d");
alist.add("a");
alist.add("a");
/*
第一种 : for循环
支持在遍历操作中进行删除集合中的元素,注意所以的变化(会发生数组的越界)
*/
for (int i = 0; i < alist.size(); i++) {
System.out.print(alist.get(i) + " ");
}
System.out.println();//a b c d a a
}
}
2. 增强for循环
不支持在遍历集合时进行删除集合中的元素,否则会抛出并发修改异常
(concurrentModificationException)
注:只允许删除一次,删除的同时使用break结束循环
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList<String> alist = new ArrayList<>();
alist.add("a");
alist.add("b");
alist.add("c");
alist.add("d");
alist.add("a");
alist.add("a");
/*
第二种: 增强for循环
不支持在遍历集合时进行删除集合中的元素,否则会抛出并发修改异常
(concurrentModificationException)
*/
for (String item: alist
) {
System.out.print(item);
}
}
}
3. Iterator (迭代器)
1. 调用Iterator(),返回一个迭代器对象
package javacollection.day3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Demo1 {
public static void main(String[] args) {
ArrayList<String> alist = new ArrayList<>();
alist.add("a");
alist.add("b");
alist.add("c");
alist.add("d");
alist.add("a");
alist.add("a");
/*
第三种:迭代器
Iterator<E>(从前向后遍历删除操作) 和 ListIterator<E>
(从后往前进行遍历删除操作)两种
*/
Iterator<String> it = alist.iterator();
//调用Iterator()方法,返回一个迭代器对象
while (it.hasNext()){
String its = it.next();
if(its.equals("a")){
it.remove();//删除当前指针指定的那个元素
}
}
System.out.println(alist);//[b, c, d]
ListIterator<String> iter = alist.listIterator(alist.size());
//给出集合的长度,逆序输出集合中的元素,ListIterator只能遍历List接口下的集合
while (iter.hasPrevious()){
String its = iter.previous();
if(its.equals("b")){
iter.remove();
}
}
System.out.println(alist);//[c, d]
}
}
2. 给出集合的长度,逆序输出集合中的元素,ListIterator只能遍历List接口下的集合
package javacollection.day3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Demo1 {
public static void main(String[] args) {
ArrayList<String> alist = new ArrayList<>();
alist.add("a");
alist.add("b");
alist.add("c");
alist.add("d");
alist.add("a");
alist.add("a");
ListIterator<String> iter = alist.listIterator(alist.size());
//给出集合的长度,逆序输出集合中的元素,ListIterator只能遍历List接口下的集合
while (iter.hasPrevious()){
String its = iter.previous();
if(its.equals("b")){
iter.remove();
}
}
System.out.println(alist);//[a, c, d, a, a]
}
}