【黑马程序员】集合框架(一) 第十五天

-------  android培训java培训java学习型技术博客、期待与您交流! ----------

知识点

Java集合框架支持规则集、线性表、队列和图,他们分别定义在接口Set、List、Quene和Map中。
规则集用于存储一组互不相同的元素。
线性表用于存储一个有序的元素集合。
图(Map)中存储的是键/值对。
Java集合框架中的所有实例类都实现了Cloneable和Serializable接口。所以,它们的实例都是可以复制和可序列化的。
规则集存储的是不重复的元素。若要在集合中存储重复的元素,就需要使用线性表。线性表不仅可以存储重复的元素,而且允许用户指定存储的位置。用户可以通过下标来访问线性表中的元素。
Java集合框架支持三种类型的规则集:散列集HashSet、链式散列集LinkedHashSet和树型集TreeSet。HashSet以一个不可预知的顺序存储元素;LinkedHashSet以元素被插入的顺序存储元素;TreeSet存储已排好的元素。所有方法都继承自Collection接口。
Java集合框架支持两种类型的线性表:数组线性表ArrayList和链表LinkedList。ArrayList是实现List接口的可变大小的数组。ArrayList中的所有方法都是在List接口中定义的。LinkedList是实现List接口的一个链表。除了实现List接口,该类还提供了可从线性表两端提取、插入以及删除元素的方法。
Vector类实现了List接口。Vector类和ArrayList是一样的,所不同的是它所包含的访问和修改向量的方法是同步的。Stack类扩展了Vector类,并且提供了几种对栈进行操作的方法。
Queue接口表示队列。PriorityQueue类为优先队列实现Queue接口。
Collection接口表示存储在规则集或线性表中元素的集合。Map接口将键值映射到元素,键值类似于下标。在List中,下标是整数。而在Map中,键值可以是任意类型的对象。图中不能包含重复的键值。一个键值至多可以对应一个值。Map接口提供了查询、更新、获取值集合和键值集合的方法。
Java集合框架支持三种类型的图:散列图HashMap、链式散列图LinkedHashMap和树形图TreeMap。对于定位一个值、插入一个映射和删除一个映射而言,HashMap是很高效的。LinkedHashMap支持图中的条目排序。HashMap类中的条目是没有顺序的,但LinkedHashMap中的条目可以按某种顺序来获取,该顺序既可以是它们插入图中的顺序(称为插入顺序),也可以是它们最后一次访问的时间顺序,从最早到最晚(称为访问顺序)。对于遍历排好序的键值,TreeMap是高效的。键值可以使用Comparable接口来排序,也可以使用Comparator接口来排序。

01)集合框架(概述)



02)共性方法

/*
 * 1:add方法的参数类型都是Object。以便于接受任意类型的对象。
 * 2:集合中存储的都是对象的引用(地址)。
 */
public class CollectionDemo {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
		System.out.println("---------------分割线---------------");
		method_2();
	}
	public static void method_1(){
		//创建一个容器。使用Collection接口的子类。ArrayList。
		ArrayList al = new ArrayList();
		//1:添加元素
		al.add("Java01");
		al.add("Java02");
		al.add("Java03");
		al.add("Java04");
		//2:打印集合
		sop("原集合 = " + al);
		sop("原集合 = " + al.clone());
		//3:判断元素。
		sop("判断Java02是否存在 = " + al.contains("Java02"));
		sop("判断集合是否为空 = " + al.isEmpty());
		//3:删除元素
		al.remove("Java03");//删除指定元素。
		al.remove(1);//删除下标为1的元素。
		sop("删除后 = " + al.clone());
		//4:获取个数。集合长度。
		sop("清空前长度 = " + al.size());
		//5:清空集合。
		al.clear();
		sop("清空后集合 = " + al.clone());
		sop("清空后长度 = " + al.size());
	}
	public static void method_2(){
		ArrayList a = new ArrayList();
		a.add("Java01");
		a.add("Java02");
		a.add("Java03");
		a.add("Java04");
		sop("改变前a = " + a);
		
		ArrayList b = new ArrayList();
		b.add("Java06");
		b.add("Java05");
		b.add("Java04");
		b.add("Java03");
		sop("改变前b = " + b);
		System.out.println("---------------分割线---------------");
		
		//取交集,a只会保留和b中相同的元素。
		sop(a.retainAll(b));
		sop("改变后a = " + a);
		sop("改变后b = " + b);
		System.out.println("---------------分割线---------------");
	}
}
运行结果如下图所示:


