Java基础-集合

 

一.集合的组成及概念

 

为什么出现集合类?

 

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

数组和集合类同时容器,有何不同?

数组虽然也可以存储对象,但是长度固定,集合长度是可变的。

数组中可以存储基本数据类型,集合只能存储对象。

集合类的特点

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。

 

二.Collection

 

 

1.collection  //2

(1).collection的组成    //3

List:元素是有序的,元素可以重复。因为该集合体系有索引。

set:元素是无序,元素不可以重复。

(2)演示collection的共性方法     //3

共性方法

1.add

2.获取个数。集合长度。

sop("size:"+a1.size());
打印集合
sop(a1); //这样就可以打印集合中所有元素

3.删除元素

清空集合
a1.clear();

4.判断元素(是否包含其他元素,或者是否为空)

sop("java03是否存在:"+a1.contains("java03"));
sop("集合是否为空?"+a1.isEmpty());

 

 

(3)迭代器(Iterator)

什么是迭代器呢?

 

a1.remove("java02");

sop(a1);

其实就是集合的取出元素的方式。


 

可以这么理解   容器就是一个大罐子    里面的对象就是罐子里的布娃娃  

迭代器就是抓娃娃的爪子    要抓娃娃爪子要移动  松开   抓紧之类的各种状态

(4)代码实例

import java.util.*;
class CollectionDemoText
{
	public static void main(String[] args)
	{
		method_get_size();
	}
	
	public static void sop(Object obj)
	{
	
		System.out.println(obj);
	}
	public static void method_get_size()
	{
		ArrayList a11 = new ArrayList();
		a11.add("java01");
		a11.add("java02");
		a11.add("java03");
		a11.add("java04");
		
		sop(a11);//打印所有元素



		ArrayList a12 = new ArrayList();
		a12.add("java011");
		a12.add("java021");
		a12.add("java031");
		a12.add("java041");
		a12.add("java01");

		sop(a12);//打印所有元素

//演示集合中是否为空,是否包含某一元素操作
	sop("a12是否为空--"+a12.isEmpty());
	sop("a12是否包含java01--"+a12.contains("java01"));
	sop("a12是否包含java03--"+a12.contains("java03"));



//演示通过迭代器获取集合元素操作
		Iterator t1 = a11.iterator();
		sop("下面获取集合中的元素");
		while(t1.hasNext())
		{
		
			sop(t1.next());
		}

//演示获取集合长度操作
		sop("下面打印集合的长度");
		sop("集合长度是----"+a11.size());

//演示获取相同元素操作
		//sop("下面是两个集合共有的元素");
		//a11.retainAll(a12);
		//sop(a11);

//演示删除操作
		sop("下面删除元素");
		a11.remove("java01");
		sop(a11);

//演示清空操作
		sop("下面清空集合");
		sop("集合a12"+a12);
		sop("开始清空");
		a12.clear();
		sop("集合a12"+a12);

	}
}

 

注意:!!!!!

retainall返回的是true(有相同),false(无相同)
然后改变了调用集合的元素,只保留了相同的元素!!!!

 

 

 

2.List

List:(元素都带着脚表)

(1)特有方法。凡是可以操作角标的方法都是该体系特有的方法。

1.增

 

 

add(index,element);
addAll(index,collection);  //从指定的位置开始,将指定 collection 中的所有元素插入到此列表中

2.删

remove(index);

3.改

set(index,element);

4.查

get(index);
subList(from,to);
ListIterator();!!!


 

(2)代码实例

 

import java.util.*;
class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		arrayList_method();
	}


	public static void  arrayList_method()
	{
		ArrayList a11 =new ArrayList();


		a11.add("java01");
		a11.add("java02");
		a11.add("java03");
		a11.add("java04");
		
		sop("打印所有元素");
		sop(a11);//打印所有元素
		
//在指定位置添加新元素 add(int index ,E element)
		//sop("在指定位置添加了新元素");
		//a11.add(2,"java99");
		//sop(a11);  //打印[java01,java02,java99,java03,java04],集合长度自动增加




//删除指定的元素
		//sop("删除指定位置的元素");
		//a11.remove(4);
		//sop(a11);  //打印[java01,java02,java99,java03]


//修改指定位置的元素
		//sop("修改指定位置的元素");
		//a11.set(2,"java007");
		//sop(a11);


//通过角标获取元素
		//sop("获取指定位置的元素");
		//sop("get(1):"+a11.get(1));
		//sop(a11);
	


//使用子迭代器listIterator
	//	sop("使用迭代器");
//		ListIterator li = a11.listIterator();  //注意写法!!!大小写的区别
	//	while(li.hasNext())
	//	{
	//****************************************************************************************	
	//		Object obj = li.next();
			///-----java01-----java02----java03----java04---
	//		    |		|	   |	    |	      |
	//		    |(1)	|(2)	   |(3)	    |(4)      |(5)


	//	当程序跑完ListIterator li = a11.listIterator();迭代器的位置在1处!!!
	// 当执行it.next(),就跑到(2)处


	//Iterator迭代器包含的方法有:
	///hasNext():如果迭代器指向位置后面还有元素,则返回 true,否则返回false
	//next():返回集合中Iterator指向位置后面的元素
	//remove():从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。


	//ListIterator迭代器包含的方法有:
	//add(E e): 将指定的元素插入列表,插入位置为迭代器当前位置之前


	//hasNext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false


	//hasPrevious():如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false


	//next():返回列表中ListIterator指向位置后面的元素


	//nextIndex():返回列表中ListIterator所需位置后面元素的索引


	//previous():返回列表中ListIterator指向位置前面的元素


	//previousIndex():返回列表中ListIterator所需位置前面元素的索引


	//remove():从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。对于每个 next 或 previous 调用,
	//只能执行一次此调用。只有在最后一次调用 next 或 previous 之后,尚未调用 ListIterator.add 时才可以执行该调用。


	//set(E e):从列表中将next()或previous()返回的最后一个元素返回的最后一个元素更改为指定元素e
//************************************************************************
	//		if(obj.equals("java02"))
	///		{
	//			sop(li);
	//			//Iterator的子迭代器可以添加元素
	//			li.add("java88");  //为什么是在java02后面添加元素,而不是在java04?????????上面有讲
	///		}							//因为迭代器的列表中这时候只有[java01,java02]  还是要看看!!!!
	//	}
	//	sop(a11);//[java01,java02,java88,java03,java04]


//使用父类迭代器,注意删除!!!
	//	sop("使用父类迭代器");
	//	sop(a11);
	//	Iterator it = a11.iterator();


	//	while(it.hasNext())
	//	{
		
		//	Object obj = it.next();
		//	if(obj.equals("java03"))
		//	{
		//		it.remove();   //为什么删的是当前元素!!!??????上面讲了,看一看
		//	}


		//	sop("OBJ--"+obj);//打印  OBJ--java01  OBJ--java02  OBJ--java03  OBJ--java04
		//						//因为移出只是引用被移除了,但是元素还是在内存中依然被obj使用。所以打印出来了
								//局部变量


	//	}
		
		
	//	sop(a11); //[java01,java02,java04],因为已经被移除了


		
	
	}
}

 

(3)List的组成(元素是有序的,元素可以重复。因为该集合体系有索引。) //3

  ArrayList:

  底层的数据结构使用的是数组结构。特点:查询速度很快,但是增删稍慢(因为要移位,元素多才能体现出来)。线程不同步(可变长度数组,开始默认容量为10,如果超过则增加百分之五十变成15.)
