集合与框架(二)

转载出处:http://m.blog.csdn.net/article/details?id=44153345
三.List


1.概述:
元素是有序的,元素可以重复。
List本身是Collection接口的子接口,具备了Collection的所有方法。
2.List包括:
          1)ArrayList:底层的数据结构是数组,线程不同步,ArrayList替代了Vector,查询元素的速度非常快。
          2)LinkedList:底层的数据结构是链表,线程不同步,增删元素的速度非常快。(改变链表的地址)
          3)Vector:底层的数据结构就是数组,线程同步的,Vector无论查询和增删都非常慢。被ArrayList替代了。

3.List特有方法:凡是可以操作角标的方法。
1)添加:
add(index,element) :在指定的索引位插入元素。Index是相应的位置,element是相应元素。
addAll(index,collection) :在指定的索引位插入一堆元素。collection是一个对象。
2)删除:
remove(index) :删除指定索引位的元素。返回被删的元素。
3)修改:
         set(index,element):修改指定位置的元素。
4)查找:
         get(index):通过角标获取元素。List集合因为角标有了自己的获取元素的方式:遍历。
         subList(from,to):获取部分对象元素。(包含头,不包含尾)
         listIterator():List特有的迭代器。
         indexOf(obj) :获取指定元素第一次出现的索引位,如果该元素不存在返回-1;所以,通过-1,可以判断一个元素是否存在。


4.ListIterator:
1)概述:ListIterator是List集合特有的迭代器,是Iterator的子接口。


2)在迭代器时,只能用迭代器的方法操作元素。可是Iterator方法是有限的,只能对元素进行判断,取出,删除的操作。
如果想要其他的操作,如添加、修改等,就需要使用其子接口:ListIterrator。该接口只能通过List集合的ListIterator方法获取。
(代码 ListIteratorDemo.Java):

import java.util.*;
class ListIteratorDemo 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		ArrayList a = new ArrayList();
		a.add("java01");
		a.add("java02");
		a.add("java03");
		sop(a);

		Iterator it = a.iterator();
		while(it.hasNext())
		{
			Object obj = it.next();
			if(obj.equals("java02"))
/* 在迭代时,不可以通过集合对象的方法操作集合中的元素。(a.add("java000");)
   因为会发生ConcurrentModificationException异常。
   导致的原因是:
   集合引用和迭代器引用在同时操作元素,通过集合获取到对应的迭代器后,
   在迭代中,进行集合引用的元素添加,迭代器并不知道,所以会出现异常情况。
*/
			    //a.add("java000");
				it.remove();//将java02的引用从集合中删除了。
			sop("obj= "+obj);
		}

		sop(a);
	}
}

3)、ListIterator特有的方法:
                           add(obj); 增加。
                           set(obj); 修改为obj。
                           hasPrevious(); 判断前面有没有元素。
                           previous(); 取前一个元素。


5.可变长度数组的原理:
当元素超出数组长度,会产生一个新数组,将原数组的数据复制到新数组中,再将新的元素添加到新数组中。
ArrayList:是按照原数组的50%延长。构造一个初始容量为 10 的空列表。
Vector:是按照原数组的100%延长。


6.枚举Enumeration:
枚举就是Vector特有的取出方式。
例如:
Vector v=new Vector(); 
    for(Enumeration e=v.elements();e.hasMoreElements();) 

    System.out.println(e.nextElements()); 



7.LinkedList:
LinkedList:特有方法:
addFirst();
addLast();


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


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


在JDK1.6出现了替代方法。
offerFirst();
offerLast();


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


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


练习:(代码 LinkedListDemo.java):

//使用LinkedList模拟一个队列数据结构
//队列:先进先出
import java.util.*;
class LinkedListDemo
{
	public static void main(String[] args) 
	{
		DuiLie d = new DuiLie();
		d.add("java01");
		d.add("java02");
		d.add("java03");
		
		while(!d.isNull())
		{
			System.out.println(d.get());
		}
	}
	
}
class DuiLie
{
	private LinkedList link;
	DuiLie()
	{
		link = new LinkedList();
	}
	public void add(Object obj)
	{
		link.addFirst(obj);
	}
	public Object get()
	{
		return link.removeLast();
	}
	public boolean isNull()
	{
		return link.isEmpty();
	}
}

