200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > java中的几种泛型类——HashSet HashMap TreeSet TreeMap 遍历map 排序 HashTable比较

java中的几种泛型类——HashSet HashMap TreeSet TreeMap 遍历map 排序 HashTable比较

时间:2020-10-14 18:55:59

相关推荐

java中的几种泛型类——HashSet HashMap TreeSet TreeMap 遍历map 排序 HashTable比较

HashSet

HashSet<E>泛型类在数据组织上类似于数学上的集合,可以进行“交”、“并”、“差”等运算。 HashSet<E>泛型类创建的对象称为集合,如: HashSet<E> set = HashSet<String>(); 那么set就是一个可以存储string类型数据的集合,set可以调用add(String s)方法将string类型的数据添加到集合中。添加到集合中的数据称为集合的元素。集合不允许有相同的元素。也就是说,如果b已经是集合中的元素,那么执行add(b)的操作是无效的。集合对象的初始容量是16字节,装载因子是0.75。也就是说,如果集合添加的元素超过总容量的75%是,集合的容量将增加1倍。 相关运算: 并运算:boolean addAll(HashSet); 交运算:boolean retainAll(HashSet); 差运算:boolean remainAll(HashSet); 参数指定的集合必须与当前集合是同种类型的集合,否则上述方法返回的类型是false。 HashSet<E>泛型类实现了泛型接口Set<E>,而Set<E>接口是Collection<E>接口的子接口。HashSet<E>类中的绝大部分方法都是接口方法的实现。编程时,可以使用接口回调技术,即把HashSet<E>对象的引用赋值给Collection<E>接口变量或Set<E>接口变量,那么接口就可以调用类实现的接口方法。

HashMap

HashMap<K,V>对象成为散列映射对象。散列映射用于存储键-值数据对,允许把任何数量的键-值数据存储在一起。键不可以可重复。如果出现两个数据项的键相同,那么先前散列映射中的键-值对将被替换。散列映射在它需要更多存储容量是会自动增大容量。例如,如果散列映射的装载因子是75%时,它就自动把容量增加到原始容量的2倍。对于数组和链表这两种数据结构,如果要查找它们存储的某个特定的元素却不知道它们的位置,就需要从头开始访问元素知道找到匹配的为止;如果数据结构中包含很多元素,就会浪费时间。这时最好使用散列映射来存储要找的数据,以便检索时可以减少检索的开销。 HashMap<K,V>泛型类创建的对象称为散列映射,如:

HashMap<K,V> hash = HashMap<String,Student>(); 那么,hash就可以存储键-值对数据,其中的键必须是一个String对象,键对应的值必须是Student对象。hash可以调用 public V put(K key, V value)方法将键-值对存储在散列映射中,同时返回键所对应的值。 遍历散列映射的方法有如下四种:

