一、List概述
(一)概述
1、List特点
1)有序(存储和取出的元素顺序一致),对每个位置可以精确控制。
2)可重复的,不唯一。
2、List的子类特点
1)ArrayList:查询快
- 底层数据结构是数组(定长),查询快,增删慢。
- 线程不安全,效率高。
2)Vector:不推荐
- 底层数据结构是数组,查询快,增删慢。
- 线程安全,效率低。
3)LinkedList:增删快
- 底层数据结构是链表,查询慢,增删快。
- 线程不安全,效率高。
(二)功能
1、List集合的特有功能:
1)添加功能:void add(int index,Object element):在指定位置添加元素
2)获取功能:Object get(int index):获取指定位置的元素
3)列表迭代器:ListIterator listIterator():List集合特有的迭代器
4)删除功能:Object remove(int index):根据索引删除元素,返回被删除的元素
5)修改功能:Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
6)特有迭代
- for循环与size迭代。
- listIterator():可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,可以解决List的并发修改问题。。
- Object previous():获取上一个元素
- boolean hasPrevious():判断是否有元素
2、并发修改问题:
1)问题描述:
- 迭代器遍历元素的时候,通过集合是不能修改元素的。
- ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改
2)产生的原因:
- 迭代器是依赖于集合而存在的,在判断成功后,集合中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
- 其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。
3)如何解决呢?
- 方法1:List特有迭代器,元素是跟在刚才迭代的元素后面的。
- 方法2:普通for循环遍历,元素在最后添加的。
- 方法3:JUC并发的集合
4)代码:
<span style="font-size:18px;"> public void test5(){
// 创建List集合对象
List list = new ArrayList();
// 添加元素
list.add("hello");
list.add("world");
list.add("java");
// 迭代器遍历,会 ConcurrentModificationException
Iterator it = list.iterator();
while (it.hasNext()) {
String s = (String) it.next();
if ("world".equals(s)) {
list.add("javaee");
}
}
// 方式1:迭代器迭代元素,迭代器修改元素
// 而Iterator迭代器却没有添加功能,所以我们使用其子接口ListIterator
// 元素是跟在刚才迭代的元素后面的。
ListIterator lit = list.listIterator();
while (lit.hasNext()) {
String s = (String) lit.next();
if ("world".equals(s)) {
lit.add("javaee");
}
}
// 方式2:集合遍历元素,集合修改元素(普通for循环)
// 元素在最后添加的。
for (int x = 0; x < list.size(); x++) {
String s = (String) list.get(x);
if ("world".equals(s)) {
list.add("javaee");
}
}
// 方式3:使用JUC包同步集合 CopyOnWriteArrayList
System.out.println("list:" + list);
}</span>
二、ArrayList
(一)特点
1、底层数据结构是数组,查询快,增删慢
2、线程不安全,效率高
(二)实例
1、去重(Array中的去重,同法)
1)方法1:新创建一个集合,遍历往新集合中放
<span style="font-size:18px;"> public void test2(){
// 创建集合对象
ArrayList array = new ArrayList();
// 添加多个字符串元素(包含内容相同的)
array.add("hello");
array.add("world");
array.add("java");
array.add("world");
array.add("java");
array.add("world");
array.add("world");
array.add("world");
array.add("world");
array.add("java");
array.add("world");
// 创建新集合
ArrayList newArray = new ArrayList();
// 遍历旧集合,获取得到每一个元素
Iterator it = array.iterator();
while (it.hasNext()) {
String s = (String) it.next();
// 拿这个元素到新集合去找,看有没有
if (!newArray.contains(s)) {
newArray.add(s);//新的集合中没有,则添加
}
}
// 最后,去重后的再新集合中,遍历新集合
for (int x = 0; x < newArray.size(); x++) {
String s = (String) newArray.get(x);
System.out.println(s);
}
}
</span>
2)方法2:利用选择排序的思想,拿0索引的依次和后面的比较,有就把后的干掉。
<span style="font-size:18px;">public void test3(){
// 创建集合对象
ArrayList array = new ArrayList();
// 添加多个字符串元素(包含内容相同的)
array.add("hello");
array.add("world");
array.add("java");
array.add("world");
array.add("java");
array.add("world");
array.add("world");
array.add("world");
array.add("world");
array.add("java");
array.add("world");
// 由选择排序思想引入,我们就可以通过这种思想做这个题目
// 拿0索引的依次和后面的比较,有就把后的干掉
// 同理,拿1索引...
for (int x = 0; x < array.size() - 1; x++) {
for (int y = x + 1; y < array.size(); y++) {
if (array.get(x).equals(array.get(y))) {
array.remove(y);
y--;// 去掉一个后,后面元素会补位,会少一个元素。
} // 如去掉4位置上的word,那么5位置上的word会进入4位置。需要在4位置再检查一遍.y需要--
}
}
// 遍历集合
Iterator it = array.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
}
}
</span>
三、LinkedList
(一)LinkedList的特有功能:
1、添加功能
- public void addFirst(Object e) :往前加
- public void addLast(Object e) :往后加,和add一样
2、获取功能
- public Object getFirst() :拿的永远都是第一个
- public Obejct getLast() :拿最后一个
3、删除功能:超过范围会报错
- public Object removeFirst()
- public Object removeLast()
<span style="font-size:18px;"> public void test1(){
// 创建集合对象
LinkedList link = new LinkedList();
// 添加元素
link.add("hello");
link.add("world");
link.add("java");
link.addFirst("javaee");//往前添加
link.addLast("android");//往后添加(其实与add()方法一样的)
System.out.println("link:" + link);//link:[javaee, hello, world, java, android]
System.out.println("getFirst:" + link.getFirst());//getFirst:javaee
System.out.println("getLast:" + link.getLast());//getLast:android
System.out.println("removeFirst:" + link.removeFirst());//removeFirst:javaee
System.out.println("removeLast:" + link.removeLast());//removeLast:android
// 输出对象名
System.out.println("link:" + link);//link:[hello, world, java]
}</span>
(二)实现【栈】:先进后出
1、方法:addFirst(Object e) 和 removeFirst()
2、代码:
1)代理类 栈
<span style="font-size:18px;">package collection.list;
import java.util.LinkedList;
/**
*
* @Title: 自定义的栈集合
* @Description:利用
* @Copyright: Copyright (c) 2015
* @Company:
*
* @author: SAM-SHO
* @version: 1.0
* @CreateDate:Apr 12, 2015
*/
public class MyStack {
private LinkedList link;
public MyStack() {
link = new LinkedList();
}
public void add(Object obj) {
link.addFirst(obj);
}
public Object get() {
// return link.getFirst();//拿的永远都是第一个
return link.removeFirst();//需要弹栈
}
public boolean isEmpty() {
return link.isEmpty();
}
}
</span>
2)测试
<span style="font-size:18px;"> public void test3(){
// 创建集合对象
MyStack ms = new MyStack();
// 添加元素
ms.add("hello");
ms.add("world");
ms.add("java");
// System.out.println(ms.get());
// System.out.println(ms.get());
// System.out.println(ms.get());
// NoSuchElementException
// System.out.println(ms.get());
while(!ms.isEmpty()){//需要判断
System.out.println(ms.get());
}
}</span>
【输出】: java world hello
四、Vector(略)
五、泛型
1、泛型类:<T>在类上
2、泛型方法:<T>在方法的返回值前面。
- 如果有泛型方法,一般直接设置为泛型类。
- 泛型类中的静态方法,不能设置为泛型方法。
3、泛型接口:<T>必须在接口与继承类上都标注
4、详见:
java进阶(五):Java泛型
六、静态导入
1、格式:import static 包名….类名.方法名;
2、作用:可以直接导入到方法的级别,原来是包的导入或者类的导入。
3、静态导入的注意事项:
- 方法必须是静态的
- 如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。
七、可变参数
1、可变参数:定义方法的时候不知道该定义多少个参数。
2、格式: 修饰符 返回值类型 方法名(数据类型… 变量名){ }
3、注意:
- 这里的变量其实是一个数组,原来就是数组实现的。
- 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个