集合框架

学习日志_集合框架
Java语言_集合框架
{
	Collection
		|——List
			|——ArrayList

		|——Set
			|——HashSet
			|——TreeSet
	
	集合框架就是容器,因为它们的存储方式(数据结构)不同,有所差异
	
	集合是一种可以容纳多个对象的对象。与数组不同,集合对象的容量会根据需要自动扩展,
	以容纳添加到其中的所有对象,因此,编程时并不需要关心将来添加到其中的对象的个数

	Collection的共性方法
	①添加元素
	c.add(对象);//add方法的参数类型是Object,以便于接收任意类型的对象;集合中存储的
	都是对象的引用(地址)
	②获取长度,个数
	c.size();
	③打印集合
	System.out.println(c);//打印的是对象
	④删除元素
	c.remove(对象);
	c.clear();清空集合
	⑤判断元素
	c.contains(obj);//是否存在
	c.isEmpty();//是否为空,为空返回true
	⑥取交集
	c.retainAll(c2)//c中只会保留和c2相同的元素

	迭代器
	接口 Iterator :对 collection 进行迭代的迭代器
	
	Iterator it = al.iterator();//获取迭代器,用于取出集合元素
	Iteratro 中的方法
	it.hasNext();//如果有元素,返回true
	it.next()//返回迭代的下一个元素

	什么是迭代器
	其实就是集合的元素取出方式,把取出方式定义在集合的内部,这样取出方式就可以直接访问
	集合内部的元素,那么,取出方式就被定义成了内部类,而每一个容器的数据结构不同,所以
	取出的动作细节也不一样,但是都有共性内容:判断和取出。那么,也可以将这些共性内容进行
	抽取。这些抽取出来的规则就是Iterator。通过一个对外提供的方法iterator()。就可以获取
	集合的取出对象。

	例:
		/*集合框架__迭代器*/

		import java.util.*;//导入java工具包

		class IteratorDemo
		{
			public static void main(String[] args)
			{
				ArrayList al = new ArrayList();//创建一个集合容器

				al.add("java01");//添加元素
				al.add("java02");
				al.add("java03");

				sop("size="+al.size()); //获取长度

				Iterator it = al.iterator();//获取迭代器
				while(it.hasNext())//如果仍有元素可以迭代,则返回 true。
				{
					sop(it.next());//返回迭代的下一个元素。
				}
				/*
				迭代器也可以这样写,因为这样比较节省资源
				for(Iterator it = al.iterator();it.hasNext();)
				{
					sop(it.next());
				}
				*/
			}

			public static void sop(Object obj)
			{
				System.out.println(obj);
			}
		}
	
	<1>List集合
	凡是可以操作角标的方法都是该体系特有方法
	List集合共性方法
	①添加元素
	add(index,element)
	addAll(index,collection);
	②删除元素
	remove(index);
	③修改元素
	set(index,element);
	④查找元素
	get(index);
	subList(fromIndex,toIndex);
	listIterator();
	indexOf();

	List集合特有的迭代器
	listIterator是Iterator的子接口
	在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生并发修改异常
	所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator方法是有限的,只能
	对元素进行判断和取出删除的操作
	如果想要其它的操作如:添加修改等,就需要使用其子接口,listIterator
	*该接口只能通过List集合的listIterator方法获取,只有listIterator具备增删改查,
	因为List集合有角标

	例:
		/*集合框架__List集合共性方法*/

		import java.util.*;//导入集合工具包

		class ListDemo
		{
			public static void main(String[] args)
			{
				ArrayList li = new ArrayList();//创建集合

				li.add("java01");//添加元素
				li.add("java02");
				li.add("java03");
				
				sop("li="+li);
				li.add(2,"java04");//添加元素
				sop("li="+li);

				li.remove(2);//删除元素 ArrayList中特有方法remove(index);
				sop("li="+li);

				li.set(2,"java06");//用指定的元素替代此列表中指定位置上的元素。
				sop("li="+li);

				sop("sub="+li.subList(2,3));//返回列表中指定的fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
				sop(li);

				ListIterator ll = li.listIterator();//list集合中特有迭代器listIterator

				while(ll.hasNext())
				{
					Object obj = ll.next();
					if(obj.equals("java06"))
						ll.set("java03");//listIterator中的替换操作
				}
				sop("li = "+li);
			}

			public static void sop(Object obj)
			{
				System.out.println(obj);
			}
		}
	总结:
	List:元素有序,可以重复,因为有索引
	ArrayList:底层的数据结构使用的是数组结构,特点:查询速度快,但是增删速度慢;线程不同步


	<2>Set集合
	元素无序,元素不可以重复(存入和取出的顺序不一定一致)
	HashSet:元素无序,底层数据结构(哈希表)非同步
	HashSet是如何保证元素的唯一性?
	是通过元素的两个方法:hashCode和equals来完成的,如果元素的HashCode值相同,才会判断equals
	是否为true,如果元素的hashCode不同,不会调用equals方法
	注意:对于判断元素是否存在,以及删除操作,依赖的方法是元素的hashCode和equals方法

	例:
		/*Set__HashSet*/

		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 int hashCode()//重写hashCode方法
			{
				return name.hashCode()+age*22;
			}

			public boolean equals(Object obj)//重写equals方法,这里用Object接收
			{
				if(!(obj instanceof Person))
					throw new ClassCastException("不是Person对象");
				Person p = (Person) obj;//这里要进行强制转换
				return this.name.equals(p.name) && this.age == p.age;
			}
		}

		class HashSetTest
		{
			public static void main(String[] args)
			{
				HashSet hs = new HashSet();

				hs.add(new Person("zhangsan",11));
				hs.add(new Person("lisi",12));
				hs.add(new Person("lisi",12));
				hs.add(new Person("wangwu",13));
				hs.add(new Person("wangwu",13));
				hs.add(new Person("zhaoliu",13));

				Iterator it = hs.iterator();//创建迭代器
				while(it.hasNext())
				{
					Person p = (Person) it.next();
					sop("name = "+p.getName()+"...age = "+p.getAge());//输出内容
				}
			}

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


	TreeSet:可以对Set集合中的元素进行排序
	排序时,当主要条件相同时,一定要判断一下次要条件,对象类强制实现Comparatable接口,让该类对象
	具有比较性,并重写compareTo方法。
	底层数据结构是二叉树,和哈希值无关,与CompareTo有关
	保证元素唯一性的办法是判断compareTo的返回值是否为0,为0,则不进行存储。

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

	例:
		/*TreeSet_lastOne*/

		import java.util.*;

		class Student implements Comparable<Student>//实现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(Student s1)//重写compareTo方法,按年龄排序
			{
				int num = new Integer (this.age).compareTo(s1.age);
					if (num == 0)
						return this.name.compareTo(s1.name);//如果第一个条件为0,则比较第二个条件
				return num;//返回值
			}
		}

		class TreeSetDemo 
		{
			public static void main(String[] args)
			{
				TreeSet<Student> ts = new TreeSet<Student>();

				ts.add(new Student("czhangsan",21));
				ts.add(new Student("alisi",24));
				ts.add(new Student("dwangwu",22));
				ts.add(new Student("bzhaoliu",23));

				for(Student stu: ts)
				{
					System.out.println("Name:"+stu.getName()+"::age :"+stu.getAge());
				}
			}
		}

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

	步骤:定义比较器(比较器:定义一个类,实现Comparator接口,覆盖compare方法),
	将比较器对象作为参数传递给TreeSet集合的构造函数
	两种比较方式都存在,以比较器为主

	例:
		/*TreeSet_Comparator*/

		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;
			}
		}

		class Comp implements Comparator<Student>//创建比较器
		{
			public int compare(Student s1,Student s2)//实现compare()方法,接收两个对象进行比较
			{
				int num = s1.getName().compareTo(s2.getName());
					if(num == 0)
						return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
				return num;
			}
		}

		class TreeComp
		{
			public static void main(String[] args)
			{
				TreeSet<Student> ts = new TreeSet<Student>(new Comp());

				ts.add(new Student("czhangsan",21));
				ts.add(new Student("dzhangsan",20));
				ts.add(new Student("azhangsan",26));
				ts.add(new Student("ezhangsan",22));
				ts.add(new Student("bzhangsan",23));

				Iterator<Student> it = ts.iterator();
				while (it.hasNext())
				{
					Student stu = it.next();
					System.out.println("Name: "+stu.getName()+"  Age: "+stu.getAge());
				}
			}
		}

	泛型
	JDK1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制
	1、将运行时期出现问题ClassCastException异常转移到了编译时期,方便于程序员解决问题
	让运行时期减少安全问题
	2、避免了强制转换的麻烦

	泛型格式:通过<>来定义要操作的引用数据类型
	当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可


	Collections集合框架工具类
	①排序sort
	public static <T extends Comparable<? super T>> void sort(List<T> list)
	接收一个集合,其元素必须具有比较性(必须继承Comparable),进行排序
	public static <T> void sort(List<T> list,Comparator<? super T> c)
	接收一个结合,并传入一个比较器,进行排序
	——————————————
	②最大值max
	public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll)
	根据元素的自然顺序,返回给定 collection 的最大元素。collection 中的所有元素都必须实现
	Comparable 接口。
	public static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp)
	根据指定比较器产生的顺序,返回给定 collection 的最大元素。collection 中的所有元素
	都必须可通过指定比较器相互比较
	——————————————
	③二分查找binarySearch
	public static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)
	使用二分搜索法搜索指定列表,以获得指定对象。在进行此调用之前,必须根据列表元素的自
	然顺序对列表进行升序排序(通过 sort(List) 方法)。
	list - 要搜索的列表。
	key - 要搜索的键。
	如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点
	被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都
	小于指定的键,则为 list.size()。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
	—————————————— 
	④替换replaceAll
	public static <T> boolean replaceAll(List<T> list,T oldVal,T newVal)
	使用另一个值替换列表中出现的所有某一指定值。更确切地讲,使用 newVal 替换
	list 中满足 (oldVal==null ? e==null : oldVal.equals(e)) 的每个 e 元素。(此方法对列表的大小没有任何影响。) 
	参数:
	list - 在其中进行替换的列表。
	oldVal - 将被替换的原值。
	newVal - 替换 oldVal 的新值。 
	返回:
	如果 list 包含一个或多个满足 (oldVal==null ? e==null : oldVal.equals(e)) 的 e 元素,则返回 true。
	——————————————
	⑤反转reverse
	public static void reverse(List<?> list)
	——————————————
	⑥逆转比较器reverseOrder
	public static <T> Comparator<T> reverseOrder()
	返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
	(自然顺序是通过对象自身的 compareTo 方法强行排序的。)此方法允许使用单个语句,以逆自然顺序对实现了
	Comparable 接口的对象 collection(或数组)进行排序(或维护)。例如,假设 a 是一个字符串数组。那么:
       	Arrays.sort(a, Collections.reverseOrder());
	将按照逆字典(字母)顺序对数组进行排序。
	返回的比较器是可序列化的。
	返回:
	返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。

	public static <T> Comparator<T> reverseOrder(Comparator<T> cmp)
	返回一个比较器,它强行逆转指定比较器的顺序。如果指定比较器为 null,则此方法等同于 reverseOrder()
	(换句话说,它返回一个比较器,该比较器将强行逆转实现了 Comparable 接口的对象 collection 的自然顺序)。 
	返回的比较器是可序列化的(假设指定的比较器也是可序列化的或者为 null)。 
	返回:
	强行逆转指定比较器顺序的比较器。
	——————————————
	⑦线程同步集合
	 synchronizedCollection(Collection<T> c) 
		返回指定 collection 支持的同步(线程安全的)collection。 
	 synchronizedList(List<T> list) 
		返回指定列表支持的同步(线程安全的)列表。 	 
	 synchronizedMap(Map<K,V> m) 
		返回由指定映射支持的同步(线程安全的)映射。
	 synchronizedSet(Set<T> s) 
		返回指定 set 支持的同步(线程安全的)set。	 
	 synchronizedSortedMap(SortedMap<K,V> m) 
		返回指定有序映射支持的同步(线程安全的)有序映射	 
	 synchronizedSortedSet(SortedSet<T> s) 
		返回指定有序 set 支持的同步(线程安全的)有序 set。


	数组工具类Arrays
	asList:数组转换成集合

	public static <T> List<T> asList(T... a)返回一个受指定数组支持的固定大小的列表。
	(对返回列表的更改会“直接写”到数组。)此方法同 Collection.toArray() 一起,
	充当了基于数组的 API 与基于 collection 的 API 之间的桥梁。返回的列表是可序列化的,
	并且实现了 RandomAccess。此方法还提供了一个创建固定长度的列表的便捷方法,该列表被初始化为包含多个元素: 

	 List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
 
	参数:
	a - 支持列表的数组。 
	返回:
	指定数组的列表视图。

	例:
		/*数组变集合*/

		import java.util.*;
		import static java.util.Arrays.*;
		import static java.lang.System.*;

		class ArrCast
		{
			public static void main(String[] args)
			{
				String[] arr = {"zhangsan","lisi","wangwu","zhaoliu"};
				out.println(Arrays.toString(arr));

				List<String> list = asList(arr);

				out.println(list);
			}
		}
	这样做的好处是,可以使用集合的思想和方法来操作数组中的元素
	注意:将数组变集合,不可以使用集合的增删方法,因为数组的长度是固定的

	集合变数组
	Collection接口中的toArray方法
	1.指定类型的数组长度要定义多少呢?
	当指定类型的数组长度小于了集合的size,那么该方法内部会创建一个新的数组,
	长度为集合的size.
	当指定类型的数组长度大于了集合的size,就不会创建新的数组,而是使用传递进来的
	数组,所以创建一个刚刚好的数组最优。
	2.为了限定对元素的操作,不需要进行增删操作

	例:
		/*集合变数组*/

		import java.util.*;

		class CollCast
		{
			public static void main(String[] args)
			{
				ArrayList<Integer> al = new ArrayList<Integer>();

				al.add(1234);
				al.add(44);
				al.add(655);
				al.add(7563);
				
				System.out.println(al);

				Integer[] arr = al.toArray(new Integer[al.size()]);//数组的长度为集合的长度

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

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

	Map
	|——HashTable:底层是哈希表数据结构,不可以存入空值和空键,该集合是线程同步的(JDK1.0出现,效率较低)
	|——HashMap:底层是哈希表数据结构,允许使用空值和空键,该集合是线程不同步的(JDK1.2出现,效率高)
	|——TreeMap:底层是二叉树数据结构,线程不同步,可以用于给map集合中的键排序,和Set很像,Set底层就是
	使用了Map集合
	Map<K,V> k = key; V= value

	Map集合共性方法
	1.添加
	put(K key,V value)
	putAll(Map<? extends K,? extends V> m)
	2.删除
	clear()
	remove(Object Key)
	3.判断
	contains Value(Object Value)
	contains Key(Object Key)
	isEmpty()
	4.获取
	get(Object Key)
	size()
	values()
	entrySet()
	keySet()

	例:
		/*Map__共性方法*/

		import java.util.*;

		class MapDemo
		{
			public static void main(String[] args)
			{
				HashMap<Integer,String> hm = new HashMap<Integer,String>();

				sop("put = "+hm.put(1,"zhangsan"));
				sop("put = "+hm.put(1,"haha"));
				hm.put(4,"lisi");
				hm.put(2,"wangwu");
				hm.put(3,"zhaoliu");

				sop("size = "+hm.size());
				sop(hm);
				sop("contains02 = "+hm.containsKey(02));
				sop("containsZhaoliu = "+hm.containsValue("zhaoliu"));
				sop("get = "+hm.get(3));
				sop(hm.values());
				Collection<String> coll = hm.values();
				sop("coll = "+coll);
				sop(hm.remove(3));
				sop(hm);
			}

			public static void sop(Object obj)
			{
				System.out.println(obj);
			}
		}
	添加元素
	如果出现了添加时相同的键,那么后添加的值会覆盖原有键对应的值,并put方法会返回被覆盖的值

	Map集合的两种取出方式(原理:将Map集合转成Set集合,再通过迭代器取出)
	1.keySet:将Map中所有的键存入到Set集合,因为Set集合具备迭代器,所以可以迭代方式取出所有的键
	再根据get方法,获取每一个键对应的值
	①先获取Map集合的所有键的Set集合,KeySet()
	②有了Set集合,就可以获取迭代器
	③有了键可以通过map集合的get方法获取其对应的值

	例:
		/*Map_键值的取出*/

		import java.util.*;

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

				map.put("04","zhaoliu");
				map.put("02","lisi");
				map.put("03","wangwu");
				map.put("01","zhangsan");

				Set<String> set = map.keySet();

				for(Iterator<String> it = set.iterator();it.hasNext();)
				{
					String i = it.next();
					sop("key = "+i+",value = "+map.get(i));
				}
			}

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

	2.entrySet
	将map集合中的映射关系存入到了Set集合中,而这个关系的数据类型就是:Map.Entry
	其实Entry也是一个接口,它是Map接口中的一个内部接口
	Map集合被使用是因为具备映射关系

	例:
		/*Map__entrySet*/

		import java.util.*;

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

				map.put("04","zhaoliu");
				map.put("02","lisi");
				map.put("03","wangwu");
				map.put("01","zhangsan");

				Set<Map.Entry<String,String>> set = map.entrySet();

				for (Iterator<Map.Entry<String,String>> it = set.iterator(); it.hasNext() ; )
				{
					Map.Entry<String,String> ma = it.next();
					String key = ma.getKey();
					String value = ma.getValue();
					sop(key+":"+value);
				}
			}

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

	例:
		/*Map_TreeMap,比较器形式*/

		import java.util.*;

		class TreeMapComp implements Comparator<Student>
		{
			public int compare(Student s1,Student s2)
			{
				int num = s1.getName().compareTo(s2.getName());
					if(num == 0)
						return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
				return num;
			}
		}

		class TreeMapDemo
		{
			public static void main(String[] args)
			{
				TreeMap<Student,String> tm = new TreeMap<Student,String>(new TreeMapComp());

				tm.put(new Student("Czhangsan",20),"beijing");
				tm.put(new Student("Blisi",24),"guangzhou");
				tm.put(new Student("Awangwu",21),"tianjin");
				tm.put(new Student("Dzhaoliu",25),"nanjing");

				Set<Map.Entry<Student,String>> entrySet = tm.entrySet();

				for (Iterator<Map.Entry<Student,String>> it = entrySet.iterator(); it.hasNext() ; )
				{
					Map.Entry<Student,String> map = it.next();

					Student stu = map.getKey();
					String addr = map.getValue();
					
					System.out.println("Name = "+stu.getName()+"..Age = "+stu.getAge()+"--Addres = "+addr);
				}
			}
		}

	TreeMap练习:
		/*Map_TreeMap练习*/
		/*
		设计需求:给出一个字符串,统计字符串中各个字符出现的次数
		要求打印形式如:a(2)b(1)c(4)d(5)
		*/

		import java.util.*;

		class TreeMapTest
		{
			public static void main(String[] args)
			{
				String str = "dsf-0jewi*a1a_)fvcj5aek2jia";

				String strCount  = charCount(str);

				System.out.println(strCount);
			}

			public static String charCount (String str)
			{
				char[] chs = str.toCharArray();
				int count = 0;

				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))
						count = value;
					count++;
					tm.put(chs[x],count);
					count =0;
				}

				Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
				StringBuilder sb = new StringBuilder();
				for (Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator(); it.hasNext() ; )
				{
					Map.Entry<Character,Integer> map = it.next();

					Character key = map.getKey();
					Integer value = map.getValue();

					sb.append(key+"("+value+"); ");
				}

				return sb.toString();
			}
		}
}//Java语言_集合框架部分结束,有错误请大家指正,谢谢。 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值