黑马程序员_java_集合框架_Collection_List_Set_泛型

  ------- android培训java培训、期待与您交流! ----------




一、集合框架


为什么会出现这么多的容器呢?
因为每一个容器对数据的存储方式都有不同。
这个存储方式称之为:数据结构


Collection  也可以称之为单列集合
       |--List:元素是有序的。输入的元素可以重复,因为该结合体系有索引


          |--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度快。但是增删稍慢,线程不同步


          |--LinkedList:底层的数据结构是链表数据结构。特点。增删速度快。但是查询速度慢,


 |--Vector:底层的数据结构是数组结构。   线程同步。但是被ArrayList替代了。
枚举是Vector特有的取出方式。
发现枚举和迭代器很像
其实枚举和迭代器是一样的。
因为枚举的名称以及方法的名称都过长
所以被迭代器去取代了
而枚举就郁郁而终
示例代码
	import java.util.Vector;
	import java.util.Enumeration;


	class VectorDemo 
	{
		public static void main(String[] args) 
		{
			Vector v = new Vector();
			v.add("java01");
			v.add("java02");
			v.add("java03");


			//使用枚举遍历集合中的元素
			Enumeration e = v.elements();
			for( ; e.hasMoreElements(); )
			{
				System.out.println(e.nextElement());
			}
		}
	}






       |--Set:该集合元素是无序的。输入的元素不可以重复。因为该体系中没有索引


 |--HashSet:底层数据结构是哈希表  线程是非同步的
HsshSet是如何保证元素唯一性的呢?
是通过元素的两个方法,hashCode和equals来完成。
如果元素的HashCode的值相同,,才会判断equals是否为true。
如果原数的HashCode的值不同,才会调用equals


TreeSet的第二种排序方式。
当元素自身不具备比较性时,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性。
在集合初始化时,就有了比较性。    


当两种排序都存在时,一比较器为主。


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


	import java.util.HashSet;
	import java.util.Iterator;


	class HashSetDemo 
	{
		public static void main(String[] args) 
		{
			//创建一个容器
			HashSet hs = new HashSet();
			hs.add("java01");
			hs.add("java02");
			hs.add("java02");
			hs.add("java02");
	
			//创建一个迭代器
			Iterator it = hs.iterator();
			for( ; it.hasNext(); )
			{
				System.out.println(it.next()); //结果为java02 java01
			}
		}
	}








 |--TreeSet:可以对set集合中的元素进行排序。排序规则是参照英文字母的自然排序


底层结构是二叉树,保证元素唯一性的依据;compareTo方法return 0代表元素相同

TreeSet排序的第一种方式:让元素自身具备比较性。
元素需要实现Comparable接口,覆盖compareTo方法
这种方式也称为元素的自然排序,或者叫做默认排序


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


记住了,排序时,当主要条件相同时,一定判断一下次要条件


	import java.util.TreeSet;
	import java.lang.Comparable;
	import java.util.Iterator;


	class TreeSetTest
	{
		public static void main(String[] args) 
		{	
			//创建一个容器
			TreeSet ts = new TreeSet();
			ts.add(new Students("张三", 23));
			ts.add(new Students("李四", 32));
			s.add(new Students("王五", 23));
		
			//创建一个迭代器
			Iterator it = ts.iterator(); //只要容器中有元素。it.hasNext()结果永远为真。程序就能运行下去。一旦为false。就停止
			for( ; it.hasNext(); )
			{
				Students s = (Students)it.next(); //因为it.next()是父类印象指向子类对象。所以在这里要做强转
				System.out.println(s.getName() + "," + s.getAge());
			}
		}
	}


	//写一个学生类
	class Students implements Comparable //实现Comparable接口。对学生对象进行自定义排序
	{
		private String name;
		private int age;
		Students(String name, int age)
		{
			this.name = name;
			this.age = age;
		}


		//重写Comparable接口的方法
		public int compareTo(Object obj)
		{
			if(!(obj instanceof Students)) //判断一下是否是学生对象
				throw new RuntimeException("对象不是学生对象");
			Students s = (Students)obj;
			if(this.age > s.age) //假如传进来的对象年龄小于原来的对象年龄。就返回1
				return 1;
			if(this.age == s.age)
			{
				return this.name.compareTo(s.name); //如果年龄一样的话。就比较名字。让名字按照英文字母的顺序排列
			}
			return -1;
		}


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


		public String getName()
		{
			return name;
		}


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


		public int getAge()
		{
			return age;
		}
	}





