Java 集合框架(中)——List集合

目录

Collection案例(巩固知识)

一、List接口

List案例 :

 List集合的特有功能: 

 ListIterator接口的成员方法

 

List集合的三个常用的子接口:

1、ArrayList类概述及使用

2、Vector类概述及使用

3、LinkedList类概述及使用

List集合练习


Collection案例(巩固知识)

  1. 存储字符串并遍历
  2. 存储自定义对象并遍历
  • Student(name,age)

1、存储字符串并遍历

需求:存储字符串并遍历。
  
 分析:
          A:创建集合对象
          B:创建字符串对象
          C:把字符串对象添加到集合中
          D:遍历集合
 

如下:

package cn.wen_01;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionTest {
	public static void main(String[] args) {
		// 创建集合对象
		Collection c = new ArrayList();

		// 创建字符串对象
		// 把字符串对象添加到集合中
		c.add("小明");
		c.add("小何");
		c.add("小文");
		c.add("小马");
		c.add("小亮");

		// 遍历集合
		// 通过集合对象获取迭代器对象
		Iterator it = c.iterator();
		// 通过迭代器对象的hasNext()方法判断有没有元素
		while (it.hasNext()) {
			// 通过迭代器对象的next()方法获取元素
			String s = (String) it.next();
			System.out.println(s);
		}
	}
}

2、存储自定义对象并遍历

 需求:存储自定义对象并遍历Student(name,age)
 
  分析:
          A:创建学生类
          B:创建集合对象
          C:创建学生对象
          D:把学生对象添加到集合对象中
          E:遍历集合
 

学生类:

package cn.wen;

public class Student {
	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

测试类:

package cn.wen;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionTest {
	public static void main(String[] args) {
		// 创建集合对象
		Collection c = new ArrayList();

		// 创建学生对象
		Student s1 = new Student("小明", 25);
		Student s2 = new Student("小王", 16);
		Student s3 = new Student("小亮", 20);
		Student s4 = new Student();
		s4.setName("小红");
		s4.setAge(26);

		// 把学生对象添加到集合对象中
		c.add(s1);
		c.add(s2);
		c.add(s3);
		c.add(s4);
		c.add(new Student("小文", 18)); // 匿名对象

		// 遍历集合
		Iterator it = c.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}

一、List接口

回顾知识点:

Collection 接口是List、Set 和Queue 接口的父接口, 该接口里定义的方法既可用于操作Set 集合,也可用于操作List 和Queue 集合。

List接口概述
  • 有序的 collection也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素
  • set 不同,列表通常允许重复的元素

List 集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List 集合允许使用重复元素,可以通过索引来访问指定位置的集合元素。List 集合默认按元素的添加顺序设置元素的索引,例如第一次添加的元素索引为0 , 第二次添加的元素索引为l ……

List 作为Collection 接口的子接口,当然可以使用Co llection 接口里的全部方法。而且由于List 是有序集合,因此List 集合里增加了一些根据索引来操作集合元素的方法。

用之前学的Collection集合,学习List的

List案例 :

1、存储字符串并遍历
2、存储自定义对象并遍历
 
package cn.wen_01;

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;

/*
 * 需求:List集合存储字符串并遍历。
 */
public class ListDemo {
	public static void main(String[] args) {
		// 创建集合对象
		List list = new ArrayList();

		// 创建字符串并添加字符串
		list.add("hello");
		list.add("world");
		list.add("java");

		// 遍历集合
		Iterator it = list.iterator();
		while (it.hasNext()) {
			String s = (String) it.next();
			System.out.println(s);
		}
	}
}
package cn.wen_02;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
 * List集合的特点:
 * 		有序(存储和取出的元素一致),可重复的。
 */
public class ListDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		List list = new ArrayList();

		// 存储元素
		list.add("hello");
		list.add("world");
		list.add("java");
		list.add("javaee");
		list.add("android");
		list.add("javaee");
		list.add("android");

		// 遍历集合
		Iterator it = list.iterator();
		while (it.hasNext()) {
			String s = (String) it.next();
			System.out.println(s);
		}
	}
}

 List集合的特有功能: 


 A:添加功能
          void add(int index,Object element):在指定位置添加元素
 B:获取功能
         Object get(int index):获取指定位置的元素
 C:列表迭代器
          ListIterator listIterator():List集合特有的迭代器
 D:删除功能
          Object remove(int index):根据索引删除元素,返回被删除的元素
 E:修改功能
         Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
 

  • 部分功能测试代码如下:
