现在的位置: 首页 > 综合 > 正文

黑马程序员 集合学习

2013年06月23日 ⁄ 综合 ⁄ 共 12058字 ⁄ 字号 评论关闭

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

 

数组(Array)和集合(Collection)的关系:

相同:都是装数据的容器。

不同:数组里装的是固定长度的任意类型数据。集合的元素只能是对象,而不能是基本数据类型。

数组和集合互转:

数组转为集合:用Arrays.asList();将数组转成List集合。如果数组中的元素都是对象,则转为集合后,数组中的元素就直接转成集合中的元素;如果是基本数据类型的数组,则将整个数组当成对象(此时类型是数组类型)存入集合中。

集合转为数组:Collection.toArray();

 

集合总述:

/*
 * 为什么会出现集合?
 * 答:数据多了用对象封装,对象多了用集合封装。
 * 
 * 为什么会出现那么多的集合容器?
 * 答:因为每个集合容器对对象的存储方式(即数据结构)不一样。
 * 
 * 1、add(Object obj),参数类型为Object以便于接收任意类型对象
 * 2、集合中存储的都是对象的引用(对象首地址)
 * 
 * 迭代器:取出元素的方式
 * 就是那夹玩具用的夹子。
 * 
 * Collection
 * 		List:元素的存取是有序的,元素可以重复		:因为该体系 有索引
 * 			ArrayList:	底层使用的是数组结构,特点:查询快,增删稍慢,线程不同步
 * 			LinkedList: 底层使用的是链表数据结构,特点:增删快,查询稍慢,线程不同步
 * 			Vector:	底层是数组结构,线程同步,被ArrayList替代了。 
 * 				若多线程,可以自己加锁,也可以交给jvm处理(给它一个不安全,返回一个安全的)
 * 		
 * 		Set:元素的存取是无序的(存入和取出的顺序不一定一致),元素不可以重复
 * 			HashSet:	底层使用的是哈唏表,线程不同步
 * 						HashSet如何保证元素的唯一性?
 * 							先判断hashCode再判断equals
 * 						注意:对于判断元素是否存在以及删除元素等操作,先判断的是元素的hashCode再比较equals
 * 			TreeSet:	可以对Set集合中的元素进行排序(一般是自然顺序或叫默认顺序)
 * 						底层使用的是二叉树,线程不同步
 * 						TreeSet如何保证元素唯一性?
 * 							compareTo()方法return 0;
 * 						
 * 						TreeSet第一种排序方式:让元素自身具备比较性,定义比较方法(元素类自身实现Comparable接口,实现它的compareTo(Object obj)方法)
 * 						TreeSet第一种排序方式:让集合具备比较性,定义比较器(实现Comparator接口,覆盖compare()),再将比较器传递给TreeSet集合的构造函数
 * 						当两种排序都存在时,以比较器为主
 * 
 * 排序时,当主要条件相同时,一定要判断次要条件。
 */

import java.util.*;
public class CollectionDemo {
	
	public static void main(String[] args) {
		Collection c = new ArrayList();		
		c.add("Hello");		
		c.add("java");
		c.add(97);
		c.add(true);
		c.add('a');
		
		/*Iterator it = c.iterator();		//获取迭代器,用于取出集合中的元素
		int i = 0;
		while(it.hasNext()) {	//遍历集合
			System.out.println("Iterator:.." + ++i + "..." + it.next());
		}*/
		
		//用for循环,由于it定义在局部,循环结束,会释放内存空间
		for(Iterator it = c.iterator(); it.hasNext();) {
			System.out.println(it.next());
		}
	}
	
	public static void quJiaoJi_Method() {
		Collection c1 = new ArrayList();		
		c1.add("Hello");		
		c1.add("java");
		c1.add(97);
		c1.add(true);
		c1.add('a');
		
		Collection c2 = new ArrayList();
		c2.add("Hello");		
		c2.add("java");
		c2.add(65);
		c2.add(false);
		c2.add('a');
		
		//boolean b = c2.retainAll(c1);	//取交集,c2中只保留和c1中相同的元素
		c2.removeAll(c1);  //去交集,c2中只保留和c1中不同的元素
		System.out.println(c2);
		//System.out.println(b);
		System.out.println(c1);
	}
	
