Java 集合框架

一、集合框架

 

 

1.数组和集合都是容器,两者有什么区别呢?

数组长度是固定的,数组可以存储对象,可以存储基本数据类型。

集合长度是可变的,集合只能存储对象

 

2.为什么出现这么多容器呢?

因为每一个容器对数据的存储方式不一样,这个存储方式被称为数据结构。

 

二、常用方法

2.1 增加、删除

import  java.util.*;

/*
1,add方法的参数类型是Object。以便接收任意类型对象。
2,集合中存储的都是对象的引用(地址)。
*/
public class CollectionTest {
	public static void main(String[] args) {
		//创建一个集合容器,使用Collection接口的子类:Arraylist。
		ArrayList<String> al = new ArrayList<String>();
		
		//1.添加元素
		al.add("java01"); //add(Object o);
		al.add("java02");
		al.add("java03");
		al.add("java04");
			
		//2.获取个数。集合长度。
		System.out.println("size:"+al.size());
		
		//3.删除元素。
		al.remove("java01");
		//al.clear();
		
		//4.判断元素
		System.out.println("java03是否存在:" + al.contains("java03"));
		System.out.println("al是否为空:" + al.isEmpty());
		
		//打印集合。
		System.out.println(al);
	}
}

运行结果:
size:4
java03是否存在:true
al是否为空:false
[java02, java03, java04]

  

2.2 取交集、差集

public static void method1() {
	ArrayList<String> al1 = new ArrayList<String>();
	al1.add("java01");
	al1.add("java02");
	al1.add("java03");
	al1.add("java04");
	
	ArrayList<String> al2 = new ArrayList<String>();
	al2.add("java01");
	al2.add("java02");
	al2.add("java07");
	al2.add("java08");
	
//	al1.retainAll(al2); //取交集,al1中只会保留与al2中相同的元素。
//	System.out.println(al1);
//	System.out.println(al2);
	
	al1.removeAll(al2);
	System.out.println(al1);
	System.out.println(al2);
}

retainAll运行结果:
[java01, java02]
[java01, java02, java07, java08]
removeAll运行结果:
[java03, java04]
[java01, java02, java07, java08]

  

2.3 元素的取出

public void get_method() {
	ArrayList al = new ArrayList();
	al.add("java01");
	al.add("java02");
	al.add("java03");
	al.add("java04");
	
	Iterator it = al.iterator(); //迭代器
	
	while(it.hasNext()) {
		System.out.println(it.next());
	}
}

运行结果:
java01
java02
java03
java04

 

或者也可以这样写:

 for(Iterator it = al.iterator();it.hasNext();) {
	System.out.println(it.next());
}

  

三、List

3.1 list常见操作

package com.collection;

/*
 * Collection
 * 	|--List:元素有序。元素可以重复。因为该集合体系有索引。
 * 	|--Set:元素无序。元素不可以重复。
 * 
 * List:
 * 	特有方法:凡是可以操作角标的方法都是该体系特有的方法。
 * 
 * 	增:
 * 		add(index,element);
 * 		addAll(index,Collection);
 * 	删:
 * 		remove(index);
 * 	改:
 * 		set(index,element);
 * 	查:
 * 		get(index);
 * 		subList(from,to);
 * 		listIterator();
 * */

import java.util.*;

public class ListDemo {

	public static void main(String[] args) {
		ArrayList al = new ArrayList();
		
		al.add("java01");
		al.add("java02");
		al.add("java03");

		System.out.println("原集合是:"+al);	//原集合是:[java01, java02, java03]
		
		//在指定位置添加元素
		al.add(1, "java8");
		System.out.println("在指定位置添加元素后:"+al);	//在指定位置添加元素后:[java01, java8, java02, java03]
		
		//删除指定位置的元素
		al.remove(2);
		System.out.println("删除指定位置的元素后:"+al);	//删除指定位置的元素后:[java01, java8, java03]
		
		//修改元素
		al.set(1, "java007");
		al.add("java009");
		al.add("java009");
		al.add("java009");
		System.out.println("修改元素后:"+al); 	//修改元素后:[java01, java007, java03, java009, java009, java009]
		
		//通过角标获取元素
		System.out.println("获取元素:"+al.get(1));		//获取元素:java007
		
		//获取所有元素
		for(int i=0; i<al.size();i++) {
			System.out.println("al("+i+"):"+al.get(i));
		}
		
		//通过迭代器获取所有元素
		for(Iterator it = al.iterator();it.hasNext();) {
			System.out.println(it.next());
		}	
		
		//通过indexof获取对象位置
		System.out.println(al.indexOf("java007"));	//1
		System.out.println(al.lastIndexOf("java009"));	//5
		
		List sub = al.subList(1, 4);	// 包括开始,不包括结尾
		System.out.println("subList = " + sub);	//subList = [java007, java03, java009]
	}
}

  