package cn.wen_03;

import java.util.ArrayList;
import java.util.List;

public class ListDemo {
	public static void main(String[] args) {
		// 创建集合对象
		List list = new ArrayList();

		// 添加元素
		list.add("hello");
		list.add("world");
		list.add("java");

		// void add(int index,Object element):在指定位置添加元素
		// list.add(1, "android");//没有问题
		// IndexOutOfBoundsException
		// list.add(11, "javaee");//有问题(异常)
		// list.add(3, "javaee"); //没有问题
		// list.add(4, "javaee"); //有问题

		// Object get(int index):获取指定位置的元素
		// System.out.println("get:" + list.get(1));
		// IndexOutOfBoundsException
		// System.out.println("get:" + list.get(11));

		// Object remove(int index):根据索引删除元素,返回被删除的元素
		// System.out.println("remove:" + list.remove(1));
		// IndexOutOfBoundsException
		// System.out.println("remove:" + list.remove(11));

		// Object set(int index,Object element):根据索引修改元素,返回被修饰的元素
		System.out.println("set:" + list.set(1, "javaee"));

		System.out.println("list:" + list);
	}
}
  • List集合的特有遍历功能:

           size()和get()方法结合使用

代码测试如下:

package cn.wen_04;

import java.util.ArrayList;
import java.util.List;

/*
 * List集合的特有遍历功能:
 * 		size()和get()方法结合使用
 */
public class ListDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		List list = new ArrayList();

		// 添加元素
		list.add("hello");
		list.add("world");
		list.add("java");

		// Object get(int index):获取指定位置的元素
		// System.out.println(list.get(0));
		// System.out.println(list.get(1));
		// System.out.println(list.get(2));
		// IndexOutOfBoundsException
		// System.out.println(list.get(3));

		// 用循环改进
		// for (int x = 0; x < 3; x++) {
		// System.out.println(list.get(x));
		// }
		// 如果元素过多,数起来就比较麻烦,所以我们使用集合的一个长度功能:size()
		// 最终的遍历方式就是:size()和get()
		for (int x = 0; x < list.size(); x++) {
			// System.out.println(list.get(x));

			String s = (String) list.get(x);
			System.out.println(s);
		}
	}
}

小练习

学生类:

package cn.wen;

public class Student {
	// 成员变量
	private String name;
	private int age;

	// 构造方法
	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	// 成员方法
	// getXxx()/setXxx()
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}
}

测试类:

package cn.wen;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/*
 * 存储自定义对象并遍历,用普通for循环。(size()和get()结合)
 */
public class ListDemo3 {
	public static void main(String[] args) {
		// 创建集合对象
		List list = new ArrayList();

		// 创建学生对象
		Student s1 = new Student("小东", 18);
		Student s2 = new Student("小明", 88);
		Student s3 = new Student("小红", 38);

		// 把学生添加到集合中
		list.add(s1);
		list.add(s2);
		list.add(s3);

		// 遍历
		// 迭代器遍历
		Iterator it = list.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();
			System.out.println(s.getName() + "---" + s.getAge());
		}
		System.out.println("--------");

		// 普通for循环
		for (int x = 0; x < list.size(); x++) {
			Student s = (Student) list.get(x);
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}

 

 ListIterator接口的成员方法