	public static void base_Method() {
		Collection c = new ArrayList();
		//1、添加
		c.add("Hello");		
		c.add("java");
		c.add(97);
		c.add(true);
		c.add('a');
		System.out.println("原集合:" + c);
		
		//2、查
		System.out.println("集合中元素个数 : " + c.size());	//打印集合元素个数
		String s = "java";
		System.out.println("是否包含java :" + c.contains(s));	//是否包含某个元素
		
		//3、删除
		//c.clear();	//清空集合内的元素
		
		c.remove(true);		//移除集合中的某个元素
		System.out.println("移除后:"+ c);		
	}

}

List集合:

import java.util.*;

/*
 * List集合判断元素是否相同,依据的是元素的equals方法
 * 
 * List特有方法:凡是能操作角标的方法
 * 		增:void add(int index, E element) 
 			boolean addAll(int index, Collection<? extends E> c)  
 * 		删:E remove(int index) 
 * 		改:E set(int index, E element) 
 * 		查:E get(int index)
 * 			ListIterator<E> listIterator(int index) 
   			List<E> subList(int fromIndex, int toIndex)  
   			
   List集合特有的迭代器。ListIterator是Iterator的子接口
 * 在迭代时,不能通过集合对象的方法来操作集合中的元素,会发生ConcurrentModificationException异常 
 * 所以在迭代过程中,只能使用迭代器的方法操作元素,但Iterator的方法只有删、取出、判断,如果要进行其它
 * 操作如添加、修改等,就需要使用其子接口ListIterator来实现。
 * 
 * 该接口只能通过List集合的listIterator()方法获取。
 * 
 */
public class ListDemo {
	
	public static void main(String[] args) {
		ArrayList al = new ArrayList();		
		al.add("Hello");		
		al.add("java");
		al.add(97);
		al.add(true);
		al.add('a');
		System.out.println("原集合:" + al);
		
		//演示列表迭代器
		ListIterator li = al.listIterator();
		System.out.println(li.hasNext());	//true
		System.out.println(li.hasPrevious());	//false
		while(li.hasNext()) {
			Object obj = li.next();
			if(obj.equals("java")) {
				li.add("world");	//用列表迭代器向集合中添加元素
			}
		}
		System.out.println(al);
		System.out.println(li.hasNext());	//true
		System.out.println(li.hasPrevious());	//true
	}
	
	public static void method() {
		ArrayList al = new ArrayList();		
		al.add("Hello");		
		al.add("java");
		al.add(97);
		al.add(true);
		al.add('a');
		System.out.println("原集合:" + al);
		
		al.add(3, "你好");	//在指定位置插入元素
		System.out.println(al);
		
		al.remove(2);	//删除指定位置上的元素
		System.out.println(al);
		
		al.set(4, "world");		//修改指定位置上的元素
		System.out.println(al);		
		
		String s = (String)al.get(1);	//获取指定位置上的元素
		System.out.println(s);
		
		List list = al.subList(2, 5);	//获取子List
		System.out.println("subList:" + list);
		
		//获取所有元素,方式一:
		for(int x=0; x<al.size(); x++) {
			System.out.println("size方式:........" + al.get(x));
		}
		
		//获取所有元素,方式二:
		for(Iterator it = al.iterator(); it.hasNext();) {
			System.out.println("iterator方式:_______________" + it.next());
		}
	}

}

LindedList的特有方法:

/*
 * LindedList特有方法:
 * 	void addFirst(E e)  
 * 	void addLast(E e) 
 * 
 * 	E getFirst() 	//获取元素,元素不删除。若集合中没有元素会抛出异常NoSuchElementException
 * 	E getLast() 	
 * 
 * 	E removeFirst() 	//获取元素,并且将元素删除。若集合中没有元素会抛出异常NoSuchElementException
 * 	E removeLast() 
 * 
 * 	JDK1.6出现的替代方法:
 * 	boolean offerFirst(E e) 
 * 	boolean offerLast(E e) 
 * 
 * 	E peekFirst() 	//获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
 * 	E peekLast() 
 * 
 * 	E pollFirst() 	//获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
 * 	E pollLast() 
 */