3.2 列表迭代器

import java.util.*;

public class ListDemo {

	public static void main(String[] args) {
		//演示列表迭代器
		ArrayList al = new ArrayList();
		
		al.add("java01");
		al.add("java02");
		al.add("java03");
		
		Iterator it = al.iterator();
		
//		while(it.hasNext()){
//			System.out.println(it.next());
//		}
		
		//在迭代过程中准备添加或者删除元素
		while(it.hasNext()){
			Object obj = it.next();
			if(obj.equals("java02"))
				al.add("java000");
			
			System.out.println("obj = " + obj);
		}
	}
}

运行结果:
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at com.collection.ListDemo.main(ListDemo.java:44)
obj = java01
obj = java02

并发修改异常。
在用迭代器操作时,又用了集合的操作。

  

3.2.1 使用迭代器操作(局限性:只能删除)

//在迭代过程中准备添加或者删除元素
while(it.hasNext()){
	
	Object obj = it.next();
	
	if(obj.equals("java02"))
		it.remove();	//将java02的引用从集合中删除
	
	System.out.println("obj = " + obj);
}
System.out.println(al);

运行结果:
obj = java01
obj = java02
obj = java03
[java01, java03]

  

3.2.2 ListIterator

/*
 * List集合特有的迭代器:ListIterator。
 * ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。
 * 因为会发生ConcurrentModificationException异常。
 * 
 * 所以,在迭代时,只能使用迭代器的方法操作元素。
 * 可是Iterator方法有限,只能对元素进行判断、取出、删除的操作。
 * 如果想要其他操作,比如添加、修改等,就需要使用其子接口,ListIterator。
 * 
 * 该接口只能通过List集合的listIterator()方法调用。
 * */

public static void main(String[] args) {
	//演示列表迭代器
	ArrayList al = new ArrayList();
	
	al.add("java01");
	al.add("java02");
	al.add("java03");
	al.add("java008");
	
	ListIterator li = al.listIterator();
	while(li.hasNext()){
		Object obj = li.next();
		
		if(obj.equals("java02"))
			li.add("java009");
	}
	System.out.println(al);
}

运行结果:
[java01, java02, java009, java03, java008]

  

3.2.3 ListIterato API

 

3.3 List常见的子类对象

/*
 * Collection
 * 	|--List:元素有序。元素可以重复。因为该集合体系有索引。
 * 		|--ArrayList : 底层数据结构是数组结构。	特点:查询、修改速度很快。增加、删除速度很慢。 线程不同步。
 * 		|--LinkedList : 底层数据结构是链表结构。	特点:增删速度很快,查询稍慢。
 * 		|--Vector : 底层是数组数据结构。线程同步。被ArrayList替代了。
 * 
 * 	|--Set:元素无序。元素不可以重复。
 * 
 * */

  

3.4 Vector

/* 
 * 枚举是Vector特有的取出方式。
 * 枚举和迭代器很像。 
 * 
 * 其实枚举和迭代器一样。
 * 因为枚举的名称和方法名都过长,所以被迭代器取代。
 * */
public class VectorDemo {

	public static void main(String[] args) {
		Vector v = new Vector();
		v.add("java01");
		v.add("java02");
		v.add("java03");
		
		Enumeration en = v.elements();
		
		while(en.hasMoreElements()){
			System.out.println(en.nextElement());
		}
	}

}

  

3.5 LinkedList

3.5.1 LinkedList特有方法

package com.collection;

import java.util.*;
/*
 * LinkedList特有方法:
 * addFirst(E e);
 * addLast(E e);
 * 
 * getFirst();
 * getLast();
 * 获取元素但不删除元素。如果集合中没有元素,NoSuchElementException。
 * 
 * removeFirst();
 * removeLast();
 * 获取元素删除元素。如果集合中没有元素,NoSuchElementException。
 * 
 * 在JDK1.6出现了替代方法
 * offerFirst(E e);
 * offerLast(E e);
 * 插入元素
 * 
 * peekFirst(); 
 * peekLast(); 
 * 检索但不删除元素。如果此列表为空,则返回 null 。
 * 
 * pollFirst();
 * pollLast();
 * 检索并删除元素。如果此列表为空,则返回 null 。 
 * */