A--->B---->C---D

  LinkedList:

  底层使用的链表数据结构。特点:增删速度很快(因为只要改动部分,比如BC之间加个E,只要B知道E,E知道C就可以了),查询稍慢(因为一个一个关联,依次往下问)。

  Vector:(但是现在不用了)

  底层是数组数据结构,线程同步(如果多线程也不用这个)。特点:增删查找都慢。被ArrayList替代了(可变长度数组,开始默认容量为10,如果超过则增加百分之100,变成20,有点浪费.)

  淘汰原因

枚举就是vector特有的取出方式。

发现枚举和迭代器很像。

其实枚举和迭代是一样的。

因为枚举的名称以及方法的名称都过长。

所以被迭代器取代了。

枚举郁郁而终了。

 

class VectorDemo
{
public static void main(String[] args)
{
Vector v = new Vector();

v.add(“java01”);
v.add(“java02”);
v.add(“java03”);
v.add(“java04”);
Enumeration en = v.elements();
while(en.hasMoreElements())
{
system.out.println(en.nextElement());
}


}



}

(4)ArrayList   //3

 

1.ArrayList练习1 //4

需求:取出arrayList集合中的重复元素

arraylist或者linklist中的contain和remove用的都是equals


import java.util.*;


class CollectionDemoText
{
	public static void main(String[] args)
	{
		ArrayList a1 = new ArrayList();
		a1.add("java01");
		a1.add("java02");
		a1.add("java03");
		a1.add("java04");
		a1.add("java02");
		a1.add("java01");
		a1.add("java06");


		sop("原始集合");
		sop(a1);


		sop("取出相同的元素");
		a1 = removeSameElements(a1);
		sop("现在的集合");
		sop(a1);


	}


	public static void sop(Object obj)
	{
		System.out.println(obj);
	}


	public static  ArrayList removeSameElements(ArrayList a2)
	{
		
		ArrayList newa1 = new ArrayList();
		
		Iterator it = a2.iterator();


		while(it.hasNext())
		{
			Object obj = it.next();
			if(!newa1.contains(obj))
			{
				newa1.add(obj);
			
			}
		
		}
		
//**************************************************************	
	//开始没有使用临时容器,就靠迭代器迭代然后添加
	//	ListIterator it = a2.listIterator();


	//	while(it.hasNext())
	//	{
	//		Object obj = it.next();  
	//		sop("1");
	//		if(!a2.contains(obj))   //如果这么写永远也进不了if内,因为永远包括obj
	//		{
	//			sop("2");
	//			it.add("java22");
			
	//		}
		
	//	}
		
	//	return a2;
//****************************************************************
	return newa1;
	}
}


 

2.ArrayList 练习2

需求:将自定义对象作为元素存到ArrayList集合中,并取出重复元素。

比如:存人对象。同姓名同年龄,视为同一个人

//思路:
//1.对人描述,将数据封装进入对象
//2.定义容器,将人存入。
//3.取出
import java.util.*;


class  Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
		
	}
	
	//弄清一下为什么事在person里面复写???因为add里面的元素都是person类的
	public boolean  equals(Object obj)
	{
		if(!(obj instanceof Person))
			return false;
		Person p = (Person)obj ;
		
		System.out.println("p姓名:"+p.name+"p年龄 :"+p.age);
		System.out.println("姓名:"+this.name+"年龄:"+this.age);
		
		//String类复写了equals
		if((this.name.equals(p.name))&&(this.age == p.age))
		{
			System.out.println("true");
			return true;
		}
		else
		{
			System.out.println("false");
			return false;
		}


	
	}


	public String getName()
	{
		return name;
	}


	public int getAge()
	{
		return age;
	}
}


class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		ArrayList  a1 = new ArrayList();
		a1.add(new Person("daxiong",14));
		a1.add(new Person("daxiong1",16));
		a1.add(new Person("daxiong2",17));
		a1.add(new Person("daxiong3",14));
		a1.add(new Person("daxiong",16));
		a1.add(new Person("daxiong",14));
		a1.add(new Person("daxiong2",18));
		a1.add(new Person("daxiong3",17));


		a1 = removeSameElements(a1);
//打印集合中的元素
		Iterator it2 = a1.iterator();
		while(it2.hasNext())
		{
			Person p = (Person)it2.next();
			sop(p.getName()+"::"+p.getAge());
		}
//打印机集合中的元素
		sop("remove daxiong3"+a1.remove(new Person("daxiong3",14)));
	
	}


	


	public static  ArrayList removeSameElements(ArrayList a2)
	{
		
		ArrayList newa1 = new ArrayList();
		
		Iterator it = a2.iterator();


		while(it.hasNext())
		{
			Object obj = it.next();
			if(!newa1.contains(obj))
			{
				sop("add");
				newa1.add(obj);
			
			}
		
		}


	return newa1;
	}


}

 

(5)LinkList  //3

LinkedList:特有方法: //4

1.老的特有方法    //5

addFirst();
addLast();


getFirst();
getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementsException


removeFirst();
removeLast();
获取元素,但是元素被删除,如果集合中没有元素,会出现NoSuchElementsException

 

2.在JDK1.6出现了替代方法

offerFirst();
offerLast();

peekFirst();
peekLast(); 
获取元素,但不删除元素。如果集合中没有元素,会返回null


pollFirst();
pollLast();
获取元素,但是元素被删除,如果集合中没有元素,会返回null

 

3.代码实例

import java.util.*;
class CollectionDemoText
{
	public static void main(String[] args)
	{
		methodText();
	}
	public static void sop(Object obj)
	{
	
		System.out.println(obj);
	}


	public static void methodText()
	{
		LinkedList a11 = new LinkedList();


//倒序打印
		a11.offerFirst("java01");
		a11.offerFirst("java02");
		a11.offerFirst("java03");
		a11.offerFirst("java04");


		sop(a11);  //打印出[java04,java03,java02,java01]
//正序打印
		a11.offerLast("java05");
		a11.offerLast("java06");
		a11.offerLast("java07");
		a11.offerLast("java08");


		sop(a11);	//打印出[java04,java03,java02,java01,java05,java06,java07,java08]


//获取头尾元素
		//sop(a11.peekFirst());
		//sop(a11.peekLast());


//删除元素并取出
			sop("删除元素并取出");
		while(!a11.isEmpty())
		{
			sop(a11.pollLast());
			
		}
		sop("现在集合中的元素");
		sop(a11);  //因为删光了
	
	
	}


}





 

(2)linkedlist小练习  //4

需求:使用LinkedList模拟一个堆栈或者队列数据结构

堆栈:先进后出  如同一个杯子
队列:先进先出  First in First out FIFO 如同一个水管
import java.util.*;
 

class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}


	public static void main(String[] args)
	{
		Duilie_Duizhan a1= new Duilie_Duizhan();


		a1.myAdd("java01");
		a1.myAdd("java02");
		a1.myAdd("java03");
		a1.myAdd("java04");
		
		while(!a1.nullOrNot())
		{
			//sop(a1.duiLieGet());
			sop(a1.duiZhanGet());
		
		}
	
	}


	
}


class Duilie_Duizhan
{
	private LinkedList lk;
	Duilie_Duizhan()
	{
		lk = new LinkedList();
	}


	public void myAdd(Object obj)
	{
		lk.offerFirst(obj);
	}


	public Object duiZhanGet()
	{
		return lk.pollFirst();
	
	}


	public Object duiLieGet()
	{
	
		return lk.pollLast();
	}
	
	public boolean nullOrNot()
	{
		return lk.isEmpty();
	}
}

 

(6)总结

