集合详解(二):List

一、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>必须在接口与继承类上都标注
六、静态导入
1、格式:import static 包名….类名.方法名;
2、作用:可以直接导入到方法的级别,原来是包的导入或者类的导入。
3、静态导入的注意事项:
  • 方法必须是静态的 
  • 如果有多个同名的静态方法,容易不知道使用谁?这个时候要使用,必须加前缀。
七、可变参数
1、可变参数:定义方法的时候不知道该定义多少个参数。
2、格式: 修饰符 返回值类型 方法名(数据类型… 变量名){  } 
3、注意:
  • 这里的变量其实是一个数组,原来就是数组实现的。 
  • 如果一个方法有可变参数,并且有多个参数,那么,可变参数肯定是最后一个 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值