码迷,mamicode.com
首页 > 编程语言 > 详细

JAVA集合体系回顾(2)

时间:2016-07-24 07:04:04      阅读:239      评论:0      收藏:0      [点我收藏+]

标签:

由于上一篇文章的篇幅实在太长了,讲的都是单列集合,这篇文章将单独介绍双列集合Map的使用.

Map双列集合根接口

如果程序中存储了几百万个学生,而且经常需要使用学号来搜索某个学生,那么这个需求有效的数据结构就是Map。Map是一种依照键(key)存储元素的容器,键(key)很像下标,在List中下标是整数。在Map中键(key)可以使任意类型的对象。Map中不能有重复的键(Key),每个键(key)都有一个对应的值(value)。一个键(key)和它对应的值构成map集合中的一个元素。
Map中的元素是两个对象,一个对象作为键,一个对象作为值。键唯一、值可重复(新值覆盖旧值)

Map接口的共性方法

操作 含义 返回值
put(K key, V value) 存储元素的时候,当key相同时,则添加失败,但是添加的value值会覆盖被替换的值,并且会返回那个被替换的值,如果添加元素成功则返回 null。 Object
putAll(Map m) 调用该方法是将另一个map集合的元素添加到当前集合中。 void
remove(Object key) 根据该键删除其值并返回该调用者 Object
clear() 清空集合对象 void
get(key) 根据键获取其值 Object
size() 获取长度 int
values() 获取map集合的所有值并返回一个Collection集合中 Collection
isEmpty() 长度为0返回true否则false boolean
containsKey(Object key) 判断集合中是否包含指定的key boolean
containsValue(Object value) 判断集合中是否包含指定的value boolean

相同key替换value的示例

public class _Main44 {
    public static void main(String[] args) {
        Map<Integer,String> map = new HashMap<Integer,String>();
        map.put(1, "a");
        map.put(2, "b");
        map.put(3, "c");
        map.put(4, "d");
        //key相同,value不同,返回的是被替换的那个Value
        System.out.println(map.put(1, "g"));

        System.out.println(map);
        //将map中所有的value提取并返回到Collection集合中
        Collection<String> c = map.values();
        System.out.println(c);
    }
}

运行结果:
技术分享

Map集合的遍历

注意在Map体系的集合中,是没有Iterator迭代器可用,所以Map集合有自己的迭代方式。
1、Set keySet():该方法返回的是Map集合中的所有键,并存储到Set集合中。
2、Set entrySet() :获取Map集合中的所有键值对(关系)并返回到一个Set集合中。

通过keySet迭代Map集合

步骤:
1.调用map接口的keySet方法,获取map集合中的所有键,并存储到Set集合中。
2.通过Set接口的iterator方法创建迭代器,遍历Set集合中所存储的键值。
3.在遍历的过程中通过Map集合的get方法,获取对应键的值。

class Demo1 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("张三", "小红");
        map.put("李四", "小兰");
        map.put("王五", "小花");

        // 通过keySet方法获取map集合的键和值
        Set<String> keys = map.keySet();
        // 使用Set集合的iterator方法创建迭代器对象
        Iterator<String> it = keys.iterator();
        while (it.hasNext()) {
            // 通过迭代逐个获取Set集合中锁存储的键
            String key = it.next();
            // 通过map集合的get方法获取对应键的值
            System.out.println("键:" + key + " 值:" + map.get(key));
        }
    }
}

运行结果:
技术分享

通过entrySet迭代Map集合

步骤:
1.调用Map集合的entrySet方法,获取所有的键值对并返回到Set集合中
2.创建Set集合的迭代器,遍历Set集合中的所有键值对(关系)对象
3.在遍历键值对的时候,通过键值对对象调用Entry接口的特有方法getKey()和getValue()获取分别获取Map结合的键和值。

public class Demo1 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("张三", "小红");
        map.put("李四", "小兰");
        map.put("王五", "小花");
        // 调用entrySet方法获取键值对并存储到Set集合中
        Set<Map.Entry<String, String>> entries = map.entrySet();
        // 通过Set集合创建迭代器
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        while (iterator.hasNext()) {
            // 迭代取出Set集合中的所有键值对(关系)返回的是Entry接口类型
            Map.Entry<String, String> entry = iterator.next();
            // 通过方法getValue得到键值
            String values = entry.getValue(); 
            // 通过方法getKey得到键
            String keys = entry.getKey(); 
            System.out.println("键:" + keys + "  值:" + values);
        }
    }
}

运行结果:
技术分享

Map接口的内部接口Entry

在Map接口的内部还定义了一个Entry接口,该接口特有方法如下:
1.boolean equals(Object o)
比较指定对象与此项的相等性。
2.K getKey()
返回与此项对应的键。
3. V getValue()
返回与此项对应的值。
4.int hashCode()
返回此映射项的哈希码值。
5.V setValue(V value)
用指定的值替换与此项对应的值(可选操作)。

HashMap集合类

底层是哈希表数据结构,线程是不同步的,可以存入null键,null值。要保证键的唯一性,需要覆盖hashCode方法,和equals方法。元素是不可重复、无存储顺序的

HashMap的存储原理