如果增删操作比较多就用linklist
设计增删但不频繁  linklist arraylist
如果还涉及到查找  用arraylist
如果实在不知道用什么就用arraylist

 

 

3.Set   //2

  (1)Set的组成(元素是无序(存入和取出的顺序不一定一致),元素不可以重复)   //3

1.HashSet:底层数据结构是哈希表。

HashSet是如何保证元素唯一性的呢?

是通过元素的两个方法,hashcode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true.
如果元素的hashcode值不同,不会调用equals.
 

 2.Treeset: //4

底层数据结构是二叉树。
保证元素唯一性的依据。

TreeSet是如何保证元素唯一性的呢?

(1)Treeset排序的第一种方式,让元素自身具备比较性

 

元素需要实现compareable接口,覆盖compareTo方法。

这种房也成为元素的自然排序,或者叫做默认顺序。

(2)TreeSet的第二种排序方式。

当元素自身不具备比较性时,或者具备的比较性不是所需要的。

集合需要实现compartor接口 ,然后覆盖compare方法 

 

注意:对于判断元素是否存在,以及删除等操作,依赖的方法元素的hashcode和equals方法,先判断hascode,再用equals(arraylist   lisnklist  都是用equals判断),这是数据结构的问题

   (2).HashSet   //3

1.代码实现

import java.util.*;
class Demo
{
}
class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);

	}

	public static void main(String[] args)
	{

	Demo d1 = new Demo();
	Demo d2 = new Demo();
	//这个地方再看看sop,到底打印什么了??????<p><span style="white-space:pre">	</span>//两个对象的内存地址,存的顺序不一定是放的顺序,取是按表(按哈希值存)的顺序来存,也可以自定义值</p><p> <span style="white-space:pre">	</span>//Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于: 
<span style="white-space:pre">	</span>//getClass().getName() + '@' + Integer.toHexString(hashCode())
</p>	sop(d1);  //会打印出哈希值,其实就是toString,然后toString中的hashcode
	sop(d2);  //会打印出哈希值//地址

	HashSet hs = new HashSet();
	sop(hs.add("java01"));  //true
	sop(hs.add("java01"));	//false//地址值一样,内容也一样
	hs.add("java02");
	hs.add("java03");
	hs.add("java04");
	hs.add("java05");

	Iterator it = hs.iterator();

	while(it.hasNext())
	{
		sop(it.next()); //打印出来是无序的
	}


	}

}

 

2.练习  //4

需求:往hashset集合中存入自定义对象姓名和年龄相同为同一个人,重复元素

import java.util.*;


class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		HashSet hs = new HashSet();
		hs.add(new Person("java01",13));
		hs.add(new Person("java02",14));
		hs.add(new Person("java03",15));
		hs.add(new Person("java01",13));
		hs.add(new Person("java01",14));
		hs.add(new Person("java02",17));


		Iterator it = hs.iterator();
		while(it.hasNext())
		{
			Person p = (Person)it.next();//迭代器的取出的对象才能强制转换成Person
			sop("-名字-"+p.getName()+"-年龄-"+p.getAge());
		}


	
	}
}


class Person
{
	private String name;
	private int age;
	Person(String name, int age)
	{
		this.name = name;
		this.age = age;
	}


	public int hashCode()  //自定义哈希值
	{
		System.out.println(this.name+"....hashCode");
		return age*2+this.name.hashCode();//<span style="font-family: 宋体;">随便写的,也可用</span><span style="font-family: 'Times New Roman';">/name.hashcode()*age</span><span style="font-family: 宋体;">但是怕超出范围,这么写的是为了保持哈希值唯一性</span>

	}

<span style="white-space:pre">	</span><p><span style="white-space:pre">	</span>//<span style="font-family:宋体;">在哈希表里先看哈希值</span></p>	public boolean equals(Object obj)
	{
		if(!(obj instanceof Person))
			return false;


		Person p = (Person)obj;
		System.out.println(this.name+"..equals.."+p.name);
		if((this.name == p.name)&&(this.age == age))
		{
			return true;
		}
		else
		{
			return false;
		}
	
	}
	
	public String getName()
	{
		return name;
	}


	public int getAge()
	{
		return age;
	}
}

 

(3)TreeSet   //3

   1.TreeSet基本特性

底层数据结构是二叉树。
保证元素唯一性的依据。

TreeSet是如何保证元素唯一性的呢?
(1)Treeset排序的第一种方式,让元素自身具备比较性
(2)TreeSet的第二种排序方式。

元素需要实现compareable接口,覆盖compareTo方法。

这种房也成为元素的自然排序,或者叫做默认顺序。

当元素自身不具备比较性时,或者具备的比较性不是所需要的。

集合需要实现compartor接口 ,然后覆盖compare方法 

 

2.练习1    //4

需求:往Treeset集合中存储自定义对象学生。想按照学生的年龄进行排序。记住排序时,当主要条件相同时,一定判断一下次要条件

 

 

第一种 让元素具备可比性

 

import java.util.*;
//import java.lang.*;


class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}


	public static void main(String[] args)
	{
	
		TreeSet a1 = new TreeSet();
		a1.add(new Student("java01",13)); //需要具备比较性蓝色字体,
		//否则,传两个进来就报错,一个不会(因为不用排序)
		a1.add(new Student("java02",14));
		a1.add(new Student("java03",13));
		a1.add(new Student("java01",13));
		a1.add(new Student("java01",17));


		Iterator it = a1.iterator();<p><span style="white-space:pre">		</span>/<span style="font-family:宋体;">明明只把</span><span style="font-family:Times New Roman;">age</span><span style="font-family:宋体;">跟</span><span style="font-family:Times New Roman;">name</span><span style="font-family:宋体;">排序,为什么就自动从小到大排序????下面的原理图!!!!!!!!!!</span></p><p>
</p>		while(it.hasNext())
		{
			Student s2 = (Student)it.next();
			sop("-名字-"+s2.getName()+"年龄"+s2.getAge());
			//-名字-java01年龄13
			//-名字-java03年龄13
			//-名字-java02年龄14
			//-名字-java01年龄17
		}
	}
}


class Student implements Comparable
{	
	private String name;
	private int age;
	Student(String name , int age)
	{
		this.name = name;
		this.age = age;
	
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
	
		return age;
	}


	public int compareTo(Object obj)
	{
</pre><pre name="code" class="java">
<p><span style="white-space:pre">		</span>//return 1; //<span style="font-family:宋体;">也就是说下一个元素比上一个大</span></p><p><span style="white-space:pre">		</span>//return -1;//<span style="font-family:宋体;">也就是说下一个元素比上一个小</span></p><p>//return 0;//<span style="font-family:宋体;">也就是说下一个元素等于上一个元素</span></p>
		if(!(obj instanceof Student))
		{
			throw new RuntimeException("不是学生对象");
		}
		Student s1 = (Student)obj;


		if(this.age > s1.age)
		{
			return 1;
		}
		else if(this.age <s1.age)
		{
			return -1;
		}
		else 
		{


			//String 方法有compareTo这个方法
			//ask码值大的就返回1,排后面面
			//-1排前面面
			//-名字-java01年龄13
			//-名字-java03年龄13
			//-名字-java02年龄14
			//-名字-java01年龄17
			return	this.name.compareTo(s1.name);
		
		
		}
		
	
	
	}
}

/明明只把age跟name排序,为什么就自动从小到大排序????下面的原理图

treeset底层结构是二叉树,之前回说为什么只是做了比较,但是却没排序却自动排序了,试音,return 1  return 0  return -1的原因,自动把小的那边放到左边(例如  20放到22的左下角),还有下面(例如,左下角有两个19,但是08小于09,所以就放他的左下角)


 