  • boolean hasPrevious()
  • E previous()
  • ConcurrentModificationException
现象
原因
解决方案
 

代码测试如下: 

package cn.wen;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*
 * 列表迭代器:
 * 		ListIterator listIterator():List集合特有的迭代器
 * 		该迭代器继承了Iterator迭代器,所以,就可以直接使用hasNext()和next()方法。
 * 
 * 特有功能:
 * 		Object previous():获取上一个元素
 * 		boolean hasPrevious():判断是否有元素
 * 
 * 		注意:ListIterator可以实现逆向遍历,但是必须先正向遍历,才能逆向遍历,所以一般无意义,不使用。
 */
public class ListIteratorDemo {
	public static void main(String[] args) {
		// 创建List集合对象
		List list = new ArrayList();
		list.add("hello");
		list.add("world");
		list.add("java");

		// ListIterator listIterator()
		ListIterator lit = list.listIterator(); // 子类对象
		// while (lit.hasNext()) {
		// String s = (String) lit.next();
		// System.out.println(s);
		// }
		// System.out.println("-----------------");
		
		// System.out.println(lit.previous());
		// System.out.println(lit.previous());
		// System.out.println(lit.previous());
		// NoSuchElementException
		// System.out.println(lit.previous());

		while (lit.hasPrevious()) {
			String s = (String) lit.previous();
			System.out.println(s);
		}
		System.out.println("-----------------");

		// 迭代器
		Iterator it = list.iterator();
		while (it.hasNext()) {
			String s = (String) it.next();
			System.out.println(s);
		}
		System.out.println("-----------------");

	}
}
  •  注意小问题:
package cn.itcast_04;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

/*
 * 问题?
 * 		我有一个集合,如下,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。
 * 
 * ConcurrentModificationException:当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。 
 * 产生的原因:
 * 		迭代器是依赖于集合而存在的,在判断成功后,集合的中新添加了元素,而迭代器却不知道,所以就报错了,这个错叫并发修改异常。
 * 		其实这个问题描述的是:迭代器遍历元素的时候,通过集合是不能修改元素的。
 * 如何解决呢?
 * 		A:迭代器迭代元素,迭代器修改元素
 * 			元素是跟在刚才迭代的元素后面的。
 * 		B:集合遍历元素,集合修改元素(普通for)
 * 			元素在最后添加的。
 */
public class ListIteratorDemo2 {
	public static void main(String[] args) {
		// 创建List集合对象
		List list = new ArrayList();
		// 添加元素
		list.add("hello");
		list.add("world");
		list.add("java");

		// 迭代器遍历
		// 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");
			}
		}

		System.out.println("list:" + list);
	}
}

 

List集合的三个常用的子接口:

1、ArrayList类概述及使用

  • ArrayList类概述
底层数据结构是数组,查询快,增删慢
线程不安全,效率高
  • ArrayList案例
存储字符串并遍历
存储自定义对象并遍历

1)、存储字符串并遍历

package cn.wen_01;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * List的子类特点:
 * 		ArrayList:
 * 			底层数据结构是数组,查询快,增删慢
 * 			线程不安全,效率高
 * 		Vector:
 * 			底层数据结构是数组,查询快,增删慢
 * 			线程安全,效率低
 * 		LinkedList:
 * 			 底层数据结构是链表,查询慢,增删快
 * 			线程不安全,效率高
 * 
 * 案例:
 * 		使用List的任何子类存储字符串或者存储自定义对象并遍历。
 * 
 * ArrayList的使用。	
 * 		存储字符串并遍历
 */
public class ArrayListDemo {
	public static void main(String[] args) {
		// 创建集合对象
		ArrayList array = new ArrayList();

		// 创建元素对象,并添加元素
		array.add("hello");
		array.add("world");
		array.add("java");

		// 遍历
		Iterator it = array.iterator();
		while (it.hasNext()) {
			String s = (String) it.next();
			System.out.println(s);
		}

		System.out.println("-----------");

		for (int x = 0; x < array.size(); x++) {
			String s = (String) array.get(x);
			System.out.println(s);
		}
	}
}