8.练习题:
(代码 ArrayListDemo.java):

//去除ArrayList集合中的重复元素。
import java.util.*;
class ArrayListDemo 
{
	public static void main(String[] args) 
	{
		ArrayList a = new ArrayList();
		
		a.add("java01");
		a.add("java02");
		a.add("java03");
		a.add("java01");

		System.out.println(a);
		System.out.println(quchu(a));
	}
	public static ArrayList quchu(ArrayList a)
	{
		ArrayList newa = new ArrayList();
		Iterator it = a.iterator();
		while(it.hasNext())
		{
			Object obj = it.next();
			if(!newa.contains(obj))
				newa.add(obj);
		}
		return newa;

	}
}

(代码 ArrayListDemo2.java):

/*
将自定义对象作为元素存到ArrayList集合中,并去除重复元素。
比如:存人对象,同姓名同年龄,视为同一个人,为重复元素。
*/
import java.util.*;
class ArrayListDemo2
{
	public static void main(String[] args) 
	{
		ArrayList a = new ArrayList();
		a.add(new Person("zhangsan",10));
		a.add(new Person("lisi",11));
		a.add(new Person("wangwu",12));
		a.add(new Person("lisi",11));
		//sop(a);
		a = quchu(a);
		Iterator it = a.iterator();
		while(it.hasNext())
		{
            Object obj = it.next();
			Person p = (Person)obj;
			sop(p.getName()+"..."+p.getAge());
		}
	}
	public static ArrayList quchu(ArrayList a)
	{
		ArrayList newa = new ArrayList();
		Iterator it = a.iterator();
		while(it.hasNext())
		{
			Object obj = it.next();
			if(!newa.contains(obj))//contains依据的是equals方法。
				newa.add(obj);
		}
		return newa;

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

class Person
{
	private String name;
	private int age;
	Person(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	//List集合判断元素是否相同,依据的是元素的equals方法。
	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;
	}
}
/*
注意:
对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
*/


四.Set


1.理解:
无序(存入和取出顺序有可能不一致),不可以存储重复元素。必须保证元素唯一性。
Set集合的功能和Collection是一致的。Set接口取出方式只有一种,迭代器。


2.分类:HashSet和TreeSet。
1)、HashSet:
底层数据结构是哈希表,线程是不同步的(线程不安全)。无序,高效。存取速度快。

HashSet集合保证元素唯一性:
通过元素的hashCode和equals方法完成的。
如果元素的hashCode值相同,才继续判断元素的equals是否为true。
如果元素的hashCode值不同,那么不判断equals,从而提高对象比较的速度。
(复写hashCode和equals)
public int hashCode()
{
    return name.hashCode()+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;
}
下面用代码体现:
(代码 HashSetDemo.java):

/*
往HashSet集合中存入自定义对象。
姓名和年龄相同为同一个人,重复元素。
*/
import java.util.*;
class HashSetDemo 
{
public static void main(String[] args) 
{
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a3",13));
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
Iterator it = hs.iterator();
while (it.hasNext())
{
Person p = (Person)it.next();
System.out.println(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()
{
return name.hashCode()+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;
}
}
//注意:
//对于HashSet集合,判断元素是否存在(contains),或者删除元素(remove),
//底层依据的是hashCode方法和equals方法。


2)、TreeSet:
可以对Set集合中的元素进行排序。默认按照字母的自然排序。底层数据结构是二叉树。线程是不同步的(线程不安全)。
保证元素唯一性的依据:compareTo方法return 0。


TreeSet的第一种排序方式:
如果元素不具备比较性,在运行时会发生ClassCastException异常。
所以需要元素实现Comparable接口,强制让元素具备比较性,复写compareTo方法。
这种方式也称为元素的自然顺序,或者叫做默认顺序。
下面用代码体现:
(代码 TreeSetDemo.java):

/*
需求:
往TreeSet集合中存储自定义对象学生。
想按照学生的年龄进行排序。

记住:排序时,当主要条件相同时,一定要判断一下次要条件。
*/
import java.util.*;
class TreeSetDemo 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet();
		ts.add(new Student("lisi01",11));
		ts.add(new Student("lisi03",13));
		ts.add(new Student("lisi02",12));
		ts.add(new Student("lisi01",11));
		ts.add(new Student("lisi0002",12));
		Iterator it = ts.iterator();
		while (it.hasNext())
		{
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+"::"+stu.getAge());
		}
	}
}

