---------------------- 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培训、期待与您交流! ----------------------