第二种让集合具备可比性.

当元素自身不具备比较性,或者具备的比较性不是所需要的。
这时需要让容器自身具备比较性。
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数


当两种排序都存在时,以比较器为主。
定义了一个类,实现conparator接口,覆盖compare方法(接口在treeset构造函数中)
 

import java.util.*;
//import java.lang.*;


class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}


	public static void main(String[] args)
	{
	
		TreeSet a1 = new TreeSet(new MyCompare());
		a1.add(new Student("java01",13)); //需要具备比较性蓝色字体,
		//否则,传两个进来就报错,一个不会(因为不用排序)
		a1.add(new Student("java02",14));
		a1.add(new Student("java03",13));
		a1.add(new Student("java01",13));
		a1.add(new Student("java01",17));


		Iterator it = a1.iterator();


		while(it.hasNext())
		{
			Student s2 = (Student)it.next();
			sop("-名字-"+s2.getName()+"年龄"+s2.getAge());
			//-名字-java01年龄13
			//-名字-java03年龄13
			//-名字-java02年龄14
			//-名字-java01年龄17
		}
	}
}


class Student 
{	
	private String name;
	private int age;
	Student(String name , int age)
	{
		this.name = name;
		this.age = age;
	
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
	
		return age;
	}


	
}


class MyCompare implements Comparator
{
	public int compare(Object obj1, Object obj2)
	{
		Student s1 = (Student)obj1;
		Student s2 = (Student)obj2;


		int num = s1.getName().compareTo(s2.getName());
		if(num == 0)
		{
		<span style="white-space:pre">	</span><p></p><p><span style="white-space:pre">		</span>//<span style="font-family:宋体;">为什么要用</span><span style="font-family:Times New Roman;">integer</span><span style="font-family:宋体;">,让他变成对象是为什么???是不是</span><span style="font-family:Times New Roman;">compareTo</span><span style="font-family:宋体;">的参数就是需要对象????对的 !!!!!</span></p><p><span style="white-space:pre">		</span>//<span style="font-family:宋体;">因为</span><span style="font-family:Times New Roman;">name </span><span style="font-family:宋体;">是</span><span style="font-family:Times New Roman;">String</span><span style="font-family:宋体;">类对象</span></p>		 return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		
		}
		
		return num;
	}
}

 

3.练习2   //4

需求:按照字符串长度排序。字符串本身具备比较性。但是他的比较方式不是所需要的。这时就只能使用比较器。

import  java.util.*;
class CollectionDemoText
{
	public static void main(String[] args)
	{
		TreeSet ts = new TreeSet(new StrLenComparator());


		ts.add("abcd");
		ts.add("cc");
		ts.add("cba");
		ts.add("hahaha");
		ts.add("abc");


		Iterator it = ts.iterator();
		while(it.hasNext())
		{
		System.out.println(it.next());
		}


	}


}






class StrLenComparator implements Comparator
{
	public int compare(Object o1,Object o2)
	{
		String  s1 = (String)o1;
		String  s2 = (String)o2;
		
		int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
		if(num == 0)
		{


			return  s1.compareTo(s2); //长度相同,判断内容是否相同
									  //String 其实继承了compareable这个接口,然后写了compareTo这个方法
									  //,例如 ac  ab,字符少的放前面顺序就是  ab  ac就是Ask码值相减
		}
	return	num;
	}




}

 

泛型   //2

1.泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制。

2.使用泛型的好处

1.将运行时期出现问题classcastException,转移到了编译时期,
方便于程序员解决问题,让运行事情问题减少,安全。
2.避免强制转换麻烦。

3.泛型格式:通过<>来定义遥操作的引用数据类型。

4.什么时候使用泛型?

通常在集合框架中很常见。
只要见到<>就要定义泛型(在API中可以看到例如arraylist<E>)
其实<>就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可

 

5.老版

class GenericDemo
{
	public static void main(String[] args)
	{
		ArrayList  al = new ArrayList(); //没有明确数据类型,所以引起安全隐患
		//ArrayList<String> a1 = new ArrayList<String>();//2这种是安全的
		al.add(“abc01”);
		al.add(“abc0991”);
		al.add(“abc014”);


		al.add(4);//al.add(new Interger(4));//在这里会引起运行报错,因为不能把 Interger(4)转换为string


		//把数据取到迭代器中2
		Iterator<String> it = al.interator();//明确了迭代器中的数据类型


		while(it.hasNext())
		{
		//String s = (string)it.next();//length是String特有的方法,所以强转
		String s = it.next();//写了代码2  就不用强转
		System.out.println(s+”:”+s.length());


		}




	}


}

 

6.新版

class GenericDemo
{
	public static void main(String[] args)
	{
		ArrayList<String> al = new ArrayList<String>();//定义一个arraylist容器,里面的元素是string型,指定类型为String


		al.add(“abc01”);
		al.add(“abc0991”);
		al.add(“abc014”);


		//al.add(4);//al.add(new Interger(4));


		Iterator<String> it = al.interator();//将数据取到迭代器,所以也必须说明迭代器也是string型的??????? 知道了,如果不这么做下面就要写成String s = (string)it.next();


		while(it.hasNext())
		{
		String s = it.next();
		System.out.println(s+”:”+s.length());


		}




	}


}

 

7.泛型的使用

import java.util.*;
class GenericDemo2
{
    public static void main(String[] args)
  {
<span style="white-space:pre">	</span>TreeSet<String> ts = new TreeSet<String>(new LenComparator());

<span style="white-space:pre">	</span>ts.add(“abcd”);
<span style="white-space:pre">	</span>ts.add(“cc”);
<span style="white-space:pre">	</span>ts.add(“cba”);
<span style="white-space:pre">	</span>ts.add(“aaa”);
<span style="white-space:pre">	</span>ts.add(“z”);
<span style="white-space:pre">	</span>ts.add(“hahaha”);

<span style="white-space:pre">	</span>Iterator<String> it = ts.iterator();
<span style="white-space:pre">	</span>while(it.hasNext())
<span style="white-space:pre">	</span>{
<span style="white-space:pre">	</span>String s = it.next();
<span style="white-space:pre">	</span>System.out.println(s); <span style="white-space:pre">	</span>       //打印aaa
 <span style="white-space:pre">					</span>abcd
 <span style="white-space:pre">					</span>cba
<span style="white-space:pre">					</span> cc
<span style="white-space:pre">					</span> hahaha
<span style="white-space:pre">					</span> z
<span style="white-space:pre">				</span>为了能够按字符长度打印,所以下面写了个比较的函数

   }





}




}


class LenComparator Implements Comparator<String>//有的没有参数(只有<>),不能写<>!!!一定要使用强转(代码3),有参数的叫泛型类 
						//没看懂???????????看懂了,compartor写了<String>,后面就不需要写代码3
{
<span style="white-space:pre">	</span>  public int compare(String o1,String o2)
<span style="white-space:pre">	</span>{
<span style="white-space:pre">		</span>//String s1 = (String)o1; // 代码3
<span style="white-space:pre">		</span>//String s2 = (String)o2;
<span style="white-space:pre">		</span>int num  = new Interger(o2.length()).compareTo(new Interger(o1.length()));

<span style="white-space:pre">		</span>if(num == 0)
<span style="white-space:pre">		</span>return  o2.compareTo(o1);
<span style="white-space:pre">	</span>return num;

<span style="white-space:pre">	</span>}


}

8.泛型类

 

class Worker
{
}

class student
{

}
class Tool   //通用性不好,每创建一个类都得重写一个