HashMap存储元素的方式是无序的,原理和HashSet集合一样。
往HashMap存储元素的时候,首先会调用键的hashCode得到元素的哈希码值,然后算出该数据在哈希表中的存储位置。

情况1:根据键的哈希码算出的位置目前没有任何元素存储,那么该元素可以直接添加。
情况2: 根据键的哈希码算出的位置目前已经有了其他元素存储了,那么还会调用键的的equals方法再与这个位置的元素再比较一次。如果equals方法返回的是true,那么该元素不允许被添加,如果equals方法返回的是false,那么该元素允许添加。

TreeMap集合类

可以对进行自然排序,所以存储有序。底层是二叉树数据结构。可 以对map集合中的键进行排序。需要实现Comparable接口复写 compareTo方法或者自定义类实现Comparator接口,创建比较 器来对键值进行比较排序。return 0,来判断键的唯一性。

TreeMap的排序,TreeMap可以对集合中的键进行排序。如何实现键的排序?
方式一:元素自身具备比较性(自然排序)
和TreeSet一样原理,需要让存储在键位置的对象实现Comparable接口,重写compareTo方法,也就是让元素自身具备比较性,这种方式叫做元素的自然排序也叫做默认排序。
方式二:容器具备比较性
当元素自身不具备比较性,或者自身具备的比较性不是所需要的。那么此时可以让容器自身具备。需要定义一个类实现接口Comparator,重写compare方法,并将该接口的子类实例对象作为参数传递给TreeMap集合的构造方法。
注意:当Comparable比较方式和Comparator比较方式同时存在时,以Comparator的比较方式为主;
注意:在重写compareTo或者compare方法时,必须要明确比较的主要条件相等时要比较次要条件。(假设姓名和年龄一致的人为相同的人,如果想要对人按照年龄的大小来排序,如果年龄相同的人,需要如何处理?不能直接return 0,以为可能姓名不同(年龄相同姓名不同的人是不同的人)。此时就需要进行次要条件判断(需要判断姓名),只有姓名和年龄同时相等的才可以返回0.)

TreeMap的存储原理

原理和TreeSet类似
1. 往TreeMap添加元素的时候,如果元素的键是具备自然顺序的特性,那么会根据键的自然顺序进行排序存储。
2. 往TreeMap添加元素的时候,如果数据的键不具备自然顺序的特性,那么键所属的类必须要实现Comparable接口。把比较的规则定义在CompareTo方法中。
3. 往TreeMap添加元素的时候,如果数据的键不具备自然顺序的特性,而且键所属的类没有实现Comparable接口,那么可以在创建TreeMap对象的时候传入一个比较器对象。

注意
Set集合是元素不可重复,Map是键不可重复.
如果存入重复元素如何处理?
Set的重复元素不能存入,add方法返回false
Map的重复键将覆盖旧键,put方法返回旧键对应的值。

自定义TreeMap的排序规则

还是上一篇文章的比较器

/**
 * 自定义一个比较器类,通过id
 * 
 * @author mChenys
 * 
 */
public class MyComparator implements Comparator {
    /**
     * Compare方法中就写两个元素比较的规则。 
     * 如果o1小于o2,返回一个负数;如果o1大于o2,返回一个正数;如果他们相等,则返回0;
     */
    public int compare(Object o1, Object o2) {
        if (o1 instanceof Emp && o2 instanceof Emp) {
            Emp e1 = (Emp) o1;
            Emp e2 = (Emp) o2;
            return e1.id - e2.id;
        }
        return 0;
    }
}

排序操作

/**
 * 对TreeMap集合的key进行按Emp的id进行排序
 * @author mChenys
 *
 */
public class TreeMapSort {
    public static void main(String[] args) {
        MyComparator comparator = new MyComparator();
        TreeMap<Emp, Integer> map = new TreeMap<Emp, Integer>(comparator);
        map.put(new Emp(117, "哈哈", 3000), 1);
        map.put(new Emp(222, "呵呵", 1000), 2);
        map.put(new Emp(250, "嘻嘻", 500), 3);
        map.put(new Emp(300, "吼吼", 2000), 4);
        System.out.println("集合的元素是:" + map);
    }
}

运行结果:
技术分享

集合工具类Collections

常用方法
1,对list集合进行排序。
sort(list);
sort(list,comaprator);

2, 对list进行二分查找,返回索引位置:
int binarySearch(list,key);
int binarySearch(list,key,Comparator);

3,对集合取最大值或者最小值。
max(Collection)
max(Collection,comparator)
min(Collection)
min(Collection,comparator)

4,对list集合进行反转。 对集合中的元素进行翻转。
reverse(list);

5,对比较方式进行强行逆转。
Comparator reverseOrder();
Comparator reverseOrder(Comparator);

6,对list集合中的元素进行位置的置换。
swap(list,x,y);

7,对list集合进行元素的替换。如果被替换的元素不存在,那么原集合不变。
replaceAll(list,old,new);

8,可以将不同步的集合变成同步的集合。
Set synchronizedSet(Set s)
Map synchronizedMap(Map m)
List synchronizedList(List list)

JAVA集合体系回顾(2)

标签:

原文地址:http://blog.csdn.net/mchenys/article/details/52011376

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!