03)迭代器——Iterator

public class CollectionDemo_2 {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_get();
	}
	public static void method_get(){
		ArrayList a = new ArrayList();
		a.add("Java01");//add(Object obj)
		a.add("Java02");
		a.add("Java03");
		a.add("Java04");
		
		Iterator it_1 = a.iterator();//获取迭代器,用于取出集合中的元素。
		while(it_1.hasNext()){//如果仍有元素可以迭代,则返回 true。
			sop("While: " + it_1.next());//while代码相较for而言显的更少
		}
		System.out.println("-----分割线-----");
		for (Iterator it_2 = a.iterator(); it_2.hasNext();){
			sop("For: " + it_2.next());//细节:for能尽可能的少用内存空间。
		}
	}
}
运行结果如下图所示:


04)List集合共性方法

/*
 * Collection
 * 		|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
 * 		|--Set:元素是无序,元素不可以重复。
 * 
 * List:特有方法。凡是可以操作角标的方法都是该体系特有的方法。
 * 
 * 增:add(index, element):在列表的指定位置插入指定元素。
 * 		addAll(index, Collection):添加指定 collection 中的所有元素到此列表的结尾。
 * 删:remove(index):移除列表中指定位置的元素。
 * 改:set(index, element):用指定元素替换列表中指定位置的元素。
 * 查:get(index):返回列表中指定位置的元素。
 * 		subList(from, to):返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
 * 		listIterator();返回此列表元素的列表迭代器(按适当顺序)。
 * 		int indexOf(obj):获取指定元素的位置。
 * 		ListIterator listIterator():
 * 
 *
 */
public class ListDemo {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
	}
	public static void method_1(){
		ArrayList a = new ArrayList();
		//添加元素。
		a.add("Java01");
		a.add("Java02");
		a.add("Java04");
		sop("原集合是: " + a);
		
		//在指定位置添加元素。
		a.add(2, "Java03");
		sop("第一次修改后是: " + a);
		
		//删除指定位置元素。
		a.remove(3);
		sop("第二次修改后是: " + a);
		
		//通过下标获取元素。
		sop("get(1): " + a.get(1));
		System.out.println("-----分割线-----");
		
		//获取所有元素。
		for (int i = 0; i < a.size(); i++)
			System.out.println("a(" + i + ") = " + a.get(i));
		System.out.println("-----分割线-----");
		//迭代器,获取所有元素。
		Iterator it = a.iterator();
		while(it.hasNext())
			sop("next = " + it.next());
	}
}
运行结果如下图所示:


05)ListIterator

/*
 *  List集合特有的迭代器。
 * 		ListIterator是Iterator的子接口。
 * 
 * 在迭代时,不可以通过集合对象的方法操作集合中的元素。
 * 因为会发生ConcurrentModificationException异常。
 * 
 * 所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,
 * 只能对元素进行判断,取出,删除的操作。
 * 如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。
 * 
 * 该接口只能通过List集合的listIterator方法获取。
 */
