TreeMap是基于红黑树(red black tree)算法和NavigableMap实现的。
注意,此实现不是同步的。如果多个线程同时访问一个映射,并且其中至少一个线程从结构上修改了该映射,则其必须 外部同步。(结构上的修改是指添加或删除一个或多个映射关系的操作;仅改变与现有键关联的值不是结构上的修改。)这一般是通过对自然封装该映射的对象执行同步操作来完成的。如果不存在这样的对象,则应该使用 Collections.synchronizedSortedMap
方法来“包装”该映射。最好在创建时完成这一操作,以防止对映射进行意外的不同步访问,如下所示:
SortedMap m = Collections.synchronizedSortedMap(new TreeMap(...));
TreeMap是泛型类,K代表key(键)的类型,V代表value(值)的类型,它继承了类AbstractMap,实现了接口:
Serializable, Cloneable, Map<K,V>, NavigableMap<K,V>, SortedMap<K,V>
public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
/**
* The comparator used to maintain order in this tree map, or
* null if it uses the natural ordering of its keys.
*
* @serial
*/
private final Comparator<? super K> comparator;
private transient Entry<K,V> root = null;
/**
* The number of entries in the tree
*/
private transient int size = 0;
/**
* The number of structural modifications to the tree.
*/
private transient int modCount = 0;
它的3个构造函数如下:
(1)使用这个构造函数,因为comparator为null,但是TreeMap会按照key来排序,所以key对象要实现Comparable接口
public TreeMap() {
comparator = null;
}
public TreeMap(Comparator<? super K> comparator) {
this.comparator = comparator;
}
(3)相当于将传入的Map复制给了当前的TreeMap
Constructs a new tree map containing the same mappings and using the same ordering as the specified sorted map. This method runs in linear time.
传入的Map的key对象要实现Comparable接口
public TreeMap(Map<? extends K, ? extends V> m) {
comparator = null;
putAll(m);
}
Comparble和Comparator使用见读JDK源码(二):Comparable接口和Comparator接口
下面从增删查改角度介绍TreeMap的使用,直接看代码:
package zyang.map;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* @author secret
* @version 1.0
* @date 2012-11-30 上午10:00:05
* @fuction TreeMap的使用(增删查改)
*/
public class TreeMapTest {
//print
public static void printElements(Collection c)
{
Iterator it =c.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
} //printElements(Collection c)
/**
* @param args
*/
public static void main(String[] args) {
Map tm=new TreeMap();
//1 插入元素
tm.put("shanghai", new Student(0, "shanghai"));
tm.put("beijing", new Student(1, "beijing"));
tm.put("上海", new Student(0, "上海"));
tm.put("北京", new Student(1, "北京"));
//2 删除(根据key值删除)
//tm.remove("lisi");
//3 修改(根据key值修改)
//tm.put("zhangsan", new Student(0, "lisi"));
//------------------4 查找元素-------------------------------
// //根据key值得到元素
// Student s=(Student)tm.get("wangwu");
//
// //key的所有值
// Set keys=tm.keySet();
// printElements(keys);
//
// //value的所有值
// Collection values=tm.values();
// printElements(keys);
//4.1 查找元素方法一(跟据key值查找元素)
Set keys=tm.keySet();
//printElements(keys);
Iterator it=keys.iterator();
while(it.hasNext())
{
String key=(String)it.next();
Student value=(Student)tm.get(key);
System.out.println("key="+key+",student="+value);
}
// //4.2 查找元素方法二(根据Entry类型[Entry是键值对(键和值)]查找)
// Set entry=tm.entrySet();
// //printElements(entry); //打印出来是类似这样的结果:key1=value1 key2=value2
// Iterator entryIt=entry.iterator();
// while(entryIt.hasNext())
// {
// Map.Entry me=(Map.Entry)it.next();
// String key=(String)me.getKey();
// Student value=(Student)me.getValue();
// }
}
}
Student类如下:
public class Student {
//学号
int num;
//姓名
String name;
//constructor
public Student (int num,String name)
{
this.num=num;
this.name=name;
}
@Override
public String toString() {
return "Student [num=" + num + ", name=" + name + "]";
}
}
输出结果如下:
key=beijing,student=Student [num=1, name=beijing]
key=shanghai,student=Student [num=0, name=shanghai]
key=上海,student=Student [num=0, name=上海]
key=北京,student=Student [num=1, name=北京]
上述输出结果中key的排序如下:
beijing shanghai 上海 北京
英文排序正确,但是中文排序则明显的不正确,北京应该在上海之前。上述排序key因为是字符串(而字符串默认实现了Comparble接口)。这个主要是java中使用中文编码GB2312或者JBK时,char型转换成int型得过程出现了比较大的偏差。Java中之所以出现偏差,主要是compare方法的问题,所以这里自己实现Comparator接口,而国际化的问题,使用Collator类来解决。代码如下:
package zyang.map;
import java.text.CollationKey;
import java.text.Collator;
import java.util.Comparator;
/**
* @author yangzhong E-mail:[email protected]
* @version 1.0
* @date 2012-11-30 下午3:36:52
* @fuction
*/
public class ChineseComparator implements Comparator
{
Collator collator=Collator.getInstance();
public int compare(Object o1, Object o2) {
CollationKey key1=collator.getCollationKey(o1.toString());
CollationKey key2=collator.getCollationKey(o2.toString());
return key1.compareTo(key2);
}
}
修改TreeMapTest中找到创建TreeMap的构造函数
Map tm=new TreeMap();
需要修改为
Comparator chineseComparator=new ChineseComparator();
Map tm=new TreeMap(chineseComparator);
再次运行TreeMapTest结果如下:
key=beijing,student=Student [num=1, name=beijing]
key=shanghai,student=Student [num=0, name=shanghai]
key=北京,student=Student [num=1, name=北京]
key=上海,student=Student [num=0, name=上海]
可以看到中文排序正确了
这篇文章分析的不错: