java中的自动排序集合 ---- 20160809

TreeSet的实现:

http://blog.csdn.net/hudashi/article/details/6943522

TreeMap实现:

http://blog.csdn.net/hudashi/article/details/6944059

需要注意:

1. 当利用comparator比较两个元素相等时,插入的时候会失败。而hashset是发现两个元素相等(即:两个元素的hashcode相同,equals方法比较之后也相等)时,插入失败返回false。这说明可能treeset并不是真正的set,因为即使两个元素的hashcode相同,equals方法比较之后也相等,但是如果comparator返回两个对象不相等,也是可以插入的,而hashset插入事则会失败。

2. 排序只在插入时发生,如果后面你修改了元素的数据,元素的位置不会变。

测试类:

ChineseCharCount, 保存一个字符和它出现的次数。本来想测试读取一个文件中的所有中文字符,然后得到出现最多的字符以及出现了多少次的。本想用treeset进行排序,但是发现不行,最后还是直接用的ArrayList,然后用Collections的sort

(Comparator comparator)方法完成的。

package _00_ReadAndCountChineseCharacters;

public class ChineseCharCount {

	char ch;
	int count;
	
	public ChineseCharCount(char ch, int count) {
		// TODO Auto-generated constructor stub
		this.ch = ch;
		this.count = count;
	}

	public char getCh() {
		return ch;
	}

	public void setCh(char ch) {
		this.ch = ch;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public String toString() {
		return ch + ":appeared " + count + " times";
	}

	public int getCount() {
		return count;
	}

	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		if (obj == null) {
			return false;
		}
		if (obj == this) {
			return true;
		}
		if (!(obj instanceof ChineseCharCount)) {
			return false;
		}
		ChineseCharCount te = (ChineseCharCount) obj;
		if (te.ch == this.ch) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return (ch + "").hashCode();
	}
}

 

ChineseCharComparator,直接通过比较count来对比大小。

package _00_ReadAndCountChineseCharacters;

import java.util.Comparator;

public class ChineseCharComparator implements Comparator<ChineseCharCount>{

	public int compare(ChineseCharCount o1, ChineseCharCount o2) {
		// TODO Auto-generated method stub
		
		if(o1 == o2)
			return 0;
		if(o1!=null&&o2==null)
			return -1;
		else if(o1==null&&o2!=null)
			return 1;
		if (o1.count < o2.count)
			return 1;
		else if (o1.count > o2.count)
			return -1;
		else
			return 0;
	}
}

ReadAndCountChineseCharacters,测试类。直接读取文件,count,然后排序,输出前三。

package _00_ReadAndCountChineseCharacters;

import java.io.FileReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.TreeSet;

public class ReadAndCountChineseCharacters {

	public static void main(String[] args) throws Exception {
		String classPath = ReadAndCountChineseCharacters.class.getResource("").getPath();
		System.out.println(classPath);
		String filePath = classPath + "ChineseSentence.txt";
		// InputStream in = new FileInputStream(filePath);

		
		List<ChineseCharCount> chList = new ArrayList<ChineseCharCount>();

		FileReader fr = new FileReader(filePath);
		int i;
		while ((i = fr.read()) != -1) {
			char next = (char) i;
			if(next == '\n' || next  == '\t')
				continue;
			boolean hasCh = false;
			for (ChineseCharCount chCount : chList) {
				if (next == chCount.ch) {
					hasCh = true;
					chCount.count = chCount.count + 1;
					break;
				}
			}
			if (!hasCh) {
				chList.add(new ChineseCharCount(next, 1));
				
			}
		}
		fr.close();
		
		ChineseCharComparator comparator = new ChineseCharComparator();
		Collections.sort(chList, comparator);
		
		for (int j = 0; j < 3; j++) {
			System.out.println(chList.get(j));
		}
	}

}

 TestTreeSet 编写排序时,遇到的问题,通过下面的测试类进行了总结:

package _00_ReadAndCountChineseCharacters;

import java.util.HashMap;
import java.util.HashSet;
import java.util.TreeSet;

public class TestTreeSet {
	
	public static void main(String[] args) {
		
		ChineseCharCount ch = new ChineseCharCount('a', 1);
		ChineseCharCount ch2 = new ChineseCharCount('a', 2);
		ChineseCharCount ch3 = new ChineseCharCount('a', 1);
		ChineseCharCount ch4 = new ChineseCharCount('c', 1);
		
		ChineseCharComparator comparator = new ChineseCharComparator();
		TreeSet<ChineseCharCount> treeSet = new TreeSet<>(comparator);
		HashSet<ChineseCharCount> hashSet = new HashSet<>();
		
		HashMap<String, String> haspMap = new HashMap<>();
		
		/*
		 * Associates the specified value with the specified key in this map. 
		 * If the map previously contained a mapping for the key, the old value is replaced.
		 * 
		 * the previous value associated with key, or null if there was no mapping for key. 
		 * (A null return can also indicate that the map previously associated null with key.)
		 */
		haspMap.put("1", "1");
		
		System.out.println("abc123".hashCode());
		System.out.println("".hashCode());
		System.out.println(new String("abc123").hashCode());
		System.out.println(new String("").hashCode());
		
		
		/*
		 * Adds the specified element to this set if it is not already present. 
		 * More formally, adds the specified element e to this set if the set 
		 * contains no element e2 such that (e==null ? e2==null : e.equals(e2)). 
		 * If this set already contains the element, the call leaves the set unchanged and returns false.
		 */
		System.out.println("add into treeset");
		System.out.println(treeSet.add(ch));
		System.out.println(treeSet.add(ch2));
		System.out.println(treeSet.add(ch3));
		System.out.println(treeSet.add(ch4));
		
		
		/*
		 * Adds the specified element to this set if it is not already present. 
		 * More formally, adds the specified element e to this set if this set 
		 * contains no element e2 such that (e==null ? e2==null : e.equals(e2)). 
		 * If this set already contains the element, the call leaves the set unchanged and returns false.
		 */
		System.out.println("add into hashSet");
		System.out.println(hashSet.add(ch));
		System.out.println(hashSet.add(ch2));
		System.out.println(hashSet.add(ch3));
		System.out.println(hashSet.add(ch4));
		System.out.println("From the test result we can see, "
				+ "treeset is not really a set. AS it allowed duplicate "
				+ "attribute(determinter by hashCode and equals method). "
				+ "Instead, it didn't allwed two attributes wihich is "
				+ "equals to each other(determined by the comparator).");
		
		
		/*
		 * 从测试结果可以看出,如果两个元素利用comparator进行比较是相等的插入会失败。
		 */
		for(ChineseCharCount chs : treeSet)
			System.out.println(chs);
		
		treeSet.first().count = 0;
		treeSet.last().count = 2;
		System.out.println(treeSet.add(ch3));
		
		
		/*
		 * 从测试结果可以看出,treeset只会在存入set的时候进行排序,
		 * 当做了更改时不会重新排序。
		 */
		for(ChineseCharCount chs : treeSet)
			System.out.println(chs);
		
		
	}

}

猜你喜欢

转载自simon-9527.iteye.com/blog/2316476