java基础(the 15th day)
目录
一.List集合
1. List集合简介
2. List的特点
测试代码: 增删改查等
3. 创建List
4. 遍历List
测试:四种遍历
5. List和Array转换
6.交集,并集,差集
7. 小结
一.List集合
1. List集合简介
在集合类中,List
是最基础的一种集合:它是一种有序列表。List
的行为和数组几乎完全相同:List
内部按照放入元素的先后顺序存放,每个元素都可以通过索引确定自己的位置,List
的索引和数组一样,从0
开始。
List
和数组类似,也是有序结构。但是,如果我们使用数组,在添加和删除元素的时候,会非常不方便。
因此,在实际应用中,需要增删元素的有序列表,我们使用最多的是ArrayList
。实际上,ArrayList
在内部使用了数组来存储所有元素。
当需要在指定索引位置(索引=2)添加一个元素(X)到ArrayList时,ArrayList自动移动需要移动的元素:
size=5
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ A │ B │ │ C │ D │ E │ │ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘0 1 2 3 4 5 6 7 8 9
然后,往内部指定索引的数组位置添加一个元素,然后把size
加1
:
size=6
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ A │ B │ X │ C │ D │ E │ │ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘0 1 2 3 4 5 6 7 8 9
当继续添加元素,但是数组已满,没有空闲位置的时候,ArrayList
先创建一个更大的新数组(新数组长度为原数组的1.5倍),然后把旧数组的所有元素复制到新数组,紧接着用新数组取代旧数组(可以理解为扩容):
size=10
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ A │ B │ X │ C │ D │ E │ F │ G │ H │ I │ │ │ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
现在,新数组就有了空位,可以继续添加一个元素到数组末尾,同时size
加1
:
size=11
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│ A │ B │ X │ C │ D │ E │ F │ G │ H │ I │ J │ │ │ │ │
└───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┴───┘0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
List<E>接口的几个方法:
- 在末尾添加一个元素:
boolean add(E e)
- 在指定索引添加一个元素:
boolean add(int index, E e)
- 删除指定索引的元素:
E remove(int index)
- 删除某个元素:
boolean remove(Object e)
- 获取指定索引的元素:
E get(int index)
- 获取链表大小(包含元素的个数):
int size()
实现List
接口并非只能通过数组(即ArrayList
的实现方式)来实现,另一种LinkedList
通过“链表”也实现了List接口。在LinkedList
中,它的内部每个元素都指向下一个元素:
┌───┬───┐ ┌───┬───┐ ┌───┬───┐ ┌───┬───┐
HEAD ──>│ A │ ●─┼──>│ B │ ●─┼──>│ C │ ●─┼──>│ D │ │└───┴───┘ └───┴───┘ └───┴───┘ └───┴───┘
我们来比较一下ArrayList
和LinkedList
:
| ArrayList | LinkedList |
获取指定元素 | 速度很快 | 需要从头开始查找元素 |
添加元素到末尾 | 速度很快 | 速度很快 |
在指定位置添加/删除 | 需要移动元素 | 不需要移动元素 |
内存占用 | 少 | 较大 |
2. List的特点
使用List
时,我们要关注List
接口的规范。List
接口允许我们添加重复的元素,即List
内部的元素可以重复:
public class Main {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("apple"); // size=1list.add("pear"); // size=2list.add("apple"); // 允许重复添加元素,size=3System.out.println(list.size());}
}
List
还允许添加null
值:
public class Main {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("apple"); // size=1list.add(null); // size=2list.add("pear"); // size=3String second = list.get(1); // nullSystem.out.println(second);}
}
测试代码: 增删改查等
package apsource;import java.util.ArrayList;
import java.util.Arrays;public class Demo06 {public static void main(String[] args) {ArrayList<String> arrayList = new ArrayList<>();arrayList.addAll(Arrays.asList("穆","鹏","利"));System.out.println("集合内容为:"+arrayList);// 1.oldE set(int index, E element) 用指定的元素替代此列表中指定位置上的元素String str = arrayList.set(2,"木棚里");int index = arrayList.indexOf("木棚里");if(index >= 0){arrayList.set(index,"木棚");}System.out.println("修改后:"+str);// remove(int index) 根据指定索引删除元素,删除一个就返回Boolean b = arrayList.remove("马晓婷");System.out.println("删除结果:"+b);// void clear() 删除集合中所有元素,刺激和仍旧存在,集合元素长度变为0arrayList.clear();System.out.println("集合内容为:"+arrayList);}
}package apsource;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class Demo04 {public static void main(String[] args) {ArrayList<String> arrayList = new ArrayList<>();arrayList.add("穆");System.out.println(arrayList);// 使用工具类生成List集合List<String> list = Arrays.asList("刘常伟","行数片","木棚里");System.out.println( list);System.out.println("集合内容为:"+arrayList);
// 查看// int size()查集合的长度,具体元素个数System.out.println("集合的长度:"+arrayList.size());// E get(int index)String item = arrayList.get(0);System.out.println("集合中索引为0的元素:"+item);System.out.println("尾元素:"+arrayList.get(arrayList.size()-1));// 3.int indexOf(Object o)查找找到指定元素的下标位置,如果不存在,则返回数组-1int index = arrayList.indexOf("木棚里");System.out.println("元素下标为:"+index);// boolean contains(Object o)boolean contains = arrayList.contains("木棚里");System.out.println("集合中是否包含此元素:"+contains);// 5.boolean isEmpty()boolean empty = arrayList.isEmpty();System.out.println("集合是否为空:"+empty);// 6.截取集合List<String> list1 = arrayList.subList(0, 1);System.out.println("截取集合:"+list1);// 7.equals(Object o)boolean equals = arrayList.equals(list1);System.out.println("集合是否相等:"+equals);}}
3. 创建List
除了使用ArrayList
和LinkedList
,我们还可以通过Arrays
工具类提供的asList()
方法,根据给定元素快速创建List:
List<String> list = Arrays.asList("杭州", "北京", "上海", "南京");
4. 遍历List
测试:四种遍历
package apsource;import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.ListIterator;public class Demo05 {public static void main(String[] args) {ArrayList<String> arrayList = new ArrayList<>();arrayList.addAll(Arrays.asList("刘","常","伟"));System.out.println("集合内容为:"+arrayList);// 遍历集合// 1.forfor (int i = 0; i < arrayList.size(); i++) {System.out.println(arrayList.get(i)+"");}// foreachfor (String item : arrayList){System.out.println(item+"");}System.out.println("-----------------");// 迭代器// 1.获取迭代器对象Iterator<String> iterator = arrayList.iterator();// 判断是否有下一个元素while (iterator.hasNext()){// 获取下一个String item = iterator.next();System.out.println(item+"");}System.out.println("-----------------");// 2.使用迭代器删除元素while (iterator.hasNext()){String item = iterator.next();if ("常".equals(item)){iterator.remove();}}// 3.2 获取List迭代器对象ListIterator<String> listIterator = arrayList.listIterator(arrayList.size());// 判断是否有上一个元素while (listIterator.hasPrevious()){// 获取上一个String item = listIterator.previous();System.out.println(item+"");}}
}
5. List和Array转换
把List
变为Array
有三种方法,第一种是调用toArray()
方法直接返回一个Object[]
数组:
public class Main {public static void main(String[] args) {List<String> list = Arrays.asList("杭州", "北京", "上海", "南京");Object[] array = list.toArray();for (Object s : array) {System.out.println(s);}}
}
第二种方式是给toArray(T[])
传入一个类型相同的Array
,List
内部自动把元素复制到传入的Array
中:
public class Main {public static void main(String[] args) {List<Integer> list = Arrays.asList("杭州", "北京", "上海", "南京");Integer[] array = list.toArray(new Integer[3]);for (Integer n : array) {System.out.println(n);}}
}
注意:我们传入类型不匹配的数组,例如,String[]
类型的数组,由于List
的元素是Integer
,所以无法放入String
数组,这个方法会抛出ArrayStoreException
。
但是最好传入一个长度刚好相等的数组:
Integer[] array = list.toArray(new Integer[list.size()]);
把Array
变为List
就简单多了,使用Arrays.asList(T...)
方法把数组转换成List
。要注意的是,返回的List
不是ArrayList
或者LinkedList
,而是Arrays
工具类的一个内部类ArrayList
:
public class Arrays {...public static <T> List<T> asList(T... a) {return new ArrayList<>(a);}private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{...}...
}
这个内部类ArrayList
是一个只读的List
,对只读List
调用add()
、remove()
方法会抛出UnsupportedOperationException
。
6.交集,并集,差集
直接看代码:
package apsource;import java.util.ArrayList;
import java.util.Arrays;public class Demo07 {public static void main(String[] args) {ArrayList<String> arrayList = new ArrayList<>();ArrayList<String> arrayList1 = new ArrayList<>();arrayList.addAll(Arrays.asList("穆","鹏","利"));arrayList1.addAll(Arrays.asList("木棚里","木棚"));System.out.println("集合内容为:"+arrayList);System.out.println("集合内容为:"+arrayList1);// boolean retainAll(Collection<?> c) --交集 谁调用修改谁// boolean b = list1.retainAll(list2);
// System.out.println(b);
// System.out.println("list和list2的交集为:"+list1);// boolean removeAll(Collection<?> c) -- 差集boolean b = arrayList.removeAll(arrayList1);System.out.println("差集:"+b);System.out.println("差集:"+arrayList);}
}
7. 小结
List
是按索引顺序访问的长度可变的有序表,优先使用ArrayList
而不是LinkedList
;- 可以直接使用
for each
遍历List
; List
可以和Array
相互转换;