class Student implements Comparable//该接口强制让学生具备比较性。
{
	private String name;
	private int age;
	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public int compareTo(Object obj)
	{
		if(!(obj instanceof Student))
			throw new RuntimeException("不是学生对象");
		Student s = (Student)obj;
		if(this.age>s.age)
			return 1;
		if(this.age==s.age)
			return this.name.compareTo(s.name);
		return -1;

	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}


TreeSet的第二种排序方式:
当元素自身不具备比较性时,或者具备的比较性不是所需要的。这时就需要让容器自身具备比较性。
在集合初始化时就有了比较方式。定义一个比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将该类对象作为实际参数传递给TreeSet集合的构造函数。
第二种方式较为灵活。
下面用代码体现:
(代码 TreeSetDemo2.java):

import java.util.*;
class Student implements Comparable
{
	private String name;
	private int age;
	Student(String name,int age)
	{
		this.name = name;
		this.age = age;
	}
	public int compareTo(Object obj)
	{
		if(!(obj instanceof Student))
			throw new RuntimeException("不是学生对象");
		Student s = (Student)obj;
		if(this.age>s.age)
			return 1;
		if(this.age==s.age)
			return this.name.compareTo(s.name);
		return -1;

	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
}
class TreeSetDemo2
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet(new MyCompare());
		ts.add(new Student("lisi01",11));
		ts.add(new Student("lisi03",13));
		ts.add(new Student("lisi02",12));
		ts.add(new Student("lisi01",11));
		ts.add(new Student("lisi0002",12));
		Iterator it = ts.iterator();
		while (it.hasNext())
		{
			Student stu = (Student)it.next();
			System.out.println(stu.getName()+"::"+stu.getAge());
		}
	}
}
class MyCompare implements Comparator
{
	public int compare(Object o1,Object o2)
	{
		Student s1 = (Student)o1;
		Student s2 = (Student)o2;
		int num = s1.getName().compareTo(s2.getName());
		if(num==0)
		{
			return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
			/*
			if(s1.getAge()>s2.getAge())
				return 1;
			if(s1.getAge()==s2.getAge())
				return 0;
			return -1;
			*/
		}
		return num;
	}

}


3.知识总结(需要注意的知识点):
对于ArrayList集合,判断元素是否存在,或者删元素底层依据都是equals方法。
对于HashSet集合,判断元素是否存在,或者删除元素,底层依据的是hashCode方法和equals方法。


4.练习题:
(代码 TreeSetTest.java):

/*
练习:按照字符串长度排序。
字符串本身具备比较性,但是他的比较方式不是所需要的。
这时就必须自定义一个比较器。
*/
import java.util.*;
class TreeSetTest 
{
	public static void main(String[] args) 
	{
		TreeSet ts = new TreeSet(new MyCompare());
		ts.add("bb");
		ts.add("cba");
		ts.add("ba");
		ts.add("a");
		ts.add("bb");
        ts.add("abcd");
		Iterator it = ts.iterator();
		while (it.hasNext())
		{
			System.out.println(it.next());
		}
	}
}
class MyCompare implements Comparator
{
	public int compare(Object o1,Object o2)
	{
		String s1 = (String)o1;
		String s2 = (String)o2;
		/*
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()==s2.length())
			return s1.compareTo(s2);
		return -1;
		*/
        int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
        if(num==0)
			return s1.compareTo(s2);
		return num;
	}
}


五.泛型。表现格式:< 引用数据类型 >


1.理解:
JDK1.5版本以后出现的新特性,用于解决安全问题,是一个类型安全机制。
(定义数组时先定义了具体类型,例如int类型,所以比较安全。而集合定义时并没有定义任何类型。)


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


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


4.在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见,只要见到<>就要定义泛型。
其实<>就是来接收类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

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


5.
1)、泛型类:将泛型定义在类上。
class Tool<Q> {
private Q obj;
public  void setObject(Q obj) {
this.obj = obj;
}
public Q getObject() {
return obj;
}
}
2)、方法上的泛型:当方法操作的引用数据类型不确定的时候,可以将泛型定义在方法上。
public <W> void method(W w) {
System.out.println("method:"+w);
}
3)、静态方法上的泛型:静态方法无法访问类上定义的泛型。如果静态方法操作的引用数据类型不确定的时候,必须要将泛型定义在方法上。
public static <Q> void function(Q t) {
System.out.println("function:"+t);
}
4)、泛型定义在接口上:
interface Inter<T> {
void show(T t);
}
class InterImpl<T> implements Inter<T> {
public void show(T t) {
System.out.println("show:"+t);
}
}


6.泛型高级应用:
? 通配符。也可以理解为占位符。
可以解决当具体类型不确定的时候,这个通配符就是 ?  。当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能,那么可以用 ? 通配符来表未知类型。


泛型的限定:
? extends E:可以接受E类型或者E的子类型。上限。
? super E:可以接受E类型或者E的父类型。下限。



五.Map


1.Map集合:该集合存储键值对。一对一往里存。而且要保证键的唯一性。
Map中的存储的一对元素:一个是键,一个是值,键与值之间有对应(映射)关系。


2.Map集合的常用方法:
1)、添加:
put(K key,V value):添加元素。当存储的键相同时,新的值会替换老的值,并将老值返回。如果键没有重复,返回null。
putAll(Map):添加一个集合。


2)、删除:
clear():清空。
remove(key) :删除指定键值对。


3)、判断:
containsValue(value):判断值是否存在。
containsKey(key):判断键是否存在。
isEmpty():判断是否为空。


4)、获取:
get(key):通过键获取对应的值。(注意:可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断)
size():获取集合的长度。
values():获取集合中所有的值。返回值类型是集合Collection。
keySet():
entrySet():


3.Map分类(Map集合的子类):
1)、Hashtable:底层是哈希表数据结构,是线程同步的。效率低。不可以存储null键,null值。
2)、HashMap:底层是哈希表数据结构,是线程不同步的。效率高。可以存储null键,null值。替代了Hashtable.
3)、TreeMap:底层是二叉树结构,可以对map集合中的键进行指定顺序的排序。
Map和Set很像。其实Set底层就是使用了Map集合。


4.Map集合的两种取出方式:
1)、Set<k> keySet:将Map集合中所有的键存入到Set集合。
因为Set具备迭代器。
所以可以通过迭代方式取出所有的键,再根据get方法,获取每一个键对应的值。
Map集合的取出原理:将Map集合转成Set集合,再通过迭代器取出。
(代码 MapDemo.java):

import java.util.*;
class MapDemo 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		map.put("03","zs3");
		map.put("01","zs1");
		map.put("04","zs4");
		map.put("02","zs2");

        //先获取Map集合的所有键的Set集合,keySet();
		Set<String> keySet = map.keySet();

		//有了Set集合,就可以获取其迭代器。
		Iterator<String> it = keySet.iterator();
		while(it.hasNext())
		{
			String key = it.next();
			//有了键就可以通过Map集合的get方法获取其对应的值。
			String value = map.get(key);
			System.out.println("key="+key+",value="+value);
		}
	}
}


2)、Set<Map.Entry<k,v>> entrySet:将Map集合中的映射关系存入到了Set集合中,而这个关系的数据类型就是:Map.Entry。
(代码 MapDemo2.java):

import java.util.*;
class MapDemo2 
{
	public static void main(String[] args) 
	{
		Map<String,String> map = new HashMap<String,String>();
		map.put("03","zs3");
		map.put("01","zs1");
		map.put("04","zs4");
		map.put("02","zs2");

		//将Map集合中的映射关系取出,存入到Set集合中。
		Set<Map.Entry<String,String>> entrySet = map.entrySet();

		Iterator<Map.Entry<String,String>> it = entrySet.iterator();
		while(it.hasNext())
		{
			Map.Entry<String,String> me = it.next();
			String key = me.getKey();
			String value = me.getValue();
			System.out.println(key+"::"+value);
		}
	}
}


5.练习:
(代码 MapTest.java):