Set集合的功能和Collection是一致的





二、Collection的基本应用。和迭代器的基本使用


import java.util.ArrayList;
import java.util.Iterator;
/*
1,add方法的参数是Object.以便于接收任意类型对象。
2集合中存储的都是对象的引用(也就是地址)


常用函数
add(); 添加元素
size(); 求集合的长度
contains(String); 判断String字符是否存在于集合中
isEmpty(); 此函数判断集合是否为空
remove(String) 删除数组中的Sring元素
clear(); 清空集合


retainAll()  去交集
remove() 删除有交集的元素


什么是迭代器?
其实就是集合的取出元素的方式。
把取出方式定义在集合的内部,
这样取出方式就可以直接访问集合内容的元素。


那么取出方式就被定义成了内部类。


而每一个容器的数据结构不同。
所以取出的动作细节也不一样,但是都有共性内容。
判读和取出。那么可以可以将共性抽取。


所以这些内部类都符合一个规则。该规则就是Iterator.
如何取出集合的取出对象呢?
通过一个对外提供的方法iterator();
*/


class CollectionDemo 
{
	public static void main(String[] args) 
	{
		//mothed_1();
		//mothed_2();
		dieDai();
	}


	//结合容器Collection的一个基本应用
	public static void mothed_1()
	{
		//创建一个集合容器,使用Collection接口的子类。ArrayList
		ArrayList  a1 = new ArrayList();
		
		//添加元素
		a1.add("java01");
		a1.add("java02");
		a1.add("java03");
		a1.add("java04");


		//获取个数。求集合的长度
		p("长度是:" + a1.size());


		//打印集合
		p("原集合:" + a1);


		//判断java03元素是否存在    运用contains函数
		p("java03是否存在于集合中:" + a1.contains("java03"));


		//判断集合是否为空  运用isEmpty()函数
		p("判断集合是否为空:" + a1.isEmpty());




		//删除集合
		a1.remove("java03"); //调用remove函数删除集合中的元素
		p("删除单个元素后的集合:" + a1);


		a1.clear(); //调用clear清空集合
		p("清空后的集合:" + a1);
	}
	
	//集合中的交集小例子
	public static void mothed_2()
	{
		//创建一个集合容器,使用Collection接口的子类。ArrayList
		ArrayList  a1 = new ArrayList();
		
		//添加元素
		a1.add("java01");
		a1.add("java02");
		a1.add("java03");
		a1.add("java04");
		
		ArrayList a2 = new ArrayList();
		//添加元素
		a2.add("java01");
		a2.add("java02");
		a2.add("java05");
		a2.add("java06");
		//a1.retainAll(a2); //判断两个容器是否有交集的地方,有的话。把交集的内容打印,.可以剪短的称之为取交集
		//p(a1);
		a1.removeAll(a2); //干掉相同的元素
		p(a1); 
	}


