美文网首页Java
Set List Map的定义和KeySet(), values

Set List Map的定义和KeySet(), values

作者: 史慧君 | 来源:发表于2017-04-24 16:17 被阅读416次

    一 Set List Map的定义

    1. 什么是set
    Set的功能方法

    Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像前面有两个不同的List。实际上Set就是Collection,只 是行为不同。(这是继承与多态思想的典型应用:表现不同的行为。)Set不保存重复的元素(至于如何判断元素相同则较为负责)

    Set : 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。

    HashSet:为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。
    TreeSet: 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
    LinkedHashSet:具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。

    Set 的用法:存放的是对象的引用,没有重复对象
            Set set = new HashSet();
            String s1 = new String("hello");
            String s2 = s1;
            String s3 = new String("world");
            set.add(s1);
            set.add(s2);
            set.add(s3);
            System.out.println(set.size());// 打印集合中对象的数目 为 2。
    

    set<泛型> set=new HashSet<泛型>();
    其中泛型可以是String 类型 Integer类型,也可以自己创建的对象方入其中,这属于最简单的创建Set的事例
    其中set中可以存放重复的数据集

    set的遍历:
    boolean isExists = false;
            Iterator iterator = set.iterator();
            while (it.hasNext()) {
                String oldStr = it.next();
                if (newStr.equals(oldStr)) {
                    isExists = true;
                }
            }
    
    什么是list:

    List的特征是其元素以线性方式存储,集合中可以存放重复对象。

    List接口主要实现类

    实际上有两种List:一种是基本的ArrayList,其优点在于随机访问元素,另一种是更强大的LinkedList,它并不是为快速随机访问设计的,而是具有一套更通用的方法。

    •List:次序是List最重要的特点:它保证维护元素特定的顺序。List为Collection添加了许多方法,使得能够向List中间插入与移除元素(这只推 荐LinkedList使用。)一个List可以生成ListIterator,使用它可以从两个方向遍历List,也可以从List中间插入和移除元素。

    •ArrayList:由数组实现的List。允许对元素进行快速随机访问,但是向List中间插入与移除元素的速度很慢。ListIterator只应该用来由后向前遍历 ArrayList,而不是用来插入和移除元素。因为那比LinkedList开销要大很多。

    •LinkedList :在实现中采用链表数据结构。插入和删除速度快,访问速度慢。对顺序访问进行了优化,向List中间插入与删除的开销并不大。随机访问则相对较慢。(使用ArrayList代替。)还具有下列方 法:addFirst(), addLast(), getFirst(), getLast(), removeFirst() 和 removeLast(), 这些方法 (没有在任何接口或基类中定义过)使得LinkedList可以当作堆栈、队列和双向队列使用。

    对于List的随机访问来说,就是只随机来检索位于特定位置的元素。 List 的 get(int index) 方法放回集合中由参数index指定的索引位置的对象,下标从“0” 开始。

    最基本的两种检索集合中的所有对象的方法:

    1: for循环和get()方法:

            for (int i = 0; i < list.size(); i++) {
                System.out.println(list.get(i));
            }
    

    2: 使用 迭代器(Iterator):

            Iterator it = list.iterator();
            while (it.hashNext()) {
                System.out.println(it.next());
            }
    
    
    什么是Map:

    俗话说学习要学会类比,map对象也一样。目录所有人都知道吧左边的内容,右边对应的是页码,你只要找到页码所在的页就就可以知道这个页码的内容了。回到map对象也是一个意思,比如:
    Map<1,"我">你只要得到Map里面的key1 他对应得到的value值就是我。

    Map 是一种把键对象和值对象映射的集合,它的每一个元素都包含一对键对象和值对象。
    Map没有继承于Collection接口 从Map集合中检索元素时,只要给出键对象,就会返回对应的值对象。

    Map 的常用方法:

    1 添加,删除操作:

    Object put(Object key, Object value): //向集合中加入元素 
    Object remove(Object key): //删除与KEY相关的元素 
    void putAll(Map t):  //将来自特定映像的所有元素添加给该映像 
    void clear()://从映像中删除所有映射 
    

    2 查询操作:

    Object get(Object key):获得与关键字key相关的值 。Map集合中的键对象不允许重复,也就说,任意两个键对象通过equals()方法比较的结果都是false.但是可以将任意多个键独享映射到同一个值对象上。

    Map的功能方法

    方法put(Object key, Object value)添加一个“值”(想要得东西)和与“值”相关联的“键”(key)(使用它来查找)。
    方法get(Object key)返回与给定“键”相关联的“值”。可以用containsKey()和containsValue()测试Map中是否包含某个“键”或“值”。
    标准的Java类库中包含了几种不同的Map:HashMap, TreeMap, LinkedHashMap, WeakHashMap, IdentityHashMap。它们都有同样的基本接口Map,但是行为、效率、排序策略、保存对象的生命周期和判定“键”等价的策略等各不相同。

    执行效率是Map的一个大问题。看看get()要做哪些事,就会明白为什么在ArrayList中搜索“键”是相当慢的。而这正是HashMap提高速 度的地方。HashMap使用了特殊的值,称为“散列码”(hash code),来取代对键的缓慢搜索。“散列码”是“相对唯一”用以代表对象的int值,它是通过将该对象的某些信息进行转换而生成的。所有Java对象都 能产生散列码,因为hashCode()是定义在基类Object中的方法。

    HashMap就是使用对象的hashCode()进行快速查询的。此方法能够显着提高性能。

    Map : 维护“键值对”的关联性,使你可以通过“键”查找“值”

    HashMap:Map基于散列表的实现。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量capacity和负载因子load factor,以调整容器的性能。

    LinkedHashMap: 类似于HashMap,但是迭代遍历它时,取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点。而在迭代访问时发而更快,因为它使用链表维护内部次序。

    TreeMap : 基于红黑树数据结构的实现。查看“键”或“键值对”时,它们会被排序(次序由Comparabel或Comparator决定)。TreeMap的特点在 于,你得到的结果是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。

    WeakHashMao :弱键(weak key)Map,Map中使用的对象也被允许释放: 这是为解决特殊问题设计的。如果没有map之外的引用指向某个“键”,则此“键”可以被垃圾收集器回收。

    IdentifyHashMap: : 使用==代替equals()对“键”作比较的hash map。专为解决特殊问题而设计。

    二 Set List Map的区别

    List:将以特定次序存储元素。所以取出来的顺序可能和放入顺序不同。
           ArrayList / LinkedList / Vector
    
    Set : 不能含有重复的元素
        HashSet / TreeSet
    
    -Map
    HashMap
      HashTable
      TreeMap
    

    List,Set,Map将持有对象一律视为Object型别。
    List、Set、Map都是接口,不能实例化。
    继承自它们的 ArrayList, Vector, HashTable, HashMap是具象class,这些才可被实例化。
    vector容器确切知道它所持有的对象隶属什么型别。vector不进行边界检查。

    什么是set和list:

    List和Set都是接口。他们各自有自己的实现类,有无顺序的实现类,也有有顺序的实现类。
    List特点:元素有放入顺序,元素可重复
    Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该元素的HashCode决定的,其位置其实是固定的)
    最大的不同就是List是可以重复的。而Set是不能重复的。

    set集合和list集合的区别:

    set集合中的数据没有顺序,且如果add两个一样的对象或基本类型的数据,set集合里也是只有一个,即set集合中的数据都是独一无二的;不能使用加强的[for循环
    ;list中的数据是有顺序的,可以加入多个一样的对象和基本类型的数据,可使用加强的[for循环;

    总结:
    1. 如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
    2. 如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
    3. 在除需要排序时使用TreeSet,TreeMap外,都应使用HashSet,HashMap,因为他们 的效率更高。
    4. 要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
    5. 容器类仅能持有对象引用(指向对象的指针),而不是将对象信息copy一份至数列某位置。一旦将对象置入容器内,便损失了该对象的型别信息。
    6. 尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
    注意:

    1、Set和Collection拥有一模一样的接口。
    2、List,可以通过get()方法来一次取出一个元素。使用数字来选择一堆对象中的一个,get(0)...。(add/get)
    3、一般使用ArrayList。用LinkedList构造堆栈stack、队列queue。
    4、Map用 put(k,v) / get(k),还可以使用containsKey()/containsValue()来检查其中是否含有某个key/value
    HashMap会利用对象的hashCode来快速找到key。
    5、Map中元素,可以将key序列、value序列单独抽取出来。
    使用keySet()抽取key序列,将map中的所有keys生成一个Set。
    使用values()抽取value序列,将map中的所有values生成一个Collection。
    6、Collection没有get()方法来取得某个元素。只能通过iterator()遍历元素。
    为什么一个生成Set,一个生成Collection?那是因为,key总是独一无二的,value允许重复。

    三、 Map的KeySet(), values(), entrySet()方法

    KeySet理解:

    keySet()方法返回值是Map中key值的集合
    基于上面, 我们再讲解如下案例就非常容易理解:

       Map map = new HashMap();
       map.put(1, "a");
       map.put(2, "b");
       map.put(3, "c");
       map.put(4, "d");
       Set keys1 = map.keySet();
       Set keys2 = map.keySet();
       Set keys3 = map.keySet();
    

    上面三个set对象key1,key2,key3引用的是一个对象。这是map的keySet()方法只返回一个set实例,所以当从key1中删除一个对象时候,key2和key3将会受到影响。

    keys1.remove(1);
       System.out.println(keys1);
       System.out.println(keys2);
       System.out.println(keys3);
    

    打印结果为:

    [2, 3, 4]
    [2, 3, 4]
    [2, 3, 4]
    
    values()理解:

    values()方法返回值是Map中value值的集合

    entrySet()理解:

    <K,V>> entrySet() //返回此映射中包含的映射关系的视图。
    表示映射关系

    一. keySet()方式。

    Map<String,String> map = new HashMap<String,String>();

        map.put("01", "zhangsan");
        map.put("02", "lisi");
        map.put("03", "wangwu");
                
                
        Set<String> keySet = map.keySet();//先获取map集合的所有键的Set集合
    
        Iterator<String> it = keySet.iterator();//有了Set集合,就可以获取其迭代器。
                
        while(it.hasNext()){
                String key = it.next();
                String value = map.get(key);//有了键可以通过map集合的get方法获取其对应的值。
                        
                System.out.println("key: "+key+"-->value: "+value);//获得key和value值
                }
    

    二. entrySet()方式:
    Map<String,String> map = new HashMap<String,String>();

    map.put("01", "zhangsan");
    map.put("02", "lisi");
    map.put("03", "wangwu");

    //通过entrySet()方法将map集合中的映射关系取出(这个关系就是Map.Entry类型)
    Set<Map.Entry<String, String>> entrySet = map.entrySet();

    //将关系集合entrySet进行迭代,存放到迭代器中
    Iterator<Map.Entry<String, String>> it2 = entrySet.iterator();

    while(it2.hasNext()){
    Map.Entry<String, String> me = it2.next();//获取Map.Entry关系对象me
    String key2 = me.getKey();//通过关系对象获取key
    String value2 = me.getValue();//通过关系对象获取value

        System.out.println("key: "+key2+"-->value: "+value2);
    

    }

    虽然使用keyset及entryset来进行遍历能取得相同的结果
    但两者的遍历速度是有差别的

    keySet():迭代后只能通过get()取key
    entrySet():迭代后可以e.getKey(),e.getValue()取key和value。返回的是Entry接口

    说明:keySet()的速度比entrySet()慢了很多,也就是keySet方式遍历Map的性能不如entrySet性能好
    为了提高性能,以后多考虑用entrySet()方式来进行遍历。

    相关文章

      网友评论

      • 金获大山:☺还是个程序“猿”,听说做这个的逻辑思维很好。

      本文标题:Set List Map的定义和KeySet(), values

      本文链接:https://www.haomeiwen.com/subject/pjaczttx.html