public class ListDemo_2 {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
		System.out.println("----------------------分割线----------------------");
		method_2();
		System.out.println("----------------------分割线----------------------");
		method_3();
	}
	public static void method_3(){
		ArrayList a = new ArrayList();
		//添加元素。
		a.add("Java01");
		a.add("Java02");
		a.add("Java03");
		a.add("Java04");
		sop("原a = " + a);
		
		for (ListIterator it = a.listIterator(); it.hasNext();){
			sop("(前面是否有元素)hasPrevious = " + it.hasPrevious());//判断前面是否有元素。
			Object obj = it.next();
			if (obj.equals("Java01"))
				it.add("Java添加");
			if (obj.equals("Java03"))
				it.set("Javahah");
			sop("(打印元素)obj = " + obj);
			System.out.println("------------------------------------------------");
		}
		sop("修改后a = " + a);
	}
	public static void method_2(){
		ArrayList a = new ArrayList();
		//添加元素。
		a.add("Java01");
		a.add("Java02");
		a.add("Java03");
		a.add("Java04");
		
		//在迭代过程中,准备添加或者删除元素。
		for (Iterator it = a.iterator(); it.hasNext();){
//			sop("Next = " + it.next());
			Object obj = it.next();//取出元素。
			if(obj.equals("Java01"))
				it.remove();//将Java01的引用在集合中删除。
			sop("obj = " + obj);	
		}
		sop("a = " + a);
	}
	public static void method_1(){
		ArrayList a = new ArrayList();
		//添加元素。
		a.add("Java01");
		a.add("Java02");
		a.add("Java03");
		a.add("Java04");
		
		//通过indexOf获取对象的位置。
		sop("indexOf = " + a.indexOf("Java03"));
		//通过指定下标获取集合中的元素。
		List sup = a.subList(1, 3);
		sop("sup = " + sup);
	}
}
运行结果如下图所示:


06)List集合具体对象的特点

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

07)Vector中的枚举

/*
 * 枚举就是Vector特有的取出方式。
 * 发现枚举和迭代器很像。其实枚举和迭代器是一样的。
 * 
 * 因为枚举的名称以及方法的名称都过长。所以枚举被迭代器取代了。
 */
public class VectorDemo {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
		method_2();
	}
	public static void method_1(){
		Vector v1 = new Vector();
		v1.add("Java01");
		v1.add("Java02");
		v1.add("Java03");
		v1.add("Java04");
		sop("v1 = " + v1);
		System.out.println("-----------------------------------------");
		for (ListIterator it = v1.listIterator(); it.hasNext();){
			sop("it = " + it.next());//取数据
		}
		System.out.println("-----------------------------------------");
	}
	public static void method_2(){
		Vector v2 = new Vector();
		v2.add("Java01");
		v2.add("Java02");
		v2.add("Java03");
		v2.add("Java04");
		sop("v2 = " + v2);
		System.out.println("-----------------------------------------");
		for (Enumeration<E> en = v2.elements(); en.hasMoreElements();){//早期方式。
			sop("en = " + en.nextElement());
		}
		System.out.println("-----------------------------------------");
	}
}
运行结果如下图所示:


08)LinkedList

/*
 * LinkedList特有方法:1.6之前。
 * 		addFirst():将指定元素插入此列表的开头。
 * 		addLast():将指定元素添加到此列表的结尾。
 * 		getFirst():返回此列表的第一个元素。
 * 		getLast():返回此列表的最后一个元素。
 * 			:获取元素,但不删除元素。长度不变。
 * 			:如果集合中没有元素,会出现NoSuchElementException。
 * 		removeFirst():移除并返回此列表的第一个元素。
 * 		removeLast():移除并返回此列表的最后一个元素。
 * 			:获取元素,并且删除元素。
 * 			:如果集合中没有元素,会出现NoSuchElementException。
 * 
 * 1.6开始出现的替代:
 * 		offerFirst():
 * 		offerLast():
 * 		peekFirst():
 * 		peekLast():
 * 		poolFirst():
 * 		poolLast():
 */
public class LinkedListDemo {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
		method_2();
	}
	public static void method_1(){
		LinkedList link = new LinkedList();
		link.addFirst("(2)Java01");
		link.addLast("(3)Java02");
		link.addFirst("(1)Java03");//将元素添加到此列表的开头。
		link.addLast("(4)Java04");//将元素添加到此列表的尾部。
		sop("add = " + link);
		sop("getFirst = " + link.getFirst());
		sop("getLast = " + link.getLast());
		System.out.println("------------------------------------------------------------------");

	}
	public static void method_2(){
		LinkedList link = new LinkedList();
		link.offerFirst("(1)Java01");//将元素添加到此列表的开头。
		link.offerFirst("(2)Java02");
		link.offerFirst("(3)Java03");
		link.offerFirst("(4)Java04");
		sop("(原)add = " + link);
		sop("remove(0) = " + link.remove(0));//获取下标为0的元素,并且删除该元素。
		sop("(改)add = " + link);
		System.out.println("------------------------------------------------------------------");
		
		for(; !link.isEmpty(); ){
			sop("jdk1.6 poolLast = " + link.pollLast());
		}
	}
}
运行结果如下图所示:


09)LinkedList(练习)

/*
 * 使用LinkedList模拟一个堆栈或者队列数据结构。
 * 堆栈:先进后出。如同一个杯子。
 * 队列:先进先出。如同一根水管。
 */
public class LinkedListTest {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		useDuiLie();
		System.out.println("-----------------------");
		uesDuiZhan();
	}
	public static void useDuiLie(){
		DuiLie dl = new DuiLie();
		dl.dlAdd("Java01");
		dl.dlAdd("Java02");
		dl.dlAdd("Java03");
		dl.dlAdd("Java04");
		while (!dl.isNull())
			sop("队列: " + dl.dlGet());
	}
	public static void uesDuiZhan(){
		DuiZhan dz = new DuiZhan();
		dz.dzAdd("Java01");
		dz.dzAdd("Java02");
		dz.dzAdd("Java03");
		dz.dzAdd("Java04");
		while (!dz.isNull())
			sop("堆栈: " + dz.dzGet());
	}
}
class DuiLie{
	private LinkedList link;
	DuiLie(){
		link = new LinkedList();
	}
	public void dlAdd(Object obj){
		link.offerFirst(obj);//添加元素在队列最开头。
	}
	public Object dlGet(){
		return link.pollLast();//从队列尾部开始取元素。
	}
	public boolean isNull(){
		return link.isEmpty();
	}
}

class DuiZhan{
	private LinkedList link;
	DuiZhan(){
		link = new LinkedList();
	}
	public void dzAdd(Object obj){
		link.offerFirst(obj);//添加元素在队列最开头。
	}
	public Object dzGet(){
		return link.pollFirst();//从队列开头开始取元素。
	}
	public boolean isNull(){
		return link.isEmpty();
	}
}
运行结果如下图所示:


10)ArrayList(练习一)

/*
 * 去除ArrayList中重复的元素。
 */
public class ArrayListTest {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
	}
	public static void method_1(){
		ArrayList al = new ArrayList();
		al.add("Java0");
		al.add("Java1");
		al.add("Java3");
		al.add("Java2");
		al.add("Java1");
		al.add("Java2");
		sop("Al = " + al);
		sop("show(NewAl) = " + show(al));
	}
	public static List show(ArrayList al){
		ArrayList newAl = new ArrayList();//创建一个新集合。
		for (Iterator<E> it = al.iterator(); it.hasNext();){
			Object obj = it.next();//依次打印元素
			if (!newAl.contains(obj))//如果新集合中包不含有原集合的元素
				newAl.add(obj);//添加元素。
		}
		return newAl;//返回新集合。
	}
}
运行结果如下图所示:


11)ArrayList(练习二)

/*
 * 将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
 * 比如:存人元素。同姓名,同年龄,视为同一元素。
 * 
 * 思路:
 * 1:对人描述,将数据封装人对象。
 * 2:定义容器,将人存入。
 * 3:取出。
 * 
 * List集合判断元素是否相同,依据的是元素的equals方法。
 */
public class ArrayListTest_2 {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
		method_2();
	}
	public static void method_2(){
		ArrayList al = new ArrayList();
		al.add(new Person("汤姆01号", 10));
		al.add(new Person("汤姆02号", 10));
		al.add(new Person("汤姆01号", 10));
		al.add(new Person("杰瑞01号", 11));
		al.add(new Person("杰瑞02号", 11));
		al.add(new Person("杰瑞01号", 11));
		List al2 = show(al);
		for (Iterator it = al2.iterator(); it.hasNext();){
			Person p = (Person)it.next();
			sop(p.getName() + " " + p.getAge());
		}
	}
	public static void method_1(){//示例
		ArrayList al = new ArrayList();
		al.add(new Person("汤姆01号", 10));
		al.add(new Person("汤姆02号", 10));
		al.add(new Person("汤姆01号", 10));
		al.add(new Person("杰瑞01号", 11));
		al.add(new Person("杰瑞02号", 11));
		al.add(new Person("杰瑞01号", 11));
		for (Iterator it = al.iterator(); it.hasNext(); ){
			Person p = (Person)it.next();
			sop(p.getName() + " " + p.getAge());
		}
		System.out.println("------------------------------");
	}
	
	public static List show(ArrayList al){
		ArrayList newAl = new ArrayList();//创建一个新集合。
		for (Iterator it = al.iterator(); it.hasNext();){
			Object obj = it.next();//依次打印元素
			if (!newAl.contains(obj))//如果新集合中包不含有原集合的元素
				newAl.add(obj);//添加元素。
		}
		return newAl;//返回新集合。
	}
}