{
		private Worker w;
		public void setWorker(Worker w)
	      {
			this.w = w;
		}


		public Worker getWorker()
		{
			return w;
		}
}

 

1泛型前做法

class Tool   //通用性很好
{
	private Object obj;
	public void setObject (Object  obj)
	{
		this.obj= obj;
	}


	public Object setObject ()
	{
		return obj;
	}

}

 

2.泛型后做法

什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候
早期定义object来完成扩展。
现在定义泛型来完成扩展

class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}


public QQ getobject()
{
return q;
}


}

 

class GenericDemo3
{
public static void main(String[] args)
{
//泛型前     //看的不是很明白?????看明白了
//Tool t = new Tool();
//t.setObject (new Worker()); //这里如果new student()编译不会报错,因为是用objext来接收的
//Worker w = (Worker)t.getObject();


//泛型后
Utils<Worker> u = new Utils<Worker>();
U.setObject(new Worker());    //如果改成 new student();会在编译过程中报错,这就是使用泛型的好处,如果没用可能会在执行过程中报错
Worker   w = u.getObject();
}




}

 

三.Map

1.共性方法  //2

Map<K,V>

K-此映射所维护的键的类型

V-映射值的类型

 

map集合:该集合存储键值对,一堆一堆往里存。而且要保证键的唯一性。

1.添加

put(K key , V value)

putAll(Map<? extends K , ? extends V>m)

 

2.删除

clear()

remove(object  key)

 

3.判断

containsValue(Object value)

containskey(Object key)

isEmpty()

 

4.获取

get(Object  key)

size()

value()

entrySet()

keySet()

5.代码实现  //3

1.

import java.util.*;


class CollectionDemoText
{
	public static void sop(Object obj)
	{
	
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		Map<String,String> ha = new HashMap<String , String>();


		sop("put1-"+ha.put("01","dx1"));//打印null,因为会返回与key关联的旧值,如果key没有任何映射关系,则返回Null
		sop("put1-"+ha.put("01","dx2"));//打印dx1
		ha.put("03","dx1");
		ha.put("04","dx1");
		ha.put("05","dx7");
		
		sop(ha);


		sop("是否包含023这个键-"+ha.containsKey("023"));//打印false
		sop("是否包含dx4这个值-"+ha.containsValue("dx4"));//打印false
		sop("是否包含01这个键-"+ha.containsKey("01"));//打印false
		sop("是否包含dx2这个值-"+ha.containsValue("dx2"));//打印false




		sop("移出键07-"+ha.remove("07"));//返回与key关联的旧值,不存在就返回null
		sop("移出键05-"+ha.remove("05"));//dx7


		ha.put("06",null);//这么写但是多大没意义
		sop("获取键06的值"+ha.get("o6"));//指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null


		sop("获取键04的值"+ha.get("04"));




		//获取map集合中所有的值
		Collection<String> coll = ha.values();//values返回此映射中包含的值的 collection 视图


		sop(coll);  	//[dx2,dx1,dx1,null]
		sop(ha);	//{01 = dx2,03 = dx1, 04 = dx1 , 06 = null}
	
	}
}

 

2.keySet(),entrySet()  //4

get只能获取对应的一个键值,能不能获取很多键值,这就是写这个的原因

1.Set <k>keyset:将map中所有的键存入到set集合。因为set具备迭代器。

所有可以迭代方式取出所有的键,在根据get方法。获取每个键对应的值。

原理:map集合的取出原理:将map集合转成set集合。在通过迭代器取出。

2.Set<Map.entry<k,v>> entrySet: 将map集合中的映射关系存入到了set1集合中,而这个关系的数据类型就是:  Map.Entry

1.key取值方式

2.mapentry获取键值原理

import java.util.*;


class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}


	public static void main(String[] args)
	{
		Map<String,String> ma = new HashMap<String,String>();


		ma.put("02","dx1");
		ma.put("02","dx2");
		ma.put("03","dx3");
		ma.put("04","dx4");
		ma.put("05","dx5");
		ma.put("06","dx1");


//使用keySet迭代取值


//		Set<String> s1 = ma.keySet();//返回此映射中所包含的键(!!!!!)的 Set 视图


//		Iterator<String> it = s1.iterator();
//		while(it.hasNext())
//		{
//			String key = it.next();
//			String value = ma.get(key);
//			sop("key"+key+"-value-"+value);
//			//sop(it.next()+"对应的值"+ma.get(it.next()));//这样调用会出现noSuchElements
		<span style="white-space:pre">	</span>//因为会调用到06的时候已经是最后一个值了,再来个it.next(),就没值了,
			//就会抛出noSuchElements(没有元素可以迭代)
			
//		}




//使用entrySet迭代取值
	Set<Map.Entry<String,String>> e1 = ma.entrySet();//返回此映射所包含的映射关系(也就是<Map.entry<String,String>!!!!)的 Set 视图
	
	Iterator<Map.Entry<String,String>> it2 = e1.iterator();
	while(it2.hasNext())
	{
		Map.Entry<String,String> ma1 = it2.next();
		String key = ma1.getKey();
		String value = ma1.getValue();
		sop("key"+key+"-value-"+value);
	
	}


	}
}


//map.entry  其实entry也是一个借口,他是map借口中的一个内部接口
interface Map    //有map集合才能有entry(代表映射关系)关系,可以说是map集合的内部事物,可以直接访问map集合的内部元素,所以才定义在内部,能加
<span style="white-space:pre">		</span>//static的接口<span style="white-space:pre">	</span>一般都是内部接口!!!!!!!,因为只有接口在成员位置上才能加静态修饰符???(这个不太明白)
{
		public static interface entry
	{
		public abstract Object getkey();
		public abstract Object getvalue();


	}


}




class HashMap  implements map.Entry  //内部类来实现entry,外部类实现map
{
	class haha implements Map.entry
	{
		public Object getkey(){}
		public Object getvalue(){}
	}


}

 

2.Map的组成   //2

 

Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0

HashMap:底层是哈希表数据结构,允许存入null键null值。该集合是线程不同步的。jdk1.2

Treemap底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

注意:和set很像,其实大家。set底层就是使用了map集合!!!!!!!

(1)TreeMap练习1   //3

需求:对学生对象的年龄进行升序排序。

因为数据是以键值对形式存在的。
所以要使用可以排序的map集合。treemap.
//让元素具有比较性,还有如果按名字来排序应该怎么搞(试一试这个!!!!)搞定
 

方法一让元素具有可比性排序

import java.util.*;
class Student implements Comparable<Student>
{
	private String name;
	private int age;
	Student(String name , int age)
	{
		this.name = name;
		this.age = age;
	
	}
	public String getName()
	{
	
		return name;
	}


	public int getAge()
	{
		return age;
	}
	public int hashCode()
	{
		
		return age*2+name.hashCode(); //String类型有hashcode
	}


	public boolean equals(Object obj)
	{
		if(!(obj instanceof Student))
		{
			throw new ClassCastException("类型不匹配");
		}
		Student  p = (Student)obj;
		return ((this.name.equals(p.name)) && ((this.age == p.age)));//可不可以采用this.name.compareTo(p.name)
																	//equals返回的是正负
	}