2)、存储自定义对象并遍历

 测试类:

package cn.wen_02;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * ArrayList存储自定义对象并遍历
 */
public class ArrayListDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		ArrayList array = new ArrayList();

		// 创建学生对象
		Student s1 = new Student("武松", 30);
		Student s2 = new Student("鲁智深", 40);
		Student s3 = new Student("林冲", 36);
		Student s4 = new Student("杨志", 38);

		// 添加元素
		array.add(s1);
		array.add(s2);
		array.add(s3);
		array.add(s4);

		// 遍历
		Iterator it = array.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();
			System.out.println(s.getName() + "---" + s.getAge());
		}

		System.out.println("----------------");

		for (int x = 0; x < array.size(); x++) {
			// ClassCastException 注意,千万要搞清楚类型
			// String s = (String) array.get(x);
			// System.out.println(s);

			Student s = (Student) array.get(x);
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}

学生类:

package cn.wen_02;

public class Student {
	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

}

2、Vector类概述及使用

Vector 类概述
底层数据结构是数组,查询快,增删慢
线程安全,效率低
Vector 类特有功能
public void addElement (E obj )
public E elementAt ( int index )
public Enumeration elements ()
 
package cn.wen_03;

import java.util.Enumeration;
import java.util.Vector;

/*
 * Vector的特有功能:
 * 1:添加功能
 * 		public void addElement(Object obj)		--	add()
 * 2:获取功能
 * 		public Object elementAt(int index)		--  get()
 * 		public Enumeration elements()			--	Iterator iterator()
 * 				boolean hasMoreElements()				hasNext()
 * 				Object nextElement()					next()
 * 
 * JDK升级的原因:
 * 		A:安全
 * 		B:效率
 * 		C:简化书写
 */
public class VectorDemo {
	public static void main(String[] args) {
		// 创建集合对象
		Vector v = new Vector();

		// 添加功能
		v.addElement("hello");
		v.addElement("world");
		v.addElement("java");

		// 遍历
		for (int x = 0; x < v.size(); x++) {
			String s = (String) v.elementAt(x);
			System.out.println(s);
		}

		System.out.println("------------------");

		Enumeration en = v.elements(); // 返回的是实现类的对象
		while (en.hasMoreElements()) {
			String s = (String) en.nextElement();
			System.out.println(s);
		}
	}
}

3、LinkedList类概述及使用

LinkedList 类概述
底层 数据结构是链表,查询慢,增删快
线程不安全,效率高
LinkedList 特有功能
public void addFirst (E e) addLast (E e )
public E getFirst () getLast ()
public E removeFirst () public E removeLast ()
 
package cn.wen_03;

import java.util.LinkedList;

/*
 * LinkedList的特有功能:
 * 		A:添加功能
 * 			public void addFirst(Object e)
 * 			public void addLast(Object e)
 * 		B:获取功能
 * 			public Object getFirst()
 * 			public Obejct getLast()
 * 		C:删除功能
 * 			public Object removeFirst()
 * 			public Object removeLast()
 */
public class LinkedListDemo {
	public static void main(String[] args) {
		// 创建集合对象
		LinkedList link = new LinkedList();

		// 添加元素
		link.add("hello");
		link.add("world");
		link.add("java");

		// public void addFirst(Object e)
		// link.addFirst("javaee");
		// public void addLast(Object e)
		// link.addLast("android");

		// public Object getFirst()
		// System.out.println("getFirst:" + link.getFirst());
		// public Obejct getLast()
		// System.out.println("getLast:" + link.getLast());

		// public Object removeFirst()
		System.out.println("removeFirst:" + link.removeFirst());
		// public Object removeLast()
		System.out.println("removeLast:" + link.removeLast());

		// 输出对象名
		System.out.println("link:" + link);
	}
}

List集合练习

  • ArrayList