public class LinkedListDemo {

	public static void main(String[] args) {
		LinkedList link = new LinkedList();
		link.addFirst("java01");
		link.addFirst("java02");
		link.addFirst("java03");
		link.addFirst("java04");
		
		System.out.println(link);	//[java04, java03, java02, java01]
		System.out.println(link.getFirst());	//java04
		System.out.println(link.getLast());	//java01
		
		System.out.println(link.removeFirst());	//java04
		System.out.println(link);	//[java03, java02, java01]
		
		while(!link.isEmpty()){
			link.removeFirst();
		}
	}
}

  

3.5.1 LinkedList练习

import java.util.*;

/*
 * 使用LinkedList模拟堆栈或者队列数据结构
 * 
 * 堆栈:先进后出。如同杯子。
 * 队列:先进先出。如同水管。
 * 
 * */
public class LinkedListTest {

	public static void main(String[] args) {
		Queue q1 = new Queue();
		q1.myAdd("java01");
		q1.myAdd("java02");
		q1.myAdd("java03");
		q1.myAdd("java04");
		
		while(!q1.isNull()){
			System.out.println(q1.myGet());
		}
	}

}

class Queue{
	private LinkedList link;
	
	Queue(){
		link = new LinkedList();
	}
	
	public void myAdd(Object obj){
		link.addFirst(obj);
	}
	
	public Object myGet(){
		return link.removeLast();
	}
	
	public boolean isNull(){
		return link.isEmpty();
	}
}

  

3.5.2 LinkedList API

 

3.6 ArrayList

import java.util.*;

/*
 * 去除ArrayList集合中的重复元素
 * */
public class ArrayListTest {

	public static void main(String[] args) {
		ArrayList al = new ArrayList();
		al.add("aaa");
		al.add("bbb");
		al.add("bbb");
		al.add("def");
		al.add("ggg");
		singleElement(al);	//[aaa, bbb, def, ggg]
	}

	public static void singleElement(ArrayList al){
		//定义一个临时容器
		ArrayList al1 = new ArrayList();
		
		ListIterator li = al.listIterator();
		while(li.hasNext()){
			Object obj = li.next();
			if(al1.indexOf(obj) == -1){
				al1.add(obj);
			}
		}
		
		System.out.println(al1);
	}
}

  

import java.util.*;

/*将自定义对象存入ArrayList中,并删除重复元素*/
public class ArrayListTest2 {

	public static void main(String[] args) {
		ArrayList<Person> al = new ArrayList<Person>();
		al.add(new Person("张三",20));
		al.add(new Person("李四",25));
		al.add(new Person("王五",21));
		al.add(new Person("李四",25));
		
		ArrayList newAl = singleElement(al);
		
		Iterator<Person> it = newAl.iterator();
		while(it.hasNext()){
			Person p = it.next();
			System.out.println(p.getName() + "::" + p.getAge());
		}
	}

	public static ArrayList singleElement(ArrayList al){
		//定义一个临时容器
		ArrayList al1 = new ArrayList();
		
		ListIterator li = al.listIterator();
		
		while(li.hasNext()){
			Object obj = li.next();
			if(!al1.contains(obj)){
				al1.add(obj);
			}
		}
		
		return al1;
	}
}

class Person{
	private String name;
	private int age;
	Person(String name,int age){
		this.name = name;
		this.age = age;
	}
	public void setName(String name) {
		this.name = name;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName(){
		return name;
	}
	public int getAge(){
		return age;
	}
	public boolean equals(Object obj){
		if(!(obj instanceof Person))
			return false;
		 Person p = (Person)obj;
		 return p.name.equals(this.name) && p.age == this.age;
	}
}

运行结果:
张三::20
李四::25
王五::21

 

contains实际上是调用对象的equals方法。

 

  结论:

List集合判断元素是否相同,依据的是元素的equals方法。

 

其他:

remove、indexof底层其实用的也是元素的equals方法。

 

 

ArrayList API

 

 

 

posted on 2020-05-25 14:39  青柠锦鲤  阅读(179)  评论(0编辑  收藏  举报