	public int compareTo(Student s1)  //注意复写,要把参数类型也要复写,如果写Student s1会报错
									  //因为没写Comparable<Student>,所以只能写conpareTO(Object obj)
	{
		//if(!(obj instanceof Student))
	//	{
	//		throw new ClassCastException("比对类型不匹配")
	//	}
		
	//按照年龄排序******************************************************************************
		int num = (new Integer(s1.age)).compareTo(new Integer(this.age));


		if(num == 0)
		{
		
			return this.name.compareTo(s1.name); //返回的是1 , 0 , -1
		}
		else
		{
		
			return num;
		}
		
	//*******************************************************************************************
	
	//按照名字排序**************************************
		int num = s1.name.compareTo(this.name);
		if(num == 0)
		{
		
			return (new Integer(s1.age)).compareTo(new Integer(this.age));
		}
		else
		{
			return num;
		}


	//*****************************************************
	}




}






class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{


		//记住只有TreeMap才能排序!!!!!!!
		TreeMap<Student , String> ma = new TreeMap<Student , String>();
		ma.put(new Student("dx1",111),"beijing");
		ma.put(new Student("dx1",111),"tianjing");
		ma.put(new Student("dx2",13),"beijing");
		ma.put(new Student("dx3",45),"jiangxi");
		ma.put(new Student("dx5",52),"guangdong");
		ma.put(new Student("dx6",11),"fujian");
	
		sop(ma);


//用keySet取值
		sop("keySet.set取值排列入下");
		Set<Student> keyset = ma.keySet();
		Iterator<Student> it = keyset.iterator();//Iterator <Student> it =keySet.iterator();
		while(it.hasNext())
		{
			Student key = it.next();


			String value = ma.get(key);
			sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);
		}


//用entry.Set取值
		sop("ENtry.set取值排列入下");
		Set<Map.Entry<Student , String >> entryset = ma.entrySet();


		Iterator<Map.Entry<Student , String >> it1 = entryset.iterator();//Iterator<Map.Entry<Student , String >> it = entrySet.iterator();


		while(it1.hasNext())
		{
			Map.Entry<Student , String > ma1 = it1.next();
			
			Student key = ma1.getKey();
			String value = ma1.getValue();


			sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);
		
		}


	}


	
}



 

方法二  让集合具有比较性,用比较器比较

 

import java.util.*;
class Student
{
	private String name;
	private int age;
	Student(String name , int age)
	{
		this.name = name;
		this.age = age;
	
	}
	public String getName()
	{
	
		return name;
	}


	public int getAge()
	{
		return age;
	}
	public int hashCode()
	{
		
		return age*2+name.hashCode(); //String类型有hashcode
	}


	public boolean equals(Object obj)
	{
		if(!(obj instanceof Student))
		{
			throw new ClassCastException("类型不匹配");
		}
		Student  p = (Student)obj;
		return ((this.name.equals(p.name)) && ((this.age == p.age)));//可不可以采用this.name.compareTo(p.name)
																	//equals返回的是正负
	}


	
}




class MyCompare implements Comparator<Student>
{
	public int compare(Student s1 ,Student s2)
	{
		//按照年龄排序**********************************
		if(s1.getAge()>s2.getAge())
		{
			return -1;
		}
		else
		
		if(s1.getAge()<s2.getAge())
		{
		
			return 1;
		}
		else
		{
			return s1.getName().compareTo(s2.getName());
		}
		//************************************************
		//按照名字排序*********************************
		int num = s1.getName().compareTo(s2.getName());


		if(num == 0)
		{
		
			return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
		}
		else
		{
			return num;
		}
		//按照名字排序*********************************




	}
}


class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		TreeMap<Student , String> ma = new TreeMap<Student , String>(new MyCompare());
		ma.put(new Student("dx1",111),"beijing");
		ma.put(new Student("dx1",111),"tianjing");
		ma.put(new Student("dx2",13),"beijing");
		ma.put(new Student("dx3",45),"jiangxi");
		ma.put(new Student("dx5",52),"guangdong");
		ma.put(new Student("dx6",11),"fujian");
	
		sop(ma);


//用keySet取值
		sop("keySet.set取值排列入下");
		Set<Student> keyset = ma.keySet();
		Iterator<Student> it = keyset.iterator();//Iterator <Student> it =keySet.iterator();
		while(it.hasNext())
		{
			Student key = it.next();


			String value = ma.get(key);
			sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);
		}


//用entry.Set取值
		sop("ENtry.set取值排列入下");
		Set<Map.Entry<Student , String >> entryset = ma.entrySet();


		Iterator<Map.Entry<Student , String >> it1 = entryset.iterator();//Iterator<Map.Entry<Student , String >> it = entrySet.iterator();


		while(it1.hasNext())
		{
			Map.Entry<Student , String > ma1 = it1.next();
			
			Student key = ma1.getKey();
			String value = ma1.getValue();


			sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);
		
		}


	}


	
}

 

(2)TreeMap练习2     //3

需求:asdasfsdasdasgdfhert”获取该字符串中的字母出现的次数,希望打印结果:a(1)c(2)

通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
注意了,当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。

为什么使用map集合呢?
当数据之间存在着映射关系时,就要先想map集合。


思路:
1.将字符串转换成字符数组。因为要对每一个字母进行操作
2.定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3.遍历字符数组。
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合已经存在并有对应次数。
那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合,覆盖调用原来键所对应的值。
4.将map集合中的数据变成指定的字符串形式返回。

import java.util.*;
class CollectionDemoText
{
	public static void sop(Object obj)
	{
	
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		String s1 = charCount("asdasfsdasdasgdfhert");
		
		sop(s1);
		
	}
	public static String charCount(String str)
		{
		char [] chs = str.toCharArray();//变成数组
<p><span style="white-space:pre">				</span>//<span style="font-family:宋体;">泛型类接受的都是引用数据类型,所以要写基本的数据包装类</span><span style="font-family:Times New Roman;">(character,Interger),</span><span style="font-family:宋体;">而不是,</span><span style="font-family:Times New Roman;">char,int.</span></p>				TreeMap<Character , Integer> trma =new  TreeMap<Character , Integer>();
				int count = 0;
				for(int i = 0 ;i<chs.length;i++) //length , length(),size
				{
					if(!((chs[i]>= 'a' && chs[i] <='z')||(chs[i]>='A' && chs[i] <='Z')))//避免算其他字符被拿进来
					continue;
						Integer  value = trma.get(chs[i]);
						sop("第i个-"+i+"--是--"+chs[i]+"--值--"+value);
					


//这样也可以**************************************
					//	if(value == null)
					//	{
					//		trma.put(chs[i],1);
					//	}
					//	else
					//	{
					//		value = value+1;
					//		//value++;


					//		trma.put(chs[i],value);
						
					//	}
//这样也可以***************************************
						
					
					if(value != null)
					{
						count = value;
					}
					else
					{
						count = 0;     //这个地方换了一个字符就一定要清零,否则结果不对
					}
						count++;
						


					sop("第i个-"+i+"--是--"+chs[i]+"出现次数"+count);
					trma.put(chs[i],count);
					
				
				
				
				}
					//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
				StringBuilder sb = new StringBuilder();  //这个地方要好好看下,可以自定义打印的形式a(2)b(3)..


				Set<Map.Entry<Character , Integer>>  enset = trma.entrySet();


				Iterator<Map.Entry<Character , Integer>> it = enset.iterator();


				while(it.hasNext())
				{
					Map.Entry<Character , Integer> mapen = it.next();


					Character chs1 = mapen.getKey();
					Integer   in1 = mapen.getValue();
					sb.append(chs1+"("+in1+")");  
				}
				return sb.toString();




		
	
		}
}

3.Map扩展知识   //2

有两种方法,没看出来有很大差别????????

一对多,一般都是把学生封装成对象,用后者方法
map集合被使用是因为具备映射关系。
winsun 下属业务部,工程部


