Map接口及Map的实现类

1.Map接口的定义

2. Map接口的方法及使用

3.Map接口的实现类(HashMap、HashTable、TreeMap)的定义和使用

4.HashMap和Hashtable的区别

5.HashMap和HashTreeMap的区别

6.Map.entry接口

7.Collections类(用来操作集合的工具类)

 

1.   Map接口的定义:

Map是一个映射接口,其中的每个元素都是一个key-value键值对,TreeMap、HashMap、HashTable、WeakHashMap等实现类都通过继承AbstractMap来实现,另外,不常用的HashTable直接实现了Map接口,它和Vector都是JDK1.0就引入的集合类。

2.Map接口的常用方法:

3. No.    方法或类                    类型    描述
1    public void clear()      
         普通    清空Map集合
2    public boolean containsKey(Object key)  
     普通    判断指定的key是否存在
3    public boolean containsValue(Object value)  
 普通    判断指定的value是否存在
4    public Set<Map.Entry<K,V>>
entrySet()        普通    将Map对象变为Set集合
5    public boolean equals(Object o)  
         普通    对象比较
6    public V get(Object K)      
         普通    根据key获得value
7    public int hashCode()      
         普通    返回哈希码
8    public boolean isEmpty()      
     普通    判断集合是否为空
9    public Set<K> keySet()      
         普通    取得所有的key
10    public V put(K key,V value)      
     普通    向集合中加入元素
11    public void putAll(Map<? extends K,extends V> t)普通  
 将一个Map集合中的内容加入到别一个Map
12    public V remove(Object key)      
     普通    根据key删除value
13    public int size()      
         普通    取得集合长度
14    public Collection<V> values()  
         普通    取得全部的value Map.Entry是Map声明的一个内部接口,此接口为泛型,定义为Entry<K,V>。它表示Map中的一个实体(一个key-value对)。

二、Map接口的实现类

  1.HashMap

  定义:HashMap是最常用的Map类,根据键的Hash值计算存储位置,存储键值对,可以根据键获取对应值。具有很快的访问速度,但是是无序的、线程不安全的。且HashMap是线程不同步的

2、HashTable

定义:HashTable继承自Dictionary类 ,和HashMap差不多,它也是无序的,但是Hashtable是线程安全的,同步的,即任一时刻只有一个线程能写Hashtable

3. LinkedHashMap

定义:LinkedHashMap是Map中常用的有序的两种实现之一, 它保存了记录的插入顺序,先进先出。
对于LinkedHashMap而言,它继承与HashMap,底层使用哈希表与双向链表来保存所有元素。其基本操作与父类HashMap相似,它通过重写父类相关的方法,来实现自己的链接列表特性。LinkedHashMap采用的hash算法和HashMap相同,但是它重新定义了数组中保存的元素Entry,该Entry除了保存当前对象的引用外,还保存了其上一个元素before和下一个元素after的引用,从而在哈希表的基础上又构成了双向链接列表

4. TreeMap

定义:TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用Iterator 遍历TreeMap时,得到的记录是排过序的。
TreeMap的排序原理是:红黑树算法的实现 。
它的主要实现是Comparator架构,通过比较的方式,进行一个排序,

 

 

三、HashMap和HashTable的区别

     1. 存储结构

 

HashMap

HashTable

数组 + 链表/红黑树

数组 + 链表

HashMap的存储规则:

优先使用数组存储, 如果出现Hash冲突, 将在数组的该位置拉伸出链表进行存储(在链表的尾部进行添加), 如果链表的长度大于设定值后, 将链表转为红黑树.

 

HashTable的存储规则:

优先使用数组存储, 存储元素时, 先取出下标上的元素(可能为null), 然后添加到数组元素Entry对象的next属性中(在链表的头部进行添加).

出现Hash冲突时, 新元素next属性会指向冲突的元素. 如果没有Hash冲突, 则新元素的next属性就是null

2. 关于null

HashMap

HashTable

key, value 均可以为 null

key, value 均可以为 null

4.线程安全

HashMap

HashTable

线程不安全

线程安全

HashMap虽然是线程不安全的, 但还是推荐使用, 因为 HashTable实现线程安全的方式太低效了, 直接在方法上加了 synchronized 关键字来实现的.

 

 