	//简单应用迭代器
	public static void dieDai()
	{
		ArrayList s = new ArrayList();
		s.add("java01");
		s.add("java02");
		s.add("java03");
		s.add("java04");
		/*   此为while循环
		//获取迭代器 使用迭代器取出集合中的元素
		Iterator it = s.iterator();
		while(it.hasNext()) //判断集合中是否有内容。有就往下执行
		{
			p(it.next()); //打印输出集合中的内容
		}
		*/
		//使用for循环使用迭代器
		for(Iterator it = s.iterator(); it.hasNext(); )
		{
			p(it.next());
		}


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


}







二、List接口的使用


import java.util.ArrayList;
import java.util.ListIterator;




List
特有方法、凡是可以操作角标的方法都是该体系特有的方法
1、增加
add(index,element); 在角标为index的位置上插入element元素
addAll(index,Collection); 在角标位置为index的位置上插入一组元素
2、删除
remove(index); 删除角标位置为index上的元素
3、修改
set(index,element); 修改角标位置为index上的元素
4、查找
get(index); 查找角标位置为index上的元素
subList(from,to); 查找角标位置从from到to但并不包含to的一组元素
listIterator(); 


List集合特有的迭代器,ListIterator是Iterator的子接口。


在迭代时,不可以通过集合对象的方法操作集合中的元素。
因为会发生ConcurrentModificationException(并发修改异常)


所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator方法是有限的。
只能对元素进行判断,取出,删除的操作,
如果想要其他操作如添加。修改等,就需要使用其子接口,ListIterator;


该接口只能通过list集合的listIterator方法获取。




class ListDemo 
{
	public static void main(String[] args) 
	{
		//list();
		list_1();
	}
	
	//List的简答应用
	public static void list()
	{
		//创建一个集合容器,使用Collection的子类ArrayList
		ArrayList s = new ArrayList();
		//添加元素
		s.add("java01");
		s.add("java02");
		s.add("java03");
		p("添加前:" + s);
		//增加元素
		s.add(2,"java05"); //在角标位为2的位置插入元素
		p("添加后:" + s);
		
		s.remove(3); //删除角标位为3的元素
		p("删除后:" + s);


		s.set(2, "java08"); //把角标位为2的元素修改成java08
		p("修改后:" + s);


		p("查找的单个元素是:" + s.get(2)); //查找角标位为2的数组上的元素
 
		p("查找到的多个元素:" + s.subList(0,3)); //以为此方法查找包含头,不包含尾。所以要查找到到所有元素。必须要比元素个数大1
		


	}


	//ListIterator的简单应用
	public static void list_1()
	{
		ArrayList s = new ArrayList();
		s.add("java01");
		s.add("java02");
		s.add("java03");
		ListIterator li = s.listIterator();
		//使用List特有的迭代器ListIterator
		for(; li.hasNext(); )
		{
			Object obj = li.next(); //子类对象指向父类引用
			if(obj.equals("java03"))
			{
				li.set("java---3"); //对迭代器中的元素进行修改
				li.add("java-----3"); //对迭代器中的元素进行添加
			}
		}
		p("从头往后遍历:" + s);


		for(; li.hasPrevious(); )
		{
			p(li.previous()); //从后往前遍历
		}
		
	}


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







三、类LinkedList的简单应用


import java.util.LinkedList;


/*
LinkedLIST:特有方法
addFirst(); 每次都把元素添加在第一位
addLast(); 每一次都把元素添加到最后一位


//获取元素,但是并不删除元素。如果集合中没有元素,会出现NoSuchEmelemtException异常
getFirst(); 获取最前面的一位元素
getLast(); 获取最后面的一位元素


//获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchEmelemtException异常
removeFirst(); 删除最前面的一位元素
removeLast(); 删除最后面的一位元素


在jdk1.6中出现了替代的方法。


offerFirst(); 每次都把元素添加在第一位
offerLast(); 每一次都把元素添加到最后一位


//获取元素,但是并不删除元素。如果集合中没有元素,会出现null;
peekFirst(); 获取最前面的一位元素
peekLast(); 获取最后面的一位元素


//获取元素,但是元素被删除。如果集合中没有元素,会出现null;
pollFirst(); 删除最前面的一位元素
pollLast(); 删除最后面的一位元素

*/


class LinkedListDemo 
{
	public static void main(String[] args) 
	{
		//mothed();
		mothed_1();
	}