业务部 下属 dx1  01
dx2  02
dx3  03


都按照年龄排序


工程部 下属 dx4  22
dx5  23
dx6  24

方法1,用map嵌套

import java.util.*;
class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}


	public static void main(String[] args)
	{
		//这里可以写map.但是后面就不能写了,因为是接口,抽象的,不能实例化
		HashMap<String ,HashMap<String ,String > > winsun = new HashMap<String ,HashMap<String ,String > >();
		HashMap<String ,String > yewu = new HashMap<String ,String >();  //要放在前面,要不然后面无法添加
		HashMap<String ,String > gongcheng = new HashMap<String ,String >();
		
		
		winsun.put("yewubu",yewu);//这么写规不规范
		winsun.put("gongchengbu",gongcheng);


		
		yewu.put("dx1","22");
		yewu.put("dx2","25");
		yewu.put("dx3","26");


		
		gongcheng.put("dx4","27");
		gongcheng.put("dx5","25");
		gongcheng.put("dx6","24");


		sop("业务部人员信息");
		getPersonInfo(yewu);//获取业务部的人员信息   //如果想用toString怎么弄
		sop("工程部人员信息");
		getPersonInfo(gongcheng);//获取业务部的人员信息
		sop("获取部门信息");
		getDepartmentInfo(winsun);
		
		


	}


	public static void getDepartmentInfo(HashMap<String ,HashMap<String ,String > > tm)
	{


		//用keySet取值
		sop("用的是keyset");
		Set<String> keyset = tm.keySet();
		
		Iterator<String> it = keyset.iterator();


		while(it.hasNext())
		{
			String key = it.next();
			HashMap<String ,String > value =tm.get(key);
			sop("key-"+key+"-value-"+value);
		}
		
	
	
		sop("用的是entryset");
		//用entrySetq取值
		
		Set<Map.Entry<String ,HashMap<String ,String >>> enset = tm.entrySet();//传的是TreeMap,这里用用Map.entry();


		Iterator<Map.Entry<String ,HashMap<String ,String >>> it1 = enset.iterator();


		while(it1.hasNext())
		{
			Map.Entry<String ,HashMap<String ,String >> map = it1.next();
			
			String key = map.getKey();
			HashMap<String ,String > value = map.getValue();


			sop("key-"+key+"-value-"+value);


		}
		
	}




	//public static void getPersonInfo(Map tm)//会报错,不兼容性的类型,object无法转换成String
	public static void getPersonInfo(HashMap<String , String> tm)
	{


		//用keySet取值
		Set<String> keyset = tm.keySet();
		
		Iterator<String> it = keyset.iterator();
		while(it.hasNext())
		{
			String key = it.next();
			String value =tm.get(key);
			sop("key-"+key+"-value-"+value);
		}
		
	
		//用entrySetq取值
		
		Set<Map.Entry<String,String>> enset = tm.entrySet();//传的是TreeMap,这里用用Map.entry();


		Iterator<Map.Entry<String,String>> it1 = enset.iterator();


		while(it1.hasNext())
		{
			Map.Entry<String,String> map = it1.next()
			
			String key = map.getKey();
			String value = map.getValue();
			sop("key-"+key+"-value-"+value);


		}
		
	}
}

 

方法2,把学生做成一个集合

 

import java.util.*;


class Person
{
	private String name ;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}


	public String getName()
	{
		
		return name;
	}


	public int getAge()
	{
	
		return age;
	}


	public String toString()
	{
		return age+":::"+name;
	
	}
}




class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		HashMap<String ,List<Person>> czbk = new HashMap<String ,List<Person>>();
		
		List<Person> yure = new ArrayList<Person>();
		List<Person> jiuye = new ArrayList<Person>();


		czbk.put("yureban",yure);
		czbk.put("jiuyeban",jiuye);


		yure.add(new Person("dx1",11));
		yure.add(new Person("dx2",13));


		jiuye.add(new Person("dx2",11));
		jiuye.add(new Person("dx11",11));




		Iterator<String> it = czbk.keySet().iterator();


		while(it.hasNext())
		{
			String roomName = it.next();
			List<Person> room =czbk.get(roomName);


			System.out.println(roomName);
			getInfos(room);




		}
	
	}






	public static void getInfos(List<Person> List)
	{
		Iterator <Person> it = List.iterator();


		while(it.hasNext())
		{
			Person s = it.next();
			System.out.println(s);  //打印的其实就是toString


		}




		}
}

四.集合框架的工具类

1.作为工具类,它里面的方法全是静态的不需要对象
2.不需要保证唯一,用list,但是要排序,又只能用tree
所以这里就是collections

注意:
public static <T extends Compareable <? super T>>void sort(List<T> list)
这句话的意思是T 必须是Compareable 的子类,<? super T>这个代表T的父类,可以传person

list集合中的元素想要排序都要进行比较,如果不写extend Comparable限定T,传过来如果是没有比较性,如果运行就会出错,然后comparable也要写泛型一般写Comparable<T>现在Comparable<? super T>(? super T 表示用T或者用T的父类来比)

public static <T  extend Comparable<? super T>> void sort(List<T> list)

 

1.sort

import java.util.*;


class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}


	public static void main(String[] args)
	{
		List<String> list = new ArrayList<String>();
		list.add("asdasd");
		list.add("qwe");
		list.add("sf");
		list.add("dfgdf");
		list.add("vsf");
		list.add("sdfr");
		list.add("yujghy");
		sop(list);//按存入的顺序打印
		
		sop("按自然顺序排序");
		Collections.sort(list); //collections不能给set用,因为他自己有treeset
		sop(list);
		//用二分法查找 //这里传入的元素是具有比较性的
		int index = Collections.binarySearch(list , "sdfr");//系统的//如果找不到就返回插入点
		sop("index--"+index);
		//用二分法查找  //传入不具备比较性的元素,用比较器
		
		自己写一下二分法查找!!!!
		自己写一下二分法查找!!!!



		sop("按自己写的自然顺序排序");
		Collections.sort(list, new NormalCompartor()); //注意这里的写法!!
		sop(list);
		sop("按字符长度排序");
		Collections.sort(list, new StrLengthCompartor());
		sop(list);
		//获取长度最长的
		String max = Collections.max(list);
		sop("max--"+max);


		
	
	}
}


class StrLengthCompartor implements Comparator<String>
{
	public int compare(String s1 ,String s2)
	{
	
		if(s1.length()>s2.length())
		{
			return -1;
		}
		else
		if(s1.length()<s2.length())
		{
			return 1;
		}
		else
		{
			return	s1.compareTo(s2);
		}
	}
}


class NormalCompartor implements Comparator<String>
{
	public int compare(String s1 ,String s2)
	{
	
			return	s1.compareTo(s2);
		
	}
}

2.替换部分元素

import java.util.*;
class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	
	}
	public static void main(String[] args)
	{
		//replacePartDemo();
		replaceAllDemo();
	}


	public static void replacePartDemo()
	{
		List<String> list = new ArrayList<String>();


		list.add("abcd");
		list.add("aaa");
		list.add("qwe");
		list.add("z");
		list.add("qweqwe");
		list.add("sd");
		
		sop(list);

(1)使用替换函数replaceAll

sop("使用替换函数");
		//static <T> boolean replaceAll(List<T>,T oldVal , T newVal)
		boolean flag = Collections.replaceAll(list,"z","ww");
		sop(flag);
		sop(list);
	
	
	
	}

(2)替换所有元素