四、HashMap和TreeMap的区别

 

HashMap

TreeMap

HashMap是基于Hash表的结构,根据键的hashCode存储数据

TreeMap是基于红黑二叉树的结构

无序存放的

TreeMap实现SortMap接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器

.HashMap允许有空键和空值

TreeMap不允许有空键和空值

五、Map.Entry

定义:Map.Entry是Map内部定义的一个接口,此接口是泛型,定义为Entry<K,V>,他表示Map集合中的一个实体(即一个Key-value对),专门用来保存Key-value的内容。

 

常用方法:

Public
Boolean equals(Object o)

对象的比较

Public
K getKey()

取得Key

Public
V getValue()

取得value

Public
int hashCode

返回哈希码

Public
V setValue(V value)

设置value的值

 

五、Conllections类

Collections是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。此类不能实例化。Collections中有一些工具函数,比如说sort、reverse、fill等等。

Conllections里的方法:

排序操作

  1)static void
reverse(List<?> list):

    反转列表中元素的顺序。(注意反转不是倒序,要进行倒序就先排序再反转)

  2)static void shuffle(List<?> list) :

    对List集合元素进行随机排序。

  3) static void sort(List<T> list)

    根据元素的自然顺序 对指定列表按升序进行排序
  4)static <T> void sort(List<T> list, Comparator<?
super T> c) :

    根据指定比较器产生的顺序对指定列表进行排序。
  5)static void swap(List<?> list, int i, int j)

    在指定List的指定位置i,j处交换元素。

  6)static void rotate(List<?> list, int distance)

    当distance为正数时,将List集合的后distance个元素“整体”移到前面;当distance为负数时,将list集合的前distance个元素“整体”移到后边。该方法不会改变集合的长度。

查找、替换操作

  1) static <T> int
binarySearch(List<? extends Comparable<? super T>> list, T key)

    使用二分搜索法搜索指定列表,以获得指定对象在List集合中的索引。

    注意:此前必须保证List集合中的元素已经处于有序状态。

  2)static Object max(Collection coll)

     根据元素的自然顺序,返回给定collection 的最大元素。

  3)static Object max(Collection coll,Comparator comp):

    根据指定比较器产生的顺序,返回给定
collection 的最大元素。 

  4)static Object min(Collection coll):

    根据元素的自然顺序,返回给定collection
的最小元素。

  5)static Object min(Collection coll,Comparator comp):

    根据指定比较器产生的顺序,返回给定
collection 的最小元素。

  6) static <T> void fill(List<? super T> list, T
obj) :

    使用指定元素替换指定列表中的所有元素。
  7)static int frequency(Collection<?> c, Object o)

    返回指定 collection 中等于指定对象的出现次数。
  8)static int indexOfSubList(List<?> source, List<?>
target) :

    返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。 
  9)static int lastIndexOfSubList(List<?> source, List<?>
target)

    返回指定源列表中最后一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回 -1。
  10)static <T> boolean
replaceAll(List<T> list, T oldVal, T newVal)

    使用一个新值替换List对象的所有旧值oldVal

 

 案例总结

package com.nf.map;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class HashMapAndHashtable {
  //null值区别
  private static void test() {
   Map<String, String> map = new HashMap<String, String>();
   //没有添加null值之前
   System.out.println(“没有添加null值map的长度:”+map.size());
   //添加null值
   map.put(null, null);
   System.out.println(“添加null值map的长度:”+map.size());
  }
  private static void test2() {
   Map<String, String> map = new Hashtable<String, String>();
   //没有添加null值之前
   System.out.println(“没有添加null值map的长度:”+map.size());
   //添加null值,会报空指针异常
   map.put(null, null);
   System.out.println(“添加null值map的长度:”+map.size());
   
  }
  public static void main(String[] args) {
   test2();
  }}

2、

