map 集合的特征以及遍历方式,以及TreeMap介绍

目录

TreeMap

Map接口的遍历方式


我们知道, map 接口是双列 , 底下三个实现类 hashMap, TreeMap , HashTable

hashMap 可参考:hashMap底层实现解析(负载因子0.75,初始容量16,键不重复)_xx12321q的博客-CSDN博客

       hashTable 底层同 hashMap相同, 但是它在大部分方法上加了synchronized锁,是线程安全的(但是键不能存放null值)

最后就是TreeMap(键采用红黑树存储)

TreeMap

      TreeMap 中所有的元素都保持着某种固定的顺序,如果需要得到一个有序的 Map 就应该使用TreeMap key 值所在类必须实现 Comparable 接口。例:
TreeMap<String,String> treeMap = new TreeMap<>();
treeMap.put("b","2");
treeMap.put("c","3");
treeMap.put("d","4");
treeMap.put("a","10");
System.out.println(treeMap);

结果 : 

       我们可以看到, TreeMap根据键的顺序来为我们已经排好了序 , 我们这里的键是String, 而String已经实现了Comparable接口, 并重写了compareTo()方法,所以这里按照字母顺序排列

       但是如果我们使用了自己定义的类, 并没有实现Comparable接口 ,这样是不能put的

public class User {      //自定义一个User类

    private Integer id;
    private String account;
    private String sex;

    public User(){}

    public User(Integer id, String account, String sex) {
        this.id = id;
        this.account = account;
        this.sex = sex;
    }
}
TreeMap<User,String> treeMap = new TreeMap<>();
User user = new User();
treeMap.put(user,"abc");

结果

 可以看到,直接会报出 ClassCastException(类加载异常)

        所以我们使用TreeMap的时候,键必须要实现Comparable接口重写compareTo()方法来传入我们自己定义的排序规则, 例 :

// 实现Comparable接口,传入类型
public class User implements Comparable<User>{

    private Integer id;
    private String account;
    private String sex;

    public User() {
    }

    public User(Integer id, String account, String sex) {
        this.id = id;
        this.account = account;
        this.sex = sex;
    }

    @Override
    public int compareTo(User user) {   //可以自定义排序规则
        return 0;
    }
}

介绍完特征,我们来看 put() 方法的部分源码,这里就不完全展示了

 可以看到 , 这就是TreeMap的有序性

需要注意的是, TreeMap并不能存储 null 的键,而hashMap可以

Map接口的遍历方式

先建立一个Map , 以hashMap为例

Map<String,String> map = new HashMap<>();
map.put("a","1");
map.put("f","12");
map.put("q","123");
map.put("w","1234");
map.put("b","12345");

  方式一 :  先将所有key(键) 存到一个set 集合中(使用keySet()方法),然后遍历set集合 ,通过key拿到value ,例 :

Set<String> set = map.keySet();      //拿到所有的键
Iterator<String> iterator = set.iterator();   //拿到set的迭代器
while (iterator.hasNext()){           //循环遍历 
      System.out.println(map.get(iterator.next()));  //通过get()拿值
}

结果 : 

 

方式二 : 通过entrySet() 方法,直接拿到底层存储键值对的对象, 返回到set 集合中,然后遍历set集合

通过Entry类里的方法遍历,例:

Set<Map.Entry<String, String>> entrySet = map.entrySet();  //拿到底层entry
for (Map.Entry<String, String> entry : entrySet) {
    System.out.println("key:"+entry.getKey()+"::  value:"+entry.getValue());
}

结果 : 

方式三 : 流遍历

map.forEach(new BiConsumer<String, String>() {
     @Override
     public void accept(String s, String s2) {
          System.out.println(s+"::"+s2);
     }
});

