TreeSet的实现:
TreeMap实现:
需要注意:
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{
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 chList = new ArrayList();
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 treeSet = new TreeSet<>(comparator);
HashSet hashSet = new HashSet<>();
HashMap 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);
}
}