黑马程序员_学习日记七_集合二

---------------------- android培训java培训、期待与您交流! ----------------------

 

TreeSet概述

    TreeSet集合的特点是可以对集合中的元素进行默认排序。

    当需要用TreeSet集合存储自定义对象时,该集合是要对所存进来的对象进行排序的,如果对象不具备比较性,是无法进行排序的,此时,虚拟机就会报ClassCastException的异常。所以,首先必须要让对象具备比较性。

    那么,如何让让对象具有比较行呢?必须让所生成对象的类实现一个叫Comparable的接口,覆盖这个类中的int compareTo(Object obj)方法,强制让实现这个接口的类具备比较性。而TreeSet这个集合在底层会自动调用compareTo()这个方法来对对象进行比较。

    排序时,当主要条件相同时,一定要再判断次要条件。

TreeSet二叉树

    TreeSet这个集合底层的数据结构是二叉树。保证元素唯一性的依据是compareTo()方法返回0。

    TreeSet集合排序的第一种方式:让对象自身具备比较性,所生成对象的类必须实现Comparable接口,并且覆盖compareTo()方法。这种方式也称为元素的自然顺序,或者叫做默认顺序。

TreeSet实现Comparator方式排序

    TreeSet除了可以实现Comparable这个接口给集合中的元素排序之外,还有一种排序方式:当元素自身不具备比较性时或者具备的比较性不是所需要的,这时,就需要让集合自身具备比较性。

    那么,怎么才能让集合有比较性呢?就是在集合初始化时,强制给它定义一个比较方式。TreeSet有一个重载的构造方法TreeSet(Comparator<?> comparator),这个构造方法需要一个Comparator接口类对象作为参数。而这个接口就有一个intcompare(Object obj1, Object obj2)方法。

    步骤一:首先定义一个类实现Comparator这个接口;

    步骤二:然后在该类中按照需要比较的内容或者需求覆盖Comparator这个接口中的compare()方法。

    步骤三:接着将这个类的实例对象作为参数传递给TreeSet的构造方法TreeSet (Comparator<?> comparator)。

    总之,在TreeSet这个集合当中,有两种方式可以让其里面的对象排序。

    第一种方式是让对象具备比较方式,此时,生成对象的类需要实现Comparable接口,并覆盖该接口的int compareTo(Object obj)方法,强制让这个类生成的对象具备比较方式。

    第二种方式是让这个集合对象具备比较方式,此时,需要另外定义一个类,让该类实现Comparator这个接口,并覆盖该接口的compare()方法,然后再将这个类的实例对象作为参数传递给TreeSet的构造方法TreeSet (Comparator<?> comparator)。

泛型概述

    当集合中的对象并不是同一类型的对象时,或者在集合当中添加了不同的对象类型时,编译时是虚拟机是不会报错的,只有运行才会报错,导致程序中断。为了能够在编译时期就能够将问题解决,在JDK1.5版本以后出现了泛型的新特性,这是一个安全机制,用于解决安全问题。

    那么,泛型是如何体现的呢?在集合定义的时候就给集合指定默认的对象类型,比如:

        ArrayList<String> arrayList = newArrayList<String>();

    此时,在arrayList这个集合中只能添加类型为String的对象。

    这种机制的出现的好处有:

    1.将运行时期出现的问题转移到编译时期,方便程序员尽早发现并解决问题,让运行时期问题减少。   

    2.避免了强制转换的麻烦。

    泛型格式:通过符号<>来指定要操作的对象类型。那么在什么情况下需要是用泛型呢?

    泛型通常在集合框架中很常见,只要在程序中出现符号<>,就要定义泛型。其实,<>这个符号就是用来接收对象类型的。当使用集合时,将集合中要存储的对象类型传递到<>符号中即可,如同方法参数传递。

    特殊之处,静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上。

    泛型除了可以定义在类上,方法上,还可以定义在接口上。比如:

    interface inter<T> {}

泛型限定

    符号:?,叫做通配符或者占位符。

    泛型限定第一 种情况:? extends E,可以接收E类型或者E的子类类型对象。叫做上限限定。

    泛型限定第二种情况:? super E,可以接受E类型或者E的父类类型的对象。叫做下限定。