/*
练习:
每一个学生都有对应的归属地。
学生Student,地址String。
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。
*/
/*
步骤:
1,描述学生。
2,定义Map容器,将学生作为键,地址作为值,存入。
3,获取Map集合中的元素。
*/
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 int hashCode()
	{
		return name.hashCode()+age*34;
	}
	public boolean equals(Object obj)
	{
		if(!(obj instanceof Student))
			throw new ClassCastException("类型不匹配");
		Student s = (Student)obj;
		return this.name.equals(s.name) && this.age==s.age;
	}
    public int compareTo(Student c)
	{
		int num = new Integer(this.age).compareTo(new Integer(c.age));
		if(num==0)
			return this.name.compareTo(c.name);
		return num;
	}
	public String getName()
	{
		return name;
	}
	public int getAge()
	{
		return age;
	}
	//复写toString,自定义输出内容.
	public String toString()
	{
		return name+"::"+age;
	}
} 

class MapTest 
{
	public static void main(String[] args) 
	{
		HashMap<Student,String > hm = new HashMap<Student,String >();  
        hm.put(new Student("lisi",12),"beijing");  
        hm.put(new Student("lisi",11),"shanghai");  
        hm.put(new Student("lisi",10),"tianjin");  
        hm.put(new Student("lisi",14),"nanjing");  
        hm.put(new Student("lisi",13),"wuhan");  

		//第一种取出方式keySet
		Set<Student> keySet = hm.keySet();
		Iterator<Student> it = keySet.iterator();
        while(it.hasNext())
		{
			Student stu = it.next();
			String addr = hm.get(stu);
			System.out.println(stu+"..."+addr);
		}

		//第二种取出方法Map.Entry
		Set<Map.Entry<Student,String>> entrySet = hm.entrySet();
		Iterator<Map.Entry<Student,String>> iter = entrySet.iterator();
		while(iter.hasNext())
		{
			Map.Entry<Student,String> me = iter.next();
			Student stu = me.getKey();
			String addr = me.getValue();
			System.out.println(stu+"......"+addr);
		}
		
	}
}


(代码 MapTest2.java):

/*
练习:
"sdfgzxcvasdfxcvdf"获取该字符串中的字母出现的次数。
希望打印结果:a(1)c(2).....

通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。

当发现有映射关系时,可以选择Map集合。
因为Map集合中存放的就是映射关系。
*/

/*
思路:
第一次用s字母作为键去找集合,那么集合没有s这个键,
所以也没有对应的次数,返回null。
如果为null,就将s字母和1存入集合。
如果指定的键已经存在,说明有对应的次数。
就将对应的次数取出,并自增后重新存入集合。
*/

/*
步骤:
1,将字符串转成字符数组,因为要对每一个字母进行操作。
2,定义一个Map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。
3,遍历字符数组。
4,将Map集合中的数据变成指定的字符串返回。
*/
import java.util.*;
class MapTest2 
{
	public static void main(String[] args) 
	{
		String s = "sdfgzxcvasdfxcvdf";
		System.out.println(method(s));
	}
	public static String method(String s)
	{
		char[] chs = s.toCharArray();
		TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
		for(int x=0;x<chs.length;x++)
		{
			if(!(chs[x]>='a'&&chs[x]<='z'||chs[x]>='A'&&chs[x]<='Z'))  
				continue;
			Integer value = tm.get(chs[x]);
			if(value==null)
				tm.put(chs[x],1);
			else
			{
				value = value + 1;
				tm.put(chs[x],value);
			}
		}
		StringBuilder sb = new StringBuilder();
		Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
		Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();
		while(it.hasNext())
		{
			Map.Entry<Character,Integer> me = it.next();
			Character key = me.getKey();
			Integer value = me.getValue();
			sb.append(key+"("+value+")");
		}
		return sb.toString();
	}

}


6.Map扩展知识:
在很多项目中,应用比较多的是一对多的映射关系,这就可以通过嵌套的形式将多个映射定义到一个大的集合中,并将大的集合分级处理,形成一个体系。
(代码 MapTuoZhan.java):