结果: 

 以上就是map 遍历的三种方式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java Map 遍历方法 Map map = new HashMap(); Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object key = entry.getKey(); Object value = entry.getValue(); } Map map = new HashMap(); Iterator it = map.entrySet().iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); Object key = entry.getKey(); Object value = entry.getValue(); } JDK1.5中,应用新特性For-Each循环 Java代码 Map m = new HashMap(); for(Object o : map.keySet()){ map.get(o); } Map m = new HashMap(); for(Object o : map.keySet()){ map.get(o); } 返回的 set 中的每个元素都是一个 Map.Entry 类型。 private Hashtable<String, String> emails = new Hashtable<String, String>(); 另外 我们可以先把hashMap 转为集合Collection,再迭代输出,不过得到的对象 //方法一: 用entrySet() Java代码 Iterator it = emails.entrySet().iterator(); while(it.hasNext()){ Map.Entry m=(Map.Entry)it.next(); logger.info("email-" + m.getKey() + ":" + m.getValue()); } Iterator it = emails.entrySet().iterator(); while(it.hasNext()){ Map.Entry m=(Map.Entry)it.next(); logger.info("email-" + m.getKey() + ":" + m.getValue()); } // 方法二:jdk1.5支持,用entrySet()和For-Each循环() Java代码 for (Map.Entry<String, String> m : emails.entrySet()) { logger.info("email-" + m.getKey() + ":" + m.getValue()); } for (Map.Entry<String, String> m : emails.entrySet()) { logger.info("email-" + m.getKey() + ":" + m.getValue()); } // 方法三:用keySet() Java代码 Iterator it = emails.keySet().iterator(); while (it.hasNext()){ String key; key=(String)it.next(); logger.info("email-" + key + ":" + emails.get(key)); } Iterator it = emails.keySet().iterator(); while (it.hasNext()){ String key; key=(String)it.next(); logger.info("email-" + key + ":" + emails.get(key)); } // 方法五:jdk1.5支持,用keySEt()和For-Each循环 Java代码 for(Object m: emails.keySet()){ logger.info("email-" + m+ ":" + emails.get(m)); } Map aa = new HashMap(); aa.put("tmp1", new Object()); //追加 替换用同样的函数. aa.remove("temp1"); //删除 for (Iterator i = aa.values().iterator(); i.hasNext(); ) { Object temp = i.next(); } //遍历 for(Object m: emails.keySet()){ logger.info("email-" + m+ ":" + emails.get(m)); } Map aa = new HashMap(); aa.put("tmp1", new Object()); //追加 替换用同样的函数. aa.remove("temp1"); //删除 for (Iterator i = aa.values().iterator(); i.hasNext(); ) { Object temp = i.next(); } //遍历 来个完整的,包含TreeSet的元素内部排序的 Java代码 public static void main(String[] args) { ArrayList<String> list = new ArrayList<String>(); HashMap<Object,Object> hash = new HashMap<Object,Object>(); TreeMap<Object,Object> treeMap = new TreeMap<Object,Object>(); list.add("a"); list.add("b"); list.add("c"); hash.put(3, 3); hash.put(4, 4); hash.put(5, 5); hash.put(6, 6); hash.put(1, 1); hash.put(2, 2); treeMap.put(1, 1); treeMap.put(2, 2); treeMap.put(3, 3); treeMap.put(4, 4); treeMap.put(5, 5); treeMap.put(6, 6); //list遍历 for(String m: list){ System.out.println(m); } // hashmap entrySet() 遍历 for(Map.Entry<Object,Object> m: hash.entrySet()){ System.out.println(m.getKey()+"---"+m.getValue()); } //hashmap keySet() 遍历 for(Object m: hash.keySet()){ System.out.println(m+"---"+hash.get(m)); } // treemap keySet()遍历 for(Object m: treeMap.keySet()){ System.out.println(m+"---"+treeMap.get(m)); } }
掌握集合的概念、体系结构、分类及使用场景 2)了解Set接口及主要实现类(HashSet、TreeSet) 3)了解List接口及主要实现类(ArrayList、LinkedList、Vector) 4)了解Map接口及主要实现类(HashMapTreeMap、HashTable) 二、实验内容及步骤 1、编写程序练习将以下5个Person类的对象放在一个HashSet中。 姓名:张三 身份证号:178880001 姓名:王五 身份证号:178880002 姓名:李四 身份证号:178880003 姓名:王五 身份证号:178880002 姓名:李四 身份证号:178880004 注意:因为Person类是自定义类,需要重写hashCode()方法和equals()方法,并规定只有姓名和身份证号都相等,则对象相等。 其中计算哈希码的算法:(31 + ((name == null) ? 0 : name.hashCode()))*31 + id (注:name:Person对象的姓名,id:Person对象的身份证号) 主方法中作如下测试: 1)创建一个可放置Person类对象的HashSet; 2)依次添加上述5个对象到HashSet中; 3)把集合中的元素打印出来(使用迭代器Iterator) 2、编写程序练习List集合的基本使用: 1) 创建一个只能容纳String对象名为names的ArrayList集合; 2)按顺序往集合中添加5个字符串对象:"张三"、"李四"、"王五"、"马六"、"赵七"; 3)对集合进行遍历,分别打印集合中的每个元素的位置与内容; 4)打印集合的大小,然后删除集合中的第3个元素,并显示删除元素的内容,然后再打印目前集合中第3个元素的内容,并再次打印集合的大小。 3、编写程序练习Map集合的基本使用: 1)创建一个只能容纳String对象的person的HashMap集合; 2)往集合中添加5个"键-值"对象: "id"-"1"; "name"-"张三"; "sex"-"男"; "age"-"25"; "hobby"-"爱学Java" 3)对集合进行遍历,分别打印集合中的每个元素的键与值; 4)打印集合的大小,然后删除集合中的键为age的元素,并显示删除元素的内容,并再次打印集合的大小。 四、思考题 1、集合中的List、Set、Map有哪些不同? 2、为什么使用集合框架,而尽可能少用数组作为存储结构? 3、如何使用TreeSet实现第一题?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值