ListMap总结

Collection接口的子接口有List,Set。
List接口的常用实现类有ArrayList,LinkedList,Vector。
其中ArrayList和LinkedList是线程不同步的,可以用List list = Collections.synchronizedList(new ArrayList(…)),List list = Collections.synchronizedList(new LinkedList(…))来包装; Vector是线程同步的。
ArrayList和Vector的底层实现是数组,LinkedList的底层实现是链表。
ArrayList查询快,增删慢,LinkedList增删快,查询慢。
List元素是有序的,也是可以重复的,所有的List中可以有null元素。
对List的遍历有两个迭代器,Iterator和ListIterator。区别是Iterator只支持向前遍历,ListIterator支持双向遍历。
对List排序的两种方法:
1、List中存放的对象自身实现Comparable接口,实现comparaTo方法,然后调用Collections.sort(list)进行排序。
2、自定义比较器实现Comparator接口,实现compare方法,然后调用Collections.sort(list,new MyComparator())进行排序。
Set接口的常用实现类有HashSet和TreeSet。
HashSet和TreeSet都是线程不同步的,可以用Set s = Collections.synchronizedSet(new HashSet(…)),SortedSet s = Collections.synchronizedSortedSet(new TreeSet(…))来包装。
HashSet是在HashMap的基础上实现的,HashSet的存储方式是把HashMap中的Key作为Set的对应存储项。
TreeSet是在SortedMap接口的基础上实现的.
HashSet的底层实现是哈希表,TreeSet的底层实现是二叉树。
Set的元素是无序的,这里的无序是指存入和取出的顺序不一定一致。因为TreeSet本身的存储结构是有序的。
Set的元素是不可以重复的。
HashSet保证元素唯一性的方法:
HashSet是通过元素的两个方法hashCode和equals来完成,如果元素的HashCode值相同,才会判断equals是否也为true,如果HashCode不同则不再调用equals。所以一般自定义对象想往集成Set的集合里存时都会根据需求重写hashCode和equals方法。
HashSet判断元素是否存在以及删除等操作时,依赖的方法是元素的hashCode和equals方法。
通过重写hashCode方法可以使不同对象的HashCode值相同,也即不同的对象hashCode值也可能相同,但只要他们的equals不同,同样可以共存于Set集合中。
TreeSet集合存数据时默认调用compareTo方法来比较对象的大小,根据compareTo方法比较结果的大小进行排序,正值代表大的,负值代表小的,值为0时不存。所以用TreeSet存储自定义对象时要先实现Comparable接口,根据需求的排序方式重写compareTo方法,才能进行存储。
TreeSet保证元素唯一性的依据是compareTo方法return 0。
TreeSet的两种排序方式:
1、默认的排序方式,让元素自身具有比较性,元素实现Comparable接口,重写compareTo方法,制定元素的排序规则。
2、当元素自身不具有比较性或者比较性不是所需要的时,就需要让集合自身具备比较性,操作方法是定义比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
当两种排序方式都存在时以第二种方式比较器方式为主。第二种方式的好处是如果存入Set的多个类具有相同的排序算法,就不用重复定义相同的排序算法,只要实现Comparator接口即可。

Map
常用的Map有HashMap,TreeMap,HashTable,LinkedHashMap。
HashMap、TreeMap和LinkedHashMap不是线程同步的,可以用Map m = Collections.synchronizedMap(new HashMap(…)),SortedMap m = Collections.synchronizedSortedMap(new TreeMap(…)); Map m = Collections.synchronizedMap(new LinkedHashMap(…));来包装;HashTable是线程同步的。
一:起因:

(1)现实中需要Map容器进行排序的情况很多很多:因为Map<key,value>键值对的存储结构特别是HashMap的结构是非常优秀的,数据存储就难免对其进行排序;

(2)数据处理,只要用到映射关系的,离不开Map,这在数据处理中是非常实用的,而排序是对数据的进一步处理;

(3)Map排序的方式有很多种,两种比较常用的方式:按键排序(sort by key), 按值排序(sort by value)

二:排序的算法

(1)按键排序
jdk内置的java.util包下的TreeMap<K,V>既可满足此类需求,向其构造方法 TreeMap(Comparator<? super K> comparator) 传入我们自定义的比较器即可实现按键排序。

// 主类