import java.util.*;
class MapTuoZhan 
{
	public static void main(String[] args) 
	{
		HashMap<String,HashMap<String,String>> czbk = new HashMap<String,HashMap<String,String>>();
		HashMap<String,String> yure = new HashMap<String,String>();
		HashMap<String,String> jiuye = new HashMap<String,String>();

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

		yure.put("01","zhou");
		yure.put("02","wu");

		jiuye.put("01","zheng");
		jiuye.put("02","wang");

		//getStudentInfo(yure);
		//getStudentInfo(jiuye);

        Set<String> keySet = czbk.keySet();
		Iterator<String> it = keySet.iterator();
		while(it.hasNext())
		{
			String key = it.next();
			HashMap<String,String> value = czbk.get(key);
			System.out.println(key);
			getStudentInfo(value);
		}


	}
	public static void getStudentInfo(HashMap<String,String> roomMap)
	{
		Set<String> keySet = roomMap.keySet();
		Iterator<String> it = keySet.iterator();
		while(it.hasNext())
		{
			String key = it.next();
			String value = roomMap.get(key);
			System.out.println(key+":"+value);
		}
	}
}


六.集合总结


1.看到Array就是数组结构,有角标,查询速度很快。
2.看到Linked就是链表结构,增删速度快。
3.看到Hash就是哈希表,就要想到哈希值,就要想到唯一性,就要想到存入到该结构的中的元素必须覆盖hashCode,equals方法。
4.看到Tree就是二叉树,就要想到排序,就想要用到比较。
比较的两种方式:
一个是Comparable:覆盖compareTo方法;
一个是Comparator:覆盖compare方法。
5.集合什么时候用?
当存储的是一个元素时,就用Collection。保证唯一,就用Set。不保证唯一,就用List。
当存储对象之间存在着映射关系时,就使用Map集合。
6.用到集合时,代码中必须先导包 import java.util.*;



七.集合框架的工具类Collections


1.Collections:
Collections是集合框架中的一个工具类。它的出现给集合(list)操作提供了更多的功能。这个类不需要创建对象,内部提供的都是静态方法。


2.方法:
(代码 CollectionsDemo.java):

import java.util.*;
class CollectionsDemo 
{
	public static void sop(Object obj)
	{
		System.out.println(obj);
	}
	public static void main(String[] args) 
	{
		List<String> list = new ArrayList<String>();
		list.add("dd");
		list.add("abc");
		list.add("bbb");
		list.add("ss");
		list.add("a");
		
		//sortDemo(list);
		//maxDemo(list);
		//binarySearchDemo(list);
		//fillDemo(list.subList(0,3));//将list集合中的部分元素替换成指定元素
		//replaceAllDemo(list);
		//reverse(list);
		//swap(list);
		shuffle(list);
	}
	public static void sortDemo(List<String> list)//排序
	{
        sop(list);
		Collections.sort(list,new myCompare());
		sop(list);
	}
	public static void maxDemo(List<String> list)//最大值
	{
		String max = Collections.max(list,new myCompare());
		sop(max);
	}
	public static void binarySearchDemo(List<String> list)
	{
		sop(list);
		Collections.sort(list);
		int index = Collections.binarySearch(list,"bbb");//二分查找,返回角标。前提是有序的对象。如果没找到则返回(-插入点)-1
		sop(index);
	}
	public static void fillDemo(List<String> list)
	{
		sop(list);
		Collections.fill(list,"pp");//把集合中的所有元素都变成pp
		sop(list);
	}
	public static void replaceAllDemo(List<String> list)
	{
		sop(list);
		Collections.replaceAll(list,"abc","w");//把集合中指定元素变成w
		sop(list);
	}
	public static void reverse(List<String> list)
	{
		sop(list);
		Collections.reverse(list);//反转
		sop(list);
	}
	public static void swap(List<String> list)
	{
		sop(list);
		Collections.swap(list,0,1);//互换位置
		sop(list);
	}
	public static void shuffle(List<String> list)
	{
		sop(list);
		Collections.shuffle(list);//随机对list中的元素进行位置的置换。相当于洗牌。
		sop(list);
	}
}
class myCompare implements Comparator<String>//按指定的比较器方法排序
{
	public int compare(String s1,String s2)
	{
		if(s1.length()>s2.length())
			return 1;
		if(s1.length()==s2.length())
			return s1.compareTo(s2);
		else
			return -1;
	}
}


(代码 CollectionsDemo2.java):

import java.util.*;
class CollectionsDemo2 
{
	public static void main(String[] args) 
	{
		reverseOrderDemo();//逆向反转排序
	}
	public static void reverseOrderDemo()
	{
		TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder());
		ts.add("dd");
		ts.add("ghjk");
		ts.add("a");
		ts.add("bcd");
		Iterator<String> it = ts.iterator();
		while(it.hasNext())
		{
			System.out.println(it.next());
		}
	}
}


3.同步的集合:

List<T>synchronizedList(List<T> list); 返回支持的同步(线程安全的)List集合。
Map<K,V>synchronizedList(Map<K,V> m); 返回支持的同步(线程安全的)Map集合。



八.Arrays


1.用于操作数组对象的工具类,里面都是静态方法。


2.方法:

1)、String toString(); 可以接收各种数组类型参数,并返回指定数组内容的字符串表现形式。
例:int[] arr = {2,4,5}; 
    System.out.println(Arrays.toString(arr));//转换为字符串形式 

2)、asList方法:数组变集合。
例:String[] arr = {"abc","kk","qq"};
    List<String> list = Arrays.asList(arr);//将arr数组转成list集合。
将数组转换成集合,有什么好处呢?
可以使用集合的思想和方法来操作数组中的元素。
注意:
将数组变集合,不能使用集合的增删操作,因为数组的长度是固定的。如果进行增删操作,则会产生UnsupportedOperationException的编译异常。
如果数组中的元素都是对象,则变成集合时,数组中的元素就直接转为集合中的元素。
如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。


3.toArray():集合变数组。
用的是Collection接口中的方法:toArray();
例:ArrayList<String> al = new ArrayList<String>(); 
    al.add("abc1"); 
    al.add("abc2"); 
    al.add("abc3"); 
    //将集合变为String数组 
    String[] arr = al.toArray(new String[al.size()]); 
    //利用Arrays操作数组的方法 
    System.out.println(Arrays.toString(arr)); 
指定类型的数组到底要定义多长呢?
                              当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组。长度为集合的size。
                              当指定类型的数组长度大于了集合的size,就不会新创建了数组。而是使用传递进来的数组。
                              所以创建一个刚刚好的数组最优。
为什么要将集合变数组?
                    为了限定对元素的操作。不需要进行增删了。



九.(1.5版本新特性)高级for


1.Collection在jdk1.5以后,有了一个父接口Iterable,这个接口的出现的将iterator方法进行抽取,提高了扩展性。


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


}


3.高级for对集合进行遍历,只能获取集合元素,但不能对集合进行操作。
迭代器除了遍历,还可以进行remove集合中元素的操作。
如果是ListIterator,还可以在遍历过程中对集合进行增删改查的操作。


传统for和高级for有什么区别?
高级for有一个局限性,必须有遍历的目标。
建议在遍历数组的时候,还是希望用传统for,因为传统for可以定义角标。


4.定义一个HashMap集合:
例子:
        HashMap<Integer,String> hm = new HashMap<Integer,String>(); 
 
        hm.put(1,"a"); 
        hm.put(2,"b"); 
        hm.put(3,"c"); 
 
        //keySet取出方式的高级for遍历 
        Set<Integer> keySet = hm.keySet(); 
        for(Integer i : keySet) 
        { 
            System.out.println(i+"::"+hm.get(i)); 
        } 
 
        //entrySet取出方式的高级for遍历 
        for(Map.Entry<Integer,String> me : hm.entrySet()) 
        { 
            System.out.println(me.getKey()+"------"+me.getValue()); 
        } 


十.(1.5版本新特性)方法的可变参数


1.可变参数:其实就是数组参数的简化形式,不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。


2.例:
public static void main(String[] args)  
    { 
        show("haha",1,2,3,4,5,6); 
    } 
    public static void show(String str,int... arr)//...就表示可变参数 
    { 
        System.out.println(arr.length); 
    } 
在使用时注意:可变参数一定要定义在参数列表的最后面。



十一.(1.5版本新特性)静态导入


1.导入了类中的所有静态成员,简化静态成员的书写。


2.写法:
import static java.util.Arrays.*; 导入的是Arrays这个类中的所以静态成员。
import static java.lang.System.*; 导入了Sytem类中所以静态成员。


3.注意:
当类名重名时,需要指定具体的包名。
当方法重名时,指定具体所属的对象或者类。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值