去除集合中字符串的重复值 ( 字符串的内容相同 )
去除集合中自定义对象的重复值 ( 对象的成员变量值都相同 )
  • LinkedList
请用 LinkedList 模拟栈数据结构的集合,并测试

1)、去除集合中字符串的重复值(字符串的内容相同)

package cn.wen_01;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * ArrayList去除集合中字符串的重复值(字符串的内容相同)
 * 
 * 分析:
 * 		A:创建集合对象
 * 		B:添加多个字符串元素(包含内容相同的)
 * 		C:创建新集合
 * 		D:遍历旧集合,获取得到每一个元素
 * 		E:拿这个元素到新集合去找,看有没有
 * 			有:不搭理它
 * 			没有:就添加到新集合
 * 		F:遍历新集合
 */
public class ArrayListDemo {
	public static void main(String[] args) {
		// 创建集合对象
		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);
		}
	}
}

2)、去除集合中自定义对象的重复值(对象的成员变量值都相同)

package cn.wen_02;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * 需求:ArrayList去除集合中字符串的重复值(字符串的内容相同)
 * 要求:不能创建新的集合,就在以前的集合上做。
 */
public class ArrayListDemo2 {
	public static void main(String[] args) {
		// 创建集合对象
		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--;
				}
			}
		}

		// 遍历集合
		Iterator it = array.iterator();
		while (it.hasNext()) {
			String s = (String) it.next();
			System.out.println(s);
		}
	}
}
 

3)、请用LinkedList模拟栈数据结构的集合,并测试 

package cn.wen_03;

import java.util.ArrayList;
import java.util.Iterator;

/*
 * 需求:去除集合中自定义对象的重复值(对象的成员变量值都相同)
 * 
 * 我们按照和字符串一样的操作,发现出问题了。
 * 为什么呢?
 * 		我们必须思考哪里会出问题?
 * 		通过简单的分析,我们知道问题出现在了判断上。
 * 		而这个判断功能是集合自己提供的,所以我们如果想很清楚的知道它是如何判断的,就应该去看源码。
 * contains()方法的底层依赖的是equals()方法。
 * 而我们的学生类中没有equals()方法,这个时候,默认使用的是它父亲Object的equals()方法
 * Object()的equals()默认比较的是地址值,所以,它们进去了。因为new的东西,地址值都不同。
 * 按照我们自己的需求,比较成员变量的值,重写equals()即可。
 * 自动生成即可。
 */
public class ArrayListDemo3 {
	public static void main(String[] args) {
		// 创建集合对象
		ArrayList array = new ArrayList();

		// 创建学生对象
		Student s1 = new Student("林青霞", 27);
		Student s2 = new Student("林志玲", 40);
		Student s3 = new Student("凤姐", 35);
		Student s4 = new Student("芙蓉姐姐", 18);
		Student s5 = new Student("翠花", 16);
		Student s6 = new Student("林青霞", 27);
		Student s7 = new Student("林青霞", 18);

		// 添加元素
		array.add(s1);
		array.add(s2);
		array.add(s3);
		array.add(s4);
		array.add(s5);
		array.add(s6);
		array.add(s7);

		// 创建新集合
		ArrayList newArray = new ArrayList();

		// 遍历旧集合,获取得到每一个元素
		Iterator it = array.iterator();
		while (it.hasNext()) {
			Student s = (Student) it.next();

			// 拿这个元素到新集合去找,看有没有
			if (!newArray.contains(s)) {
				newArray.add(s);
			}
		}

		// 遍历新集合
		for (int x = 0; x < newArray.size(); x++) {
			Student s = (Student) newArray.get(x);
			System.out.println(s.getName() + "---" + s.getAge());
		}
	}
}
package cn.wen_03;

public class Student {
	private String name;
	private int age;

	public Student() {
		super();
	}

	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

}
发布了91 篇原创文章 · 获赞 16 · 访问量 1172

猜你喜欢

转载自blog.csdn.net/hewenqing1/article/details/103866614