public class MapSortDemo {  
    public static void main(String[] args) {  
        Map<String, String> map = new TreeMap<String, String>();  
        map.put("KFC", "kfc");  
        map.put("WNBA", "wnba");  
        map.put("NBA", "nba");  
        map.put("CBA", "cba");  
        Map<String, String> resultMap = sortMapByKey(map);    //按Key进行排序  
        for (Map.Entry<String, String> entry : resultMap.entrySet()) {  
            System.out.println(entry.getKey() + " " + entry.getValue());  
        }  
    }  
/** 
 * 使用 Map按key进行排序 
 * @param map 
 * @return 
 */  
public static Map<String, String> sortMapByKey(Map<String, String> map) {  
    if (map == null || map.isEmpty()) {  
        return null;  
    }  
    Map<String, String> sortMap = new TreeMap<String, String>(new MapKeyComparator());  
    sortMap.putAll(map);  
    return sortMap;  
}  

}

//比较器类

public class MapKeyComparator implements Comparator<String>{  
    public int compare(String str1, String str2) {  
        return str1.compareTo(str2);  
    }  
}

说明一:比较器类,MapKeyComparator implements Comparator 中的参数是通过类似模板类的Comparator<>传进来的,再重载其compare()函数即可,比较简单。
说明二:主类中的 sortMapByKey(Map<String, String> map) 函数中声明TreeMap<String,String>(new MapKeyComparator())进行key值排序,再调用sortMap.putAll(map) 复制到新的map中。

说明三:数据是用TreeMap存储的。

(2)按值排序

按值排序就相对麻烦些了,貌似没有直接可用的数据结构能处理类似需求,需要我们自己转换一下。

Map本身按值排序是很有意义的,很多场合下都会遇到类似需求,可以认为其值是定义的某种规则或者权重。
原理:将待排序Map中的所有元素置于一个列表中,接着使用Collections的一个静态方法 sort(List list, Comparator<? super T> c)

来排序列表,同样是用比较器定义比较规则。排序后的列表中的元素再依次装入Map,为了肯定的保证Map中元素与排序后的List中的元素的顺序一致,使用

LinkedHashMap数据类型

// 主类

public class MapSortDemo {  
    public static void main(String[] args) {  
        Map<String, String> map = new TreeMap<String, String>();  
        map.put("KFC", "kfc");  
        map.put("WNBA", "wnba");  
        map.put("NBA", "nba");  
        map.put("CBA", "cba");  
        Map<String, String> resultMap = sortMapByValue(map); //按Value进行排序  
        for (Map.Entry<String, String> entry : resultMap.entrySet()) {  
            System.out.println(entry.getKey() + " " + entry.getValue());  
        }  
    }  
/** 
 * 使用 Map按value进行排序 
 * @param map 
 * @return 
 */  
public static Map<String, String> sortMapByValue(Map<String, String> map) {  
    if (map == null || map.isEmpty()) {  
        return null;  
    }  
    Map<String, String> sortedMap = new LinkedHashMap<String, String>();  
    List<Map.Entry<String, String>> entryList = new ArrayList<Map.Entry<String, String>>(map.entrySet());  
    Collections.sort(entryList, new MapValueComparator());  
    Iterator<Map.Entry<String, String>> iter = entryList.iterator();  
    Map.Entry<String, String> tmpEntry = null;  
    while (iter.hasNext()) {  
        tmpEntry = iter.next();  
        sortedMap.put(tmpEntry.getKey(), tmpEntry.getValue());  
    }  
    return sortedMap;  
}  

}

//比较器类

public class MapValueComparator implements Comparator<Map.Entry<String, String>> {  
    public int compare(Entry<String, String> me1, Entry<String, String> me2) {  
        return me1.getValue().compareTo(me2.getValue());  
    }  
}  

说明一:比较器类,MapValueComparator implements Comparator<Map.Entry<String,String>> 中的参数是通过类似模板类的Comparator<>传进来的,再重载其compare()函数即可,只是参数是Map.Entry<String,String>的接口类,compare()函数的两个参数也相应的变为Entry<String,String>。

说明二:主类中的 sortMapByKey(Map<String, String> map) 函数中声明LinkedHashMap<String,String>再用ArrayList<Map.Entry<String,String>>(map.entrySet())进行List形式的存储,再调用collections.sort(entryList,

new MapKeyComparator())进行排序;最后把entryList转化为LinkedMap

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值