import java.util.*;
public class LinkedListDemo {

	public static void main(String[] args) {
		LinkedList link = new LinkedList();
		link.addFirst("java01");
		link.addFirst("java02");
		link.addFirst("java03");
		link.addFirst("java04");
		System.out.println(link);	//[java04, java03, java02, java01]
		
		while(!link.isEmpty()) {	//不用迭代获取所有元素
			System.out.println(link.removeFirst());
		}
	}

}

Vector的枚举:

(现已很少用到)Vector已被ArrayList替代,若要同步,可在代码中添加同步,还可以用Collections的工具类完成同步功能。

/*
 * 枚举就是Vector特有的取出方式
 * 
 * 枚举和迭代是一样的,而枚举的名称及方法名都过长 ,所以被迭代器取代了。
 */
import java.util.*;
public class VectorDemo {

	public static void main(String[] args) {
		Vector v = new Vector();
		v.add("java1");
		v.add("java2");
		v.add("java3");
		v.add("java4");
		for(Enumeration er = v.elements(); er.hasMoreElements();) {
			System.out.println(er.nextElement());
		} 
	}
}

 

HashSet中Person对象的hashCode计算方法int hashCode() {return name.hashCode() + age*39}

TreeSet的自然排序:

import java.util.*;

/*
 * Set集合功能和Collection一致
 * 
 * TreeSet存储自定义对象,要求对象类要实现Comparable接口,实现它的compareTo(Object obj)方法
 * */
public class TreeSetDemo {
	
	public static void main(String[] args) {
		TreeSet<Student> ts = new TreeSet<Student>();
		ts.add(new Student("张三", 23));
		ts.add(new Student("李四", 20));
		ts.add(new Student("李二", 20));
		ts.add(new Student("王五", 25));
		
		for(Iterator it = ts.iterator(); it.hasNext();) {
			System.out.println(it.next());
		}
	}

}

class Student implements Comparable<Student>{
	private String name;
	private int age;
	
	public 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 s) {
//		if(!(obj instanceof Student))
//			throw new RuntimeException("不是学生");
		
//		Student s = (Student)obj;
		if(this.age == s.age)
			return this.name.compareTo(s.name);
		return this.age-s.age;		
	}
	
	public String toString() {
		return this.name + "...." + this.age;
	}
}

 

元素用二叉树怎么存入的怎么取出?(即存入顺序和取出顺序一致) 

答:元素类实现Comparable接口的compareTo()时直接返回1。(存入时全往右边放,取出时即为存入的顺序,从小往大取,被称为自然顺序)

 

泛型:详见http://blog.csdn.net/wyl530274554/article/details/7764757

 

Map集合的键值对:

/*
 * Map集合:存储键值对。一对一对往里存。并且要保证唯一性。
 * 
 * 何时使用Map集合? 当数据之间存在映射关系时。
 * 
 * 1,添加
 * 		void putAll(Map<? extends K,? extends V> m) 
 * 		V put(K key, V value)  //第二个相同存入会覆盖第一个,并返回第一个的“值”
 * 2,删除
 * 		V remove(Object key) 
 * 		void clear()
 * 3,判断
 * 		boolean isEmpty() 
 * 		boolean containsKey(Object key) 
 * 		boolean containsValue(Object value) 
 * 4,获取
 * 		V get(Object key) 
 * 		int size() 
 * 		Collection<V> values() //获取集合中的所有的“值”,并以Collection<>返回
 * 
 * 		Set<K> keySet()	//可将所有键存入Set中,迭代出后,用get()方法得到所有的值。 
 * 		Set<Map.Entry<K,V>> entrySet() 
 * 
 * Map 
 * 		Hashtable:底层是哈唏表,不能存入null键和null值。线程同步。效率低
 * 		HashMap:底层是哈唏表,允许使用null键和null值。线程不同步。效率高
 * 		TreeMap:底层是二叉树,线程不同步,可以对Map集合的键排序。
 * 
 * 和Set很像,其实Set集合的底层用的就是Map中的方法
 * 
 * Map中用作键的对象必须实现hashCode和equals方法。
 * 
 * Map集合中元素取出原理:将Map集合转成Set集合,再用迭代器取出。 
 * */

import java.util.*;
public class MapDemo {

	public static void main(String[] args) {
		Map<String, Integer> mp = new HashMap<String, Integer>();
		mp.put("zhangsan", 20);
		mp.put("lisi", 25);
		mp.put("wangwu", 23);
		mp.put("qingliu", 20);
		/*System.out.println(mp);
		System.out.println(mp.remove("lisi"));
		System.out.println(mp);*/
		
		//1、用keySet()方式取出 :将键集存入Set集合中
		Set<String> keySet = mp.keySet();
		for(Iterator<String> it = keySet.iterator(); it.hasNext();) {
			String key = it.next();
			int value = mp.get(key);
			System.out.println(key+"...keySet...."+value);
		}
		
		//2、用entrySet(()方式取出 :将映射关系存入Set集合中,这个关系的类型就是:Map.Entry
		Set<Map.Entry<String, Integer>> entrySet = mp.entrySet();
		for(Iterator<Map.Entry<String, Integer>> it = entrySet.iterator(); it.hasNext();) {
			Map.Entry<String, Integer> me = it.next();
			String key = me.getKey();
			int value = me.getValue();
			System.out.println(key + "_______________entrySet______________" + value);
		}
	}

}

 

Map集合按值排序示例:

思路:

1、将Map中的映射关系存入Set,即mp.entry();

2、将得到的Set集合转成List 

3、用Collections工具对List按指定比较进行排序

/*统计字符串”abadcdffbaeba”中每个字符出现了多少次,按次数排序并输出。
	例如:c : 1,e : 1,d : 2,f : 2,b : 3,a : 4
*/

import java.util.*;
public class CharCount{
	public static void main(String[] args) {
		String str = "abadcdffbaeba";
		System.out.println("按指定格式输出:" + charcount(str));//c:1,e:1,d:2,f:2,b:3,a:4
	}

	public static String charcount(String str) {
		char[] chs = str.toCharArray();//String ---> char[]
		TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();	
		//从char[]中找键,从Map集合中找值;字符作为键,出现的次数作为值存入Map集合中
		for(char ch : chs) {
			Integer value = tm.get(ch);
			if(value == null) {
				tm.put(ch, 1);
			}
			else {
				tm.put(ch, ++value);
			}
		}
		System.out.println("自然排序:"+tm);//{a=4, b=3, c=1, d=2, e=1, f=2}

		//按值排序:1、将映射关系对象存入Set集合中,并用Set构成List集合。2、用工具Collections对List按比较器进行排序
		List<Map.Entry<Character, Integer>> list = new ArrayList<Map.Entry<Character, Integer>>(tm.entrySet());
		Collections.sort(list, new CharCountComparator());
		System.out.println("按值排序:"+list);//[c=1, e=1, d=2, f=2, b=3, a=4]

		//按指定格式输出:c : 1,e : 1,d : 2,f : 2,b : 3,a : 4
		//用迭代器取出list中映射关系,并将键值按指定格式存入StringBuilder中
		StringBuilder sb = new StringBuilder();
		for(Iterator<Map.Entry<Character, Integer>> it = list.iterator();it.hasNext();) {
			Map.Entry<Character, Integer> me = it.next();
			char key = me.getKey();
			int value = me.getValue();
			if(!it.hasNext())
				sb.append(key + ":" + value);
			else sb.append(key + ":" + value + ",");
		}
		return sb.toString();
		
	}
}

//比较器
class CharCountComparator implements Comparator<Map.Entry<Character, Integer>>
{	
	//将映射关系先按value比较,若value相同,再按key比较
	public int compare(Map.Entry<Character, Integer> me1, Map.Entry<Character, Integer> me2) {
		if(me1.getValue() == me2.getValue())
			return me1.getKey().compareTo(me2.getKey());
		return me1.getValue() - me2.getValue();
	}
}

 

 