public static void main(String[] args) {Map<String, String> map = new HashMap<String, String>();map.put("1", "value1");map.put("2", "value2");map.put("3", "value3");// 第一种:普遍使用,二次取值System.out.println("通过Map.keySet遍历key和value:");for (String key : map.keySet()) {System.out.println("key= " + key + " and value= " + map.get(key));}// 第二种System.out.println("通过Map.entrySet使用iterator遍历key和value:");Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();while (it.hasNext()) {Map.Entry<String, String> entry = it.next();System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());}// 第三种:推荐,尤其是容量大时System.out.println("通过Map.entrySet遍历key和value");for (Map.Entry<String, String> entry : map.entrySet()) {System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());}// 第四种System.out.println("通过Map.values()遍历所有的value,但不能遍历key");for (String v : map.values()) {System.out.println("value= " + v);}}

HashMap<E>泛型类是实现泛型接口Map<E>。

TreeSet

TreeSet<E>类是实现Set接口的类。

TreeSet<E>泛型类创建的对象称为树集,如:

TreeSet<Student> tree = TreeSet<Student>(); 那么tree就是一个可以存储Student对象的集合,tree可以调用add(Student s)方法将Student对象添加到树集中。树集采用树结构存储数据,树集节点的排列和链表不同,不按添加的先后顺序顺序排列。树集采用add()方法增加节点,节点会按其存放的数据的“大小”顺序一层一层地依次排序,同一层的节点按“大小”顺序递增排列,下一层的比上一层的小。树集是一个有序集合。

TreeMap

TreeMap类实现了Map接口,TreeSet类提供了按排序顺序存储键-值对的有效手段。TreeMap保证它的元素按key升序排列。构造函数有2种: TreeMap<K,V>()按照关键字key的大小顺序来对键-值对进行升序排序,key的顺序是按其字符串表示的字典顺序。 TreeMap<K,V>(Comparator<K> comp)关键字key的大小顺序按照Comparator接口规定的大小顺序对树映射中的键-值对进行排序,即可以升序,也可以降序,取决于里面重写的方法。 下面是一个排序的例子:

package test;import java.util.Collections;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.TreeMap;public class Sort {public static void main(String[] args) {System.out.println("开始:");Person person1 = new Person("马先生", 21);Person person2 = new Person("李先生", 23);Person person3 = new Person("王小姐", 26);Map<Number, Person> map = new HashMap<Number, Person>();map.put(person1.getIdCard(), person1);map.put(person2.getIdCard(), person2);map.put(person3.getIdCard(), person3);System.out.println("由HashMap类实现的Map集合,无序:");for (Iterator<Number> it = map.keySet().iterator(); it.hasNext();) {// 遍例集合Person person = map.get(it.next());System.out.println(person.getIdCard() + " " + person.getName());}System.out.println("由TreeMap类实现的Map集合,键对象升序:");TreeMap<Number, Person> treeMap = new TreeMap<Number, Person>();treeMap.putAll(map);for (Iterator<Number> it = treeMap.keySet().iterator(); it.hasNext();) {// 遍例集合Person person = treeMap.get(it.next());System.out.println(person.getIdCard() + " " + person.getName());}System.out.println("由TreeMap类实现的Map集合,键对象降序:");TreeMap<Number, Person> treeMap2 = new TreeMap<Number, Person>(Collections.reverseOrder());// 初始化为反转排序treeMap2.putAll(map);for (Iterator it = treeMap2.keySet().iterator(); it.hasNext();) {// 遍例集合Person person = (Person) treeMap2.get(it.next());System.out.println(person.getIdCard() + " " + person.getName());}System.out.println("结束!");}}class Person {private String name;private long idCard;public Person(String name, long idCard) {this.name = name;this.idCard = idCard;}public long getIdCard() {return idCard;}public void setIdCard(long idCard) {this.idCard = idCard;}public String getName() {return name;}public void setName(String name) {this.name = name;}}

输出结果为:

开始:由HashMap类实现的Map集合,无序:26 王小姐21 马先生23 李先生由TreeMap类实现的Map集合,键对象升序:21 马先生26 王小姐23 李先生由TreeMap类实现的Map集合,键对象降序:23 李先生26 王小姐21 马先生结束!

TreeMap也可以用一个简单的方法使它按键key降序排列:

TreeMap<Double, double[]> sortMap = new TreeMap<Double, double[]>(<span style="color:#ff0000;">Collections.reverseOrder()</span>);// 初始化为翻转排序

所以,如果map需要按键排序,把键-值对放在TreeMap即可。

map中按值排序则需要重写Comparator方法,如下的例子:

List<Map.Entry<Integer, Double>> entrySet = newArrayList<Map.Entry<Integer, Double>>(map.entrySet());System.out.println("排序前的特征值: " + entrySet);Collections.sort(entrySet,new <span style="color:#ff0000;">Comparator</span><Map.Entry<Integer, Double>>() {public int compare(Entry<Integer, Double> o1,Entry<Integer, Double> o2) {return o2.getValue().compareTo(o1.getValue());//<span style="color:#ff0000;">此处对象o1和对象o2的先后顺序可决定是按升序还是按降序排序</span>}});

Map常用操作

1) 添加操作:

V put(K key, V value):如果key已存在,在关联后,返回替换前该key对应的value值,如果不存在,则返回null;

void putAll(Map t):将来自特定映像的所有元素添加给该映射。

2) 删除操作:

V remove(Object key):从此映射中移除指定键的映射关系(如果存在),不存在则返回null;

void clear() :从此映射中移除所有映射关系.

3) 查询操作:

V get(key): 获得与关键字key相关的值,并且返回与关键字key相关的对象,如果没有该关键字,则返回null;判断key是否存在,可以通过返回值是否等于null

boolean containsKey(key): 判断映像中是否存在关键字key;

boolean containsValue(Object value): 判断映像中是否存在值value;

int size(): 返回当前映像中映射的数量;

boolean isEmpty(): 判断映像中是否有任何映射.

Collection values():返回映像中所有value值的集,由于值多个,用Collection集合,对其操作可以使用Collection基本方法.

HashMap和HashTable的区别:

1) HashTable:底层是哈希表数据结构;hash值直接使用对象的hashCode;不可以存入null键和null值;hash数组默认大小是11,增加的方式是old*2+1;线程同步,在多线程并发的环境下,可以直接使用Hashtable;JDK1.0效率低; 2) HashMap:继承自Dictionary类,底层是哈希表数据结构;重新计算hash值;可以存入null键和null值;hash数组的默认大小是16,而且一定是2的指数;线程不同步,在多线程并发的环境下,要自己增加同步处理;JDK1.2效率高。 一般情况下,HashMap能够比Hashtable工作的更好、更快,主要得益于它的散列算法,以及没有同步。应用程序一般在更高的层面上实 现了保护机制,而不是依赖于这些底层数据结构的同步,因此,HashMap能够在大多应用中满足需要。推荐使用HashMap,如果需要同步,可以使用同步工具类将其转换成支持同步的HashMap。

LinkedHashMap保存了记录的插入顺序,在用Iterator遍历LinkedHashMap时,先得到的记录肯定是先插入的.也可以在构造时用带参数,按照应用次数排序。在遍历的时候会比HashMap慢,不过有种情况例外,当HashMap容量很大,实际数据较少时,遍历起来可能会比LinkedHashMap慢,因为LinkedHashMap的遍历速度只和实际数据有关,和容量无关,而HashMap的遍历速度和他的容量有关。

有并发访问的时候用ConcurrentHashMap,效率比用锁的HashMap好 功能上可以,但是毕竟ConcurrentHashMap这种数据结构要复杂些,如果能保证只在单一线程下读写,不会发生并发的读写,那么就可以试用HashMap。ConcurrentHashMap读不加锁

—————————————————————————————————————————————————————— 写博经验尚浅,请各位多多指教。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。