更好的使用Java集合(四)

    集合(List)可以快速地查找现有的元素。但是,要查看一个元素,需要有要查找元素的精确副本。这不是一种非常通用的查询方式。通常,如果知道某些键的信息,并想要查找与之对应的元素,则可以使用映射表(map)。

    Java类库中提供了两个通用的实现:HashMap和TreeMap。它们都实现了Map接口。    

    散列映射表HashMap对键进行散列,树映射表TreeMap用键的整体顺序对元素进行排序,并将其组织成搜索树。散列或比较函数只能作用于键。与键关联的值不能进行散列或比较。

    这两个Map的性能哪个更好呢?与集合一样,散列稍微快一些。如果不需要按照排列顺序访问键,就最好选择散列。

    每当往映射表里添加对象时,必须同时提供一个对象的键(key),键是一个字符串,对应的值可以是对象。

    @Test
    public void HashMapTest() {
        HashMap<String, Task> map = new HashMap<String, Task>();
        Task task1 = new Task("task1", 1);
        Task task2 = new Task("task2", 2);
        Task task3 = new Task("task3", 3);
        map.put("t1", task1);
        map.put("t2", task2);
        map.put("t3", task3);
        
        System.out.println(map.get("t1").name);
        /**
         * output:task1
         * */
        
        Task task4 = new Task("task4", 4);
        map.put("t1", task4);
        System.out.println(map.get("t1").name);
        /**
         * output:task4
         * */
        
        System.out.println(map.get("t5"));
        /**
         * output:null
         * */
        
        //    在map中删除一项。3-1=2。
        map.remove("t1");
        
        
        System.out.println(map.size());
        /**
         * output:2
         * */
    }

    如上面的代码所见,在put时候将对象放入map,如果对同一个键两次调用put方法,第二个值就会取代第一个值。如果在映射表中没有与给定键对应的信息,get将返回null。

    remove方法用于删除给定键对应的元素,size方法用于返回元素表中的元素数量。

    集合框架并没有将映射表本身视为一个集合(其他的数据结构框架则将映射表视为pairs的集合,也就是对儿的集合,一对的意思,或者视为用键作为索引的值的集合)。然而,可以获得映射表的视图。视图实现了Collection接口对象。

    有三个视图,分别是键集合、值集合和键/值集合:

  •     Set<K> KeySet();

  •     Collection<K> values();

  •     Set<Map.Entry<K,V>> enterSet();

    第一个KeySet既不是HashSet也不是TreeSet,而是实现了Set接口的某个其他类的对象。Set接口拓展了Collection接口。因此,可以与使用任何集合一样使用KeySet。

    使用keyset的代码如下:

    @Test
    public void HashMapTest() {
        HashMap<String, Task> map = new HashMap<String, Task>();
        Task task1 = new Task("task1", 1);
        Task task2 = new Task("task2", 2);
        Task task3 = new Task("task3", 3);
        map.put("t1", task1);
        map.put("t2", task2);
        map.put("t3", task3);
        
        Set<String> keys = map.keySet();
        for(String key : keys) 
            System.out.println(key);
        /**
         * output:
         * t1,t2,t3
         * */
    }

    如果想要同时查看键与值,就可以通过每句哥哥条目(entries)查看,以避免对值进行查找。可以使用下面这段代码框架:

@Test
    public void HashMapTest() {
        HashMap<String, Task> map = new HashMap<String, Task>();
        Task task1 = new Task("task1", 1);
        Task task2 = new Task("task2", 2);
        Task task3 = new Task("task3", 3);
        map.put("t1", task1);
        map.put("t2", task2);
        map.put("t3", task3);

        for(Map.Entry<String, Task> entry : map.entrySet()) {
            String key = entry.getKey();
            Task task = entry.getValue();
            //    从写了Task类的toString方法。
            System.out.println("key = " + key + ", value = " + task.toString() + ";");
        }
        /**
         * output:
         * key = t1, value = Task [name=task1, priority=1];
         * key = t2, value = Task [name=task2, priority=2];
         * key = t3, value = Task [name=task3, priority=3];
         * */
    }

    如果调用迭代器的remove方法,实际上就从映射表中删除了键以及对应的值。但是,不能将元素添加到视图中。如果只添加值是毫无意义的。如果试图调用add方法,将会抛出UnsupportedOperationException异常。


你可能感兴趣的:(更好的使用Java集合(四))