class Person{
	private String name;
	private int age;
	Person(String name, int age){
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj){
		if (!(obj instanceof Person))
			return false;
		Person p = (Person)obj;
		return this.name.equals(p.name) && this.age == p.age;
	}
	public String getName(){
		return name;
	}
	public int getAge(){
		return age;
	}
}
运行结果如下图所示:


12)HashSet

/*
 * |--Set:元素是无序(存入顺序和元素的位置不一致),元素不可以重复。
 * 		|--HashSet:底层的数据结构是哈希表。
 * 		|--TreeSet:
 * 
 * Set集合的功能和Collection接口的功能是一致的。
 */
public class HashSetDemo {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
	}
	public static void method_1(){
		HashSet hs = new HashSet();//创建一个HashSet集合。无序。
		sop(hs.add("Java01"));//判断为true
		sop(hs.add("Java01"));//判断为false
		hs.add("Java02");
		hs.add("Java03");
		sop(hs.add("Java03"));//判断为false
		hs.add("Java04");
		for (Iterator it = hs.iterator(); it.hasNext();){
			sop(it.next());
		}
	}
}
运行结果如下图所示:


13)HashSet存储自定义对象——复写hashCode和equals方法

/*
 * |--Set:元素是无序(存入顺序和元素的位置不一致),元素不可以重复。
 * 		|--HashSet:底层的数据结构是哈希表。
 * 			HashSet是如何保证元素唯一性的呢?
 * 			是通过元素的两个方法,hasCode和equals来完成的。
 * 			如果元素的hashCode值相同,才会判断equals是否为true。
 * 			如果hashCode的值不同,就不会判断equals。
 * 		|--TreeSet:
 * 
 * Set集合的功能和Collection接口的功能是一致的。
 */
public class HashSetTest_1 {
	public static void sop(Object obj){
		System.out.println(obj);
	}
	public static void main(String[] args) {
		method_1();
	}
	public static void method_1(){
		HashSet hs = new HashSet();
		hs.add(new Person_2("汤姆(1)", 10));
		hs.add(new Person_2("汤姆(2)", 10));
		sop(hs.add(new Person_2("汤姆(2)", 10)));//判断为false
		hs.add(new Person_2("汤姆(3)", 10));
		sop(hs.add(new Person_2("汤姆(3)", 10)));//判断为false
		hs.add(new Person_2("汤姆(4)", 10));
		for (Iterator it = hs.iterator(); it.hasNext();){
			Person_2 p = (Person_2)it.next();
			sop(p.getName() + " :: " + p.GetAge());
		}
	}
}
class Person_2{
	private String name;
	private int age;
	Person_2(String name, int age){
		this.name = name;
		this.age = age;
	}
	public int hashCode(){//细节:复写hashCode。集合底层内部自动调用。
		return name.hashCode() + age * age;
	}
	public boolean equals(Object obj){//细节:复写equals。集合底层内部自动调用。
		if (!(obj instanceof Person_2))
			return false;
		Person_2 p = (Person_2)obj;
		return this.name.equals(p.name) && this.age == p.age;
	}
	public String getName(){
		return name;
	}
	public int GetAge(){
		return age;
	}
}	
运行结果如下图所示:


14)HashSet判断和删除的依据

对于元素是否存在,以及删除等操作,依赖的方法是元素的hashCode和equals方法。

附言:我是Java新人,如有错误的地方请指出。
                         每天学习一点点,纠错一点点,进步很大点。


-------  android培训java培训java学习型技术博客、期待与您交流! ----------


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值