集合的工具类Collections:

import java.util.*;
public class CollectionsDemo {

	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("abcdf");
		list.add("ebf");
		list.add("tree");
		list.add("ebf");
		list.add("bcdf");
		list.add("af");
		
		System.out.println("原List集合:" + list);
		
		Collections.sort(list);		//对list集合排序,按自然顺序;还可以传比较器。
		System.out.println("自然排序后:" + list);
		
		/*Collections.fill(list, "Hello");	//用指定元素替换所有元素
		System.out.println(list);*/
		
		int i = Collections.binarySearch(list, "af");
		System.out.println("“af”在哪? " + i);
		
		String s = Collections.max(list);
		System.out.println("最大的元素是:" + s);
		
		Collections.replaceAll(list, "ebf", "Hello");
		System.out.println("替换后:" + list);
		
		Collections.reverse(list);
		System.out.println("反转后:" + list);
		
		Collections.swap(list, 2, 5);
		System.out.println("交换后:" + list);
		
		//static <T> Comparator<T>  reverseOrder(Comparator<T> cmp)  //★★强行逆转比较器
		//static <T> Collection<T>  synchronizedCollection(Collection<T> c)  //★★非同步变成同步
	
		Collections.shuffle(list);	//将List集合中的元素随机排序。比如:洗牌
		System.out.println(list);
	}

}

 

Properties集合:

是Hashtable的子类,具备Map集合的特点。它里面的键值对都是字符串。

Properties 可保存在流中或从流中加载。是集合和IO流技术相结合的集合容器。

可以用于键值对形式的配置文件。

此类是线程安全的。

 该集合的常用方法:

import java.util.*;
import java.io.*;
public class PropertiesDemo {

	public static void main(String[] args) throws Exception {
		Properties prop = new Properties();
		//添加元素
		prop.setProperty("李四", "20");
		System.out.println(prop.setProperty("张三", "21"));
		//打印设置时返回的值(属性列表中指定键的旧值,如果没有值,则为 null。)
		System.out.println(prop.setProperty("李四", "23"));
		//打印设置后的集合
		System.out.println(prop);
		//获取元素,以键找值
		System.out.println(prop.getProperty("张三"));
		
		//集合中的键集
		Set<String> set = prop.stringPropertyNames();
		System.out.println(set);//[张三, 李四]
		
		//读取配置文件(用相对路径时,放本项目下),将硬盘上的文件加载到了内存中		
		FileReader fr = new FileReader("Properties.config");
		Properties prop2 = new Properties();
		prop2.load(fr);
		//System.out.println(prop2);
		prop2.list(System.out);
		
		//向内存中的集合中添加元素后存入相应的文件中
		prop2.setProperty("wyl", "35");
		BufferedWriter fw = new BufferedWriter(new FileWriter("Properties.config"));
		prop2.store(fw, "This is newer");
		prop2.list(System.out);
		
	}

}

演示软件试用次数限制:

建立配置文件,记录使用的次数

import java.util.*;
import java.io.*;
public class RunCount {

	public static void main(String[] args) throws Exception {		
		//创建流对象关联配置文件
		File file = new File("count.properties");
		if(!file.exists())
			file.createNewFile();
		FileInputStream fis = new FileInputStream(file);

		//创建Properties对象,用于操作配置文件
		Properties prop = new Properties();

		//将流中数据加载到集合当中
		prop.load(fis);		
		String value = prop.getProperty("time");//获取使用次数
		
		int count = 0;
		if(value != null) {
			count = Integer.parseInt(value);//String-->int

			//如果软件使用次数达到5次,则提示用户试用期快到
			if(count>=5) {
				System.out.println("使用次数已到!");
				return;
			}
		}
		count++;//使用一次count自增

		prop.setProperty("time", count+"");//信息存入集合中
		
		FileOutputStream fos = new FileOutputStream(file);
		prop.store(fos, "");//集合中的数据存入硬盘的文件中

		fos.close();
		fis.close();
	}

}

  

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

 详情请查看:http://edu.csdn.net/heima

 

抱歉!评论已关闭.