Map概述

    Map<K, V>这个集合接口存储键值对,一对一对往里存,将键映射到值对象,一个映射不能包含重复的键,即要保证键的唯一性,每个键最多只能映射到一个值。

    Map集合中有以下共性方法:

    1.void clear(),移除集合中所有的映射关系。

    2.boolean containsKey(Object key),如果此映射关系包含指定键的映射关系,则返回true。

    3.boolean containsValue(Object value),如果此映射将一个或多个键映射到指定值,则返回true。

    4.value get(Object key),返回指定键所映射的值,如果此映射不包含该键的映射关系,则返回null。

    5.boolean isEmpty(),判断此映射是否包含键值映射关系,如果不包含,则返回true。

    6.value put(K key, V value),向集合中添加映射关系,将指定的value与指定的key关联。如果添加映射时,出现了相同的key,那么后添加的value会覆盖原有key映射的value,而且该方法会返回被覆盖的value。

    7.void putAll(Map<? Extends K, ? extends V> m),从指定集合中将所有的映射关系添加到此集合中。

    8.Value remove(Object key),将指定键的映射关系从此集合中移除。

    9.int size(),返回此集合中键值对映射总数。

    10.Collection values(),返回此集合中包含值的Collection。

    除此之外,还有两个比较重要的方法:

    1.Set<Map.Entry<K,V>> entrySet()。

    2.Set<K> keySet()。

Map子类对象特点

    Map这个集合有三个子类,分别是HashTable、HashMap、TreeMap。

    1.HashTable的底层数据结构是哈希表,这个集合类实现一个哈希表,该哈希表将键映射到相应的值,任何非null对象都可以用作键或值,既key和value不可以为null。为了能够在哈希表中存储和获取对象,用作键的对象必须实现hashCode()和equals()方法。该集合还是线程同步的。

    2.HashMap的底层数据结构也是哈希表,HashMap和HashTable的主要区别在于允许存在key和value为null,并且HashMap还是线程非同步的。除了这两个区别之外,其他大致相同。

    HashMap和HashTable相比效率要更高。

    3.TreeMap的底层数据结构是二叉树。可以用于给集合中的key进行排序,是线程不同步的。

    Map集合和Set集合很类似,因为Set集合的底层就是使用了Map集合。

Map集合-keySet()

    Map集合的取出方法一:Set<key> keySet()

    该方法将Map集合中所有的键存入到了Set集合中,因为Set集合可以利用迭代器实现key的读取,所以可以通过迭代方式取出所有的key,然后再使用get方法获取每个key对应的value。

    步骤一:先获取Map集合中的所有key的Set集合。

    步骤二:有了Set集合,就可以获取其迭代器。

    步骤三:根据迭代器,再获取Set集合中的元素key

    步骤四:有了key值之后,就可以调用get()方法获取key对应的value。

示例代码如下:

        Set<String> keySet = map.keySet();

        Iterator<String> it = keySet.iterator();

        while(it.hasNext())

        {

            String key = it.next();

            String value = map.get(key);

            System.out.println(value);

        }

    这种方法的原理是先将Map集合中的key存放到一个Set集合中,再通过迭代器的取出方式取出。

Map集合-entrySet()

    Map集合的取出方法二:Set<Map.Entry<K, V>> entrySet()

    该方法将Map集合中的映射关系存入到了Set集合中,而这个关系的数据类型就是Map.Entry<K, V>类型。Map.Entry<K,V>是一个接口,功能相当于List集合中的迭代器Iterator。

    步骤一:将Map集合中的映射关系取出,泛型为<Map.Entry<String,String>>,存入到Set集合中。

    步骤二:获取Set集合的迭代器对象it,在利用迭代器对象it获取集合关系Map.Entry型对象me。

    步骤三:关系Map.Entry型对象me获取到之后,在调用Map.Entry这个接口中的getKey和getValue方法获取key和value。

    代码示例如下:

    Set<Map.Entry<String, String>> entrySet =map.entrySet();

    Iterator<Map.Entry<String, String>> it =entrySet.iterator();

    While(it.hasNext())

    {

        Map.Entry<String, String> me = it.next();

        String key = me.getKey();

        String value = me.getValue();

        System.out.println(“Key:” + key + “Value” + value);

    }

    那么Map.Entry究竟是什么东西呢?其实Entry也是一个接口,而且它还是Map接口中的一个内部接口,而Entry这个接口中就有getKey()和getValue()两个抽象方法,代码如下:

    interface Map

    {

        public static Object Entry

        {

            public abstract Object getKey();

            public abstract Object getValue();

 

        }

    }

 

---------------------- android培训java培训、期待与您交流! ----------------------

详细请查看:http://edu.csdn.net/heima 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值