package com.nf.map;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class HashMapAndHashtable {
  //null值区别
  private static void test() {
   Map<String, String> map = new HashMap<String, String>();
   //没有添加null值之前
   System.out.println(“没有添加null值map的长度:”+map.size());
   //添加null值
   map.put(null, null);
   System.out.println(“添加null值map的长度:”+map.size());
  }
  private static void test2() {
   Map<String, String> map = new Hashtable<String, String>();
   //没有添加null值之前
   System.out.println(“没有添加null值map的长度:”+map.size());
   //添加null值,会报空指针异常
   map.put(null, null);
   System.out.println(“添加null值map的长度:”+map.size());
   
  }
  public static void main(String[] args) {
   test2();
  }
}

3、

package com.nf.map;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import com.nf.entity.Student;
public class TestTreeMap {
 /**
  * key为非系统类的对象的时候,让key对应的类实现Comparable接口并
  * 重写comparable中的比较方法来规定排序的规则
  */
 private static void test1() {
  TreeMap<Student, String> treemap = new TreeMap<Student,String>();
  Student stu1  =  new Student(“张三”,”123″, 88.8);
  Student stu2  = new Student(“李四”, “345”, 77);
  Student stu3 = new Student(“王五”, “324”, 97);
  treemap.put(stu1, stu1.getSname());
  treemap.put(stu2, stu2.getSname());
  treemap.put(stu3, stu3.getSname());
  for (Student ele : treemap.keySet()) {
   System.out.println(“姓名:”+treemap.get(ele)+”;成绩:”+ele.getScore());
  }
 }
 /**
  *为TreeMap构建一个比较器,来排序
  */
 private static void test2() {
  TreeMap<Student,String> treemap = new TreeMap<>(new StudentImp());
  Student stu1  =  new Student(“张三”,”123″, 88.8);
  Student stu2  = new Student(“李四”, “345”, 77);
  Student stu3 = new Student(“王五”, “324”, 97);
  treemap.put(stu1, stu1.getSname());
  treemap.put(stu2, stu2.getSname());
  treemap.put(stu3, stu3.getSname());
  for (Student ele : treemap.keySet()) {
   System.out.println(“姓名:”+treemap.get(ele)+”;成绩:”+ele.getScore());
  }
 }
 private static void test3() {
  Map<String,Integer> treeMap = new TreeMap<String, Integer>();
  treeMap.put(“1”, 888);
  treeMap.put(“9”, 55);
  treeMap.put(“31”, 777);
  treeMap.put(“239”, 88);
  treeMap.put(“177”, 999);
  System.out.println(“使用默认排序规则,生成的结果为:” + treeMap);
  Map<String, Integer> treeMap2 = new TreeMap<String,Integer>(new Comparator<String>() {
   public int compare(String o1, String o2) {
     //修改比较规则,按照数字大小升序排列
     return Integer.parseInt(o1) – Integer.parseInt(o2);
    }
   });
    treeMap2.put(“1”, 888);
    treeMap2.put(“9”, 55);
    treeMap2.put(“31”, 777);
    treeMap2.put(“239”, 88);
    treeMap2.put(“177”, 999);
    System.out.println(“使用自定义排序规则,生成的结果为:” + treeMap2);
  //由此可见,当key值中存储了Integer类型的数字时,将默认无法根据数字大小来进行排序,只有规定比较规则才能排序
 }
 public static void main(String[] args) {
//  test1();
//  test2();
  test3();
 }
}

3、实体类

package com.nf.entity;
public class Student implements Comparable<Student>{
  private String sname;//姓名
  private String sclass;//班级
  private double score;//成绩
  public Student(String sname, String sclass, double score) {
   super();
   this.sname = sname;
   this.sclass = sclass;
   this.score = score;
  }
  public String getSname() {
   return sname;
  }
  public void setSname(String sname) {
   this.sname = sname;
  }
  public String getSclass() {
   return sclass;
  }
  public void setSclass(String sclass) {
   this.sclass = sclass;
  }
  public double getScore() {
   return score;
  }
  public void setScore(double score) {
   this.score = score;
  }
  @Override
  public int compareTo(Student stu) {
   return (int)((stu.getScore()-this.getScore())*10);
  }
  
}
 
package com.nf.map;
import java.util.Comparator;
import com.nf.entity.Student;
public class StudentImp implements Comparator<Student>{
 @Override
 public int compare(Student o1, Student o2) {
  return (int)((o1.getScore()-o2.getScore())*10);
 }
}

测试类