public static void replaceAllDemo()
	{
		List<String> list = new ArrayList<String>();


		list.add("fgj");
		list.add("fghr");
		list.add("se");
		list.add("z");
		list.add("czxc");
		list.add("bcv");
		
		sop(list);

 

(3)使用替换函数fill

sop("使用替换函数fill");
		//static <T> boolean replaceAll(List<T>,T oldVal , T newVal)
		Collections.fill(list,"ww");
		sop(list);
	
	
	
	}
}

 

3.实现反转

import java.util.*;

class CollectionDemoText
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args)
	{
		orderDemo();
	}


	public static void orderDemo()
	{
	//	TreeSet<String>  ts = new TreeSet<String>(new StrComparator());//使用自定义比较器 


	//	reverseOrder()返回一个比较器,它强行逆转实现了Comparable接口的对象Collection的自然顺序
	//	TreeSet<String>  ts = new TreeSet<String>(Collections.reverseOrder());//最简单的方法//系统自带,collections.reverseorder()返回的是一个比较器
	
	//  reverseOrder()返回一个比较器,它强行逆转指定比较器的顺序
	//	TreeSet<String>  ts = new TreeSet<String>(Collections.reverseOrder(new  StrComparator())); //强制反转已有的比较器,这个方法更牛
	//	TreeSet<String>  ts = new TreeSet<String>();//使用默认的比较方式
		ts.add("abcde");
		ts.add("aaa");
		ts.add("kkk");
		ts.add("ccc");


		Iterator it = ts.iterator();
		while(it.hasNext())
		{
			sop(it.next());
		}






	}




}




class StrComparator implements Comparator<String>    //自定义的比较器
{
	public int compare(String s1, String s2)  //在这里加了个分号,报错误,缺少方法主体,或声明抽象
	{
		return  s2.compareTo(s1);//正常的情况是s1.compareTo(s2),但是这里我们需要倒序
	}
}

 

五..Arrays:用于操作数组的工具类。

 

1.asList:将数组变成list集合

 

还有String变成char???????????

import java.util.*;
class CollectionDemoText
{
	public static void sop(Object obj)
	{
	
		System.out.println(obj);
	}

	public static void main(String[] args)
	{
		int[] arr = {2,4,5};
		sop(arr);//只会打印哈希值
		sop(Arrays.toString(arr)); //返回字符串形式[2,4,5]

	//把数组变成list集合有什么好处?
	

	//	可以使用集合的思想和方法来操作数组中的元素。
	//	注意:将数组变成集合,不可以使用集合的增删方法。
	//	因为数组的长度是固定。
	//	contains
	//	get
	//	indexof()
	//	subList();
	//	如果你增删。那么回反生unsupportedOperationException,
	//	sop(list);
	String[] arr = {"asd","qwe","sdf"} ;
	List<String> list = Arrays.asList(arr)
		
	
	
	
	}
}

 

六.一些扩展

 

1.集合变数组

Collection接口中的toArray方法。。传什么类型,返回就什么类型

 

 

import java.util.*;
class collectionToArray
{
public static void main(String[] args)
{
ArrayList<String> a1 = new ArrayList<String>();
 
a1.add(“abc1”);
a1.add(“abc2”);
a1.add(“abc3”);

 

1.指定类型的数组到底要定义多长呢?

当指定类型的数组长度小于集合的size,那么该方法内部会创建一个新的数组,长度为集合的size.

当指定类型的数组长度大于了集合的size,就不会新创建了数组,而是使用传递进来的数组。所以创建一个刚刚好的数组最优。(把 new String[0]改为new String[a1.size()]

 

2,为什么要将集合变数组?

为了限定对元素的操作,不需要进行增删了(集合长度可变,数组长度固定)

 

String[] arr = a1.toArray(new String[0](改成String[a1.size()]))//如果Sting[5](超过数组长度),会打印出[abc1,abc2,abc3,null,null]
System.out.println(Arrays.toString(arr)); //[abc1,abc2,abc3]
 
}
 
}

 

 

2.高级for循环

 

 

格式:

for(数据类型  变量名  : 被遍历的集合(Collection)或者数组)

{

 

}

注意:

对集合进行遍历。

只能获取集合元素。但是不能对集合进行操作

迭代器除了遍历,还可以进行remove集合中元素的动作。

如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

 

传统for和高级for有什么区别呢?

高级for有一个局限性。必须有被遍历的目标。

 

建议在遍历数组的时候,还是希望用传统的for.因为传统for可以定义脚标

 

 

import java.util.*;
class ForEachDemo
{
public static void main(String[] args)
{
ArrayList<String> a1 =new ArrayList<String>();
 
a1.add(“abc1”);
a1.add(“abc2”);
a1.add(“abc3”);
 
for(String s : a1)   //只能取出,不能改变连remove都不行(iterator可以)
{
//s= “KK”;//不会影响打印的结果
System.out.println(s);
}
 
System.out.println(a1);
/*
Iterator <String> it = a1.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
*/复杂了
 
*/
 
 
int []  arr = {3,5,1};
for(int i:arr)
{
System.out.println(“i:”+i);
}
 
HashMap<Integer,String> hm =new HashMap<Integer , String>();
hm.put(1,”a”);
hm.put(2,”b”);
hm.put(3,”c”);
 
Set<Integer> keySet = hm.keySet();
for(Integer i : keySet)
{
System.out.println(i+”::”+hm.get(i));//  打印 1::a  2::b  3::c
}
 
 
/*
Set<Map.Entry<Interger , String>> entrySet = hm.entrySet();
for(Map.Entry<Integer, String > me : entrySet)
*///复杂了可以简写成下面的
for(Map.Entry<Integer , String >   me : hm.entrySet())
{
System.out.println(me.getKey()+”------”+me.getValue());
}

 

 

3.方法的可变参数

 

在使用时注意:可变参数一定要定义在参数列表最后面。

例如

如果

show (“haha”,2,3,4,5,6);

则需要show函数这么写

public static void show(String str , int ...arr) 

 

class  ParamethodDemo
{
public static void main(String[] args)
{
/*
可变参数
其实就是上一种数组参数的简写形式。
不用每一次都手动的建立数组对象。
只要将要操作的元素作为参数传递即可。
隐式将这些参数封装成了数组。
 
*/
show(2);
show(2,3,4,5,6);//打印 5
 
}
 
public static void show(int...arr)(三个点)
{
 	//System.out.println(arr);//打印[I@de6ced](数组的哈希值)
System.out.println(arr.length);//打印 1  //这里用length?????不是应该用size吗
}
 
 
}

 

 

4.静态导入

 

/*

StaticImport 静态导入。

*/

import  java.util.*;

import  static java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

import  static java.lang.System.*;//导入了system类中所有静态成员。

(输出与不用写System.out,可以直接写out.)

当类名重名时,需要指定具体包名。

当方法重名时,指定具备所属的对象或者类。

 

class staticImport  extends Object

{

public static void main(String[]  args)

{

int[]  arr = {3,1,5};

sort(arr);

int index = binarySearch(arr ,1);  //排完序才能查找,因为用的是二分法

 

System.out.println(Arrays.toString(arr));//因为extends Object中也有tostring方法,但是不能传参数,先进入object,如果去掉Arrays会报错

当类名重名时,需要指定具体包名。

当方法重名时,指定具备所属的对象或者类。

 

 

 

System.out.println(“Index=”+index);

 

}

 

/*

class staticImport

{

public static void main(String[]  args)

{

int[]  arr = {3,1,5};

Arrays.sort(arr);

int index = Arrays.binarySearch(arr ,1);

 

System.out.println(Arrays.toString(arr));

 

System.out.println(“Index=”+index);

 

}

*/

 

}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值