	//写一个1.6以后出现的新特性的应用函数
	public static void mothed_1()
	{
		//创建一个集合
		LinkedList l = new LinkedList();


		l.offerFirst("java02"); //addFirst();每次输入进去的元素都放在第一位。把原来第一位上的元素挤到后面去
		l.offerFirst("java01"); //所以结果为:[java01, java02]
		p(l);


		l.offerLast("java03"); //addLast();每次输入的元素都放在最后一位。并把原来排在最后一位的元素往前挤
		l.offerLast("java04"); //所以结果为:[java01, java02, java03, java04]
		p(l);


		//获取第一个元素和最后一个元素
		p("第一个元素是:" + l.peekFirst());
		p("最后一个元素是:" + l.peekLast());


		//删除第一个元素
		l.pollFirst();
		p(l);


		//删除最后一个元素
		l.pollLast();
		p(l);
	}


	//写一个LinkedList类的应用函数
	public static void mothed()
	{
		//创建一个集合
		LinkedList l = new LinkedList();


		l.addFirst("java01"); //addFirst();每次输入进去的元素都放在第一位。把原来第一位上的元素挤到后面去
		l.addFirst("java02"); //所以输出结果是:[java04, java03, java02, java01]
		l.addFirst("java03");
		l.addFirst("java04");
		p(l);


		l.addLast("java05"); //addLast();每次输入的元素都放在最后一位。并把原来排在最后一位的元素往前挤
		l.addLast("java06"); //所以输出的结果是:[java04, java03, java02, java01, java05, java06, java07, java08]
		l.addLast("java07");
		l.addLast("java08");
		p(l);


		p("最前面的元素是:" + l.getFirst());
		p("最后面的元素是:" + l.getLast());
		
		l.removeFirst();
		p(l); //删除最前面的元素。结果为:[java03, java02, java01, java05, java06, java07, java08]
		l.removeLast();
		p(l); //删除最后面的元素。结果为:[java03, java02, java01, java05, java06, java07]
	}


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


}







四、堆栈与队列


/*
使用LinkedList模拟出一个堆栈或者队列的数据结构
堆栈:先进后出
队列:先进先出
*/


import java.util.LinkedList;


//写一个对列
class DuiLie
{
	private LinkedList ll;
	DuiLie()
	{
		ll = new LinkedList();		
	}
	
	//输入元素
	public void myAdd(Object obj)
	{
		ll.addFirst(obj); //把每次传进来的元素都放在第一位
	}


	//获取元素
	public Object myGet()
	{
		return ll.removeLast(); //把要删除的元素反出去。这样可以保证把存进来元素一次取出
	}


	//添加一个判断是否存在元素的函数
	public boolean isNull()
	{
		return ll.isEmpty();
	}


}


//写一个堆栈
class DuiZhan
{
	private LinkedList ll;
	DuiZhan()
	{
		ll = new LinkedList();
	}


	//输入元素
	public void myAdd(Object obj)
	{
		ll.addFirst(obj);
	}


	//获取元素
	public Object myGet()
	{
		return ll.removeFirst();
	}


	//判断是否为空
	public boolean isNull()
	{
		return ll.isEmpty();
	}


}


class LinkedListTest 
{
	public static void main(String[] args) 
	{
		//调用堆栈
		duiZhan();
		//调用队列
		duiLie();
	}
	
	//写一个应用堆栈的函数
	public static void duiZhan()
	{
		DuiZhan d = new DuiZhan(); //创建一个容器
		d.myAdd("java03"); //输入元素
		d.myAdd("java04");
		
		//获取全部元素
		for( ; !d.isNull(); )
		{
			p(d.myGet());
		}
	}


	//写一个应用队列的函数
	public static void duiLie()
	{
		DuiLie d = new DuiLie();
		d.myAdd("java01"); //添加元素
		d.myAdd("java02");
		
		//获取全部元素
		for( ; !d.isNull(); )
		{
			p(d.myGet());
		}
	}


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












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


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

	//定义一个只能装String类型的数据的容器
	ArrayList<String> al = new ArrayList<String>();
	al.add("java");
	al.add("jaasdfds");
	al.add("adfasf");