package com.nf.conllections;
import java.util.*;
public class TestEmpty {
  /**
   * 返回空的List,Set,Map集合,
   * 但返回的对象是无法添加数据的.
   */
  private static void testEmpty() {
   List<String> allList = Collections.emptyList();
   Set<String> allSet = Collections.emptySet();
   Map<String,String> allMap =Collections.emptyMap();
   allList.add(“Hello”);
   allSet.add(“SB”);
   allMap.put(“name”, “张三”);
  }
  private static void testAddall() {
   // TODO Auto-generated method stub
   List<String> all = new ArrayList<String>();
   System.out.println(“——没添加内容前——–“);
   System.out.println(“长度:”+all.size());
   //使用addAll方法为指定集合添加内容,第一个参数为要添加内容的集合号,后面的参数为要添加的内容。
   Collections.addAll(all,”aaa”,”bbb”);
   System.out.println(“——添加内容后——–“);
   for (String str : all) {
    System.out.println(str);
   }
  }
  /**
  *  public static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key)
  * 二分法搜索
  */
  private static void testBinarySearch() {
     List<Integer> list1 = new ArrayList<Integer>();
          list1.add(2);
          list1.add(3);
          list1.add(1);
          list1.add(4);
          Collections.sort(list1);
          int index1=Collections.binarySearch(list1, 2);
          int index2=Collections.binarySearch(list1, 1);
          System.out.println(index1);
          System.out.println(index2);
          System.out.println(“——–搜索不存在的——-“);
          int index5=Collections.binarySearch(list1, 5);
          System.out.println(index5);
  }
  private static void testReplaceAll() {
   List<String> all = new ArrayList<String>();
   all.add(“AAA”);
   all.add(“BBB”);
   all.add(“CCC”);
   System.out.println(“———-替换之前———–“);
   for (String ele : all) {
    System.out.println(ele);
   }
   Collections.replaceAll(all, “BBB”, “bbb”);//将原来的BBB替换成bbb。
   System.out.println(“———-替换之后———–“);
   for (String ele : all) {
    System.out.println(ele);
   }
   
  }
  /**
   * 使用swap()方法将集合中两个位置的内容进行交换
   */
  private static void testSwap() {
   List<String> all = new ArrayList<String>();
   all.add(“AAA”);
   all.add(“BBB”);
   all.add(“CCC”);
   System.out.println(“———-交换之前———–“);
   for (String ele : all) {
    System.out.println(ele);
   }
   Collections.swap(all, 0, 2);//将all集合的0位置的AAA和2位置的CCC进行交换
   System.out.println(“———-交换之后———–“);
   for (String ele : all) {
    System.out.println(ele);
   }
  }
  public static void main(String[] args) {
   testSwap();
  }
}
 
 
package com.nf.conllections;
import java.util.*;
public class TestSort {
  public static void test1() {
   List<String> listS = new ArrayList<String>();
    //一.将String类型的变量插入到listS中并排序
    //listS中的对象String 本身含有compareTo方法,所以可以直接调用sort方法,按自然顺序排序,即升序排序
   listS.add(“5”);
   listS.add(“2”);
   listS.add(“9”);
   System.out.println(“——-排序前——-“);
   for (String ele : listS) {
    System.out.println(ele);
   }
   Collections.sort(listS);
   System.out.println(“——-排序后——-“);
   for (String ele : listS) {
    System.out.println(ele);
   }
  }
  /**
   * 倒序
   */
  private static void test2() {
   List<String> list = new ArrayList<String>();
   list.add(“1”);
   list.add(“3”);
   list.add(“2”);
   System.out.println(“——-没任何操作前——-“);
   for (String ele : list) {
    System.out.println(ele);
   }
   Collections.reverse(list);
   System.out.println(“——-反转后——-“);
   for (String ele : list) {
    System.out.println(ele);
   }
   Collections.sort(list);
   Collections.reverse(list);
   System.out.println(“——-排序后再反转——-“);
   for (String ele : list) {
    System.out.println(ele);
   }
  }
  public static void main(String[] args) {
   test2();
  }
}
 
 

 

版权声明:本文为nisiweiLIQIYONG原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/nisiweiLIQIYONG/p/9613310.html