	Iterator<String> it = al.iterator(); //建立一个String类型的迭代器
	for( ; it.hasNext(); )
	{
		String s = it.next();
		System.out.println(s + "   " + s.length());
	}






泛型的格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见。
只要见到<>就要定义泛型。


其实<>就是用来接收类型的。


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




示例代码:


import java.util.TreeSet;
import java.util.Iterator;
import java.util.Comparator;


class GenericDemo 
{
	public static void main(String[] args) 
	{
		TreeSet<String> ts = new TreeSet<String>(new LenBi()); //创建一个String类型的容器
		ts.add("abd");
		ts.add("bc");
		ts.add("g");
		ts.add("ddd");
		ts.add("agdg");


		Iterator<String> it = ts.iterator(); //创建一个String类型的迭代器
		for( ; it.hasNext(); )
		{
			String s = it.next(); //把遍历的元素赋值给变量s;
			System.out.println(s + "   " + s.length());
		}
	}
}

//定义一个比较长度的比较器 
class LenBi implements Comparator<String>  //定义一个判断字符串长度的比较器
{
	public int compare(String s1, String s2)
	{
		int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
		if(num == 0)
		{
			return s1.compareTo(s2);
		}
		return num;
	}
}




六、泛型类


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


class Worker
{
}


//没有泛型之前的做法
class SetObject
{
	private Object obj;
	public void setObject(Object obj)
	{
		this.obj = obj;
	}


	public Object getObject()
	{
		return obj;
	}
}


//写一个泛型类
class FanXing<QQ>
{
	private QQ q;
	public void setQQ(QQ q)
	{
		this.q = q;
	}
	
	public QQ getQQ()
	{
		return q;
	}
}


class GenericDemo1
{
	public static void main(String[] args) 
	{
		SetObject s = new SetObject();
		s.setObject(new Worker());
		Worker w = (Worker)s.getObject();
		//运用泛型
		FanXing<Worker> f = new FanXing<Worker>();
		f.setQQ(new Worker());
		Worker w1 = f.getQQ();
	}
}










七、泛型限定


?通配符。也可以理解为占位符。
泛型的限定:
? extends E: 可以接收E类型或者E的子类型。上限
? super E: 可以接收E类型或者E的父类型。下限
示例代码:


import java.util.TreeSet;
import java.util.Iterator;
import java.util.Comparator;


class GenericSuper 
{
	public static void main(String[] args) 
	{
		//创建一个容器。只打印狗类
		TreeSet<Dog> d = new TreeSet<Dog>(new Comp());
		d.add(new Dog("小狗"));
		d.add(new Dog("老狗")); //给容器添加元素
		d.add(new Dog("中型狗"));


		//创建一个容纳猫类的容器
		TreeSet<Cat> c = new TreeSet<Cat>(new Comp());
		c.add(new Cat("小猫"));
		c.add(new Cat("老猫")); //给容器添加元素
		c.add(new Cat("中年猫"));
		daYin(d); //调用函数打印元素
		daYin(c);
	}
	public static void daYin(TreeSet<? extends Animal> ts) //使用上限的方式对两个容器元素进行输出
	{
		Iterator<? extends Animal> it = ts.iterator(); 
		for( ; it.hasNext(); )
		{
			System.out.println(it.next().getName());
		}
	}
}


class Comp implements Comparator<Animal> //使用下限的形式创建了一个比较器
{
	public int compare(Animal a1, Animal a2)
	{
		return a1.getName().compareTo(a2.getName()); //按照自然顺序把名字排列
	}
}


//创建一个动物类
class Animal
{
	private String name; //定义动物名字变量
	Animal(String name) //定义构造函数。让其在建立对象的时候就设置好名字
	{
		this.name = name;
	}


	//设置名字
	public void setName(String name)
	{
		this.name = name;
	}


	//返回名字
	public String getName()
	{
		return name;
	}
}


//创建一个狗类
class Dog extends Animal
{
	Dog(String name) 
	{
		super(name);
	}
}
 //创建一个猫类
class Cat extends Animal
{
	Cat(String name)
	{
		super(name);
	}
}


---------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Unity开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------


详细请查看:<a href="http://edu.csdn.net" target="blank">http://edu.csdn.net</a>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章