精华内容
下载资源
问答
  • 为什么会乱序,是因为取得数据行主键的时候,使用了HashMap.keySet()方法,而这个方法返回的Set结果,里面的数据是乱序排放的。JavaDoc里面没有详细地解释,所以用代码进行了一下尝试import java.sql.Timestamp;...

    上回说到,由于对数据进行处理的时候是按照乱序一行一行的处理,导致并行线程各自占据了一部分数据,谁也不肯释放,从而发生死锁。

    为什么会乱序,是因为取得数据行主键的时候,使用了HashMap.keySet()方法,而这个方法返回的Set结果,里面的数据是乱序排放的。

    JavaDoc里面没有详细地解释,所以用代码进行了一下尝试

    a4c26d1e5885305701be709a3d33442f.png

    import java.sql.Timestamp;

    import java.util.HashMap;

    import java.util.Hashtable;

    import java.util.Iterator;

    import java.util.LinkedHashMap;

    import java.util.Map;

    import java.util.Set;

    import java.util.TreeMap;

    public class Test2 {

    public static void main(String[] args) {

    ///TEST / System.out.println("## Hashtable ##");

    Hashtable ht = new Hashtable();

    ht.put("1", "OOO");

    ht.put("3", "OOO");

    ht.put("2", "OOO");

    ht.put("5", "OOO");

    ht.put("4", "OOO");

    Iterator it = ht.keySet().iterator();

    while (it.hasNext()) {

    System.out.println(it.next());

    }

    ///TEST / System.out.println("## TreeMap ##");

    TreeMap tm = new TreeMap();

    tm.put("1", "OOO");

    tm.put("3", "OOO");

    tm.put("2", "OOO");

    tm.put("5", "OOO");

    tm.put("4", "OOO");

    Iterator it2 = tm.keySet().iterator();

    while (it2.hasNext()) {

    System.out.println(it2.next());

    }

    ///TEST / System.out.println("## HashMap ##");

    Map hm = new HashMap();

    hm.put("1", "OOO");

    hm.put("3", "OOO");

    hm.put("2", "OOO");

    hm.put("5", "OOO");

    hm.put("4", "OOO");

    Iterator it3 = hm.keySet().iterator();

    while (it3.hasNext()) {

    System.out.println(it3.next());

    }

    ///TEST / System.out.println("## LinkedHashMap ##");

    LinkedHashMap lhm = new LinkedHashMap();

    lhm.put("1", "OOO");

    lhm.put("3", "OOO");

    lhm.put("2", "OOO");

    lhm.put("5", "OOO");

    lhm.put("4", "OOO");

    Iterator it4 = lhm.keySet().iterator();

    while (it4.hasNext()) {

    System.out.println(it4.next());

    }

    }

    }

    a4c26d1e5885305701be709a3d33442f.png

    输出结果如下

    a4c26d1e5885305701be709a3d33442f.png

    ## Hashtable ##

    5

    4

    3

    2

    1

    ## TreeMap ##

    1

    2

    3

    4

    5

    ## HashMap ##

    3

    2

    1

    5

    4

    ## LinkedHashMap ##

    1

    3

    2

    5

    4

    a4c26d1e5885305701be709a3d33442f.png

    由此可见,大致上如下

    Hashtable.keySet() 降序

    TreeMap.keySet() 升序

    HashMap.keySet() 乱序

    LinkedHashMap.keySet() 原序

    除了TreeMap.keySet(), JavaDoc中对keySet()返回值的顺序没有明确说明,

    实际应用中,如果对顺序有明确要求,最好能明确的对其顺序进行整理。

    展开全文
  • Set * set=hashMap.keySet(); for(Student stu:set){ System.out.println(stu); * } */ System.out.println("the treeMap out put----"); TreeMaptreeMap = new TreeMap( hashMap); Setset2 = treeMap.keySet(); ...

    使用TreeMap简单地HashMap的key进行排序,使用ArrayList对HashMap的value排序。

    分别使用Comparator接口和Comparable接口实现key的排序。

    package com.inspiration.examples.collection.sort;

    import java.util.ArrayList;

    import java.util.Collection;

    import java.util.Collections;

    import java.util.Comparator;

    import java.util.HashMap;

    import java.util.List;

    import java.util.Map;

    import java.util.Set;

    import java.util.TreeMap;

    import java.util.Map.Entry;

    public class SortExample {

    public static void listSort() {

    ListstuList = new ArrayList();

    Student s1 = new Student(1, "wang");

    Student s2 = new Student(2, "li");

    stuList.add(s1);

    stuList.add(s2);

    Collections.sort(stuList);

    for (Student stu : stuList) {

    System.out.println(stu);

    }

    // map sort which implements the Comparable Interface

    public static void mapKeySetSort() {

    MaphashMap = new HashMap();

    for (int i = 0; i < 100; i++) {

    Student stu = new Student(i, "wang" + i);

    hashMap.put(stu, i);

    }

    /*

    * System.out.println("the hashMap out put----"); Set

    * set=hashMap.keySet(); for(Student stu:set){ System.out.println(stu);

    * }

    */

    System.out.println("the treeMap out put----");

    TreeMaptreeMap = new TreeMap(

    hashMap);

    Setset2 = treeMap.keySet();

    for (Student stu : set2) {

    System.out.println(stu);

    }

    // map sort which implements the Comparator Interface

    public static void mapKeySetSort2() {

    MaphashMap = new HashMap();

    for (int i = 0; i < 100; i++) {

    Teacher tea = new Teacher(i, "wang" + i);

    hashMap.put(tea, i);

    }

    /*

    * System.out.println("the hashMap out put----"); Set

    * set=hashMap.keySet(); for(Teacher tea:set){ System.out.println(tea);

    * }

    */

    System.out.println("the treeMap out put----");

    TreeMaptreeMap = new TreeMap(

    new TeacherComparator());

    treeMap.putAll(hashMap);

    Setset2 = treeMap.keySet();

    for (Teacher tea : set2) {

    System.out.println(tea);

    }

    public static void sortValues() {

    Mapkeyfreqs = new HashMap();

    keyfreqs.put("w", 1);

    keyfreqs.put("b", 2);

    ArrayList> l = new ArrayList>(

    keyfreqs.entrySet());

    Collections.sort(l, new Comparator>() {

    public int compare(Map.Entryo1,

    Map.Entryo2) {

    return (o1.getValue() - o2.getValue());

    }

    });

    for (Entrye : l) {

    System.out.println(e.getKey() + "::::" + e.getValue());

    }

    public static void main(String[] args) {

    // listSort();

    // System.exit(1);

    // mapSort();

    // mapKeySetSort2();

    }

    package com.inspiration.examples.collection.sort;

    public class Student implements Comparable{

    private int id;

    private String name;

    public Student(int id, String name) {

    super();

    this.id = id;

    this.name = name;

    }

    public int getId() {

    return id;

    }

    public void setId(int id) {

    this.id = id;

    }

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    @Override

    public int compareTo(Student o) {

    // return o.id-this.id;

    return this.id-o.id;

    }

    @Override

    public int hashCode() {

    final int prime = 31;

    int result = 1;

    result = prime * result + id;

    return result;

    }

    @Override

    public boolean equals(Object obj) {

    if (this == obj)

    return true;

    if (obj == null)

    return false;

    if (getClass() != obj.getClass())

    return false;

    Student other = (Student) obj;

    if (id != other.id)

    return false;

    return true;

    }

    @Override

    public String toString() {

    return "Student [id=" + id + ", name=" + name + "]";

    }

    package com.inspiration.examples.collection.sort;

    public class Teacher {

    private int id;

    private String name;

    public Teacher(int id, String name) {

    super();

    this.id = id;

    this.name = name;

    }

    public int getId() {

    return id;

    }

    public void setId(int id) {

    this.id = id;

    }

    public String getName() {

    return name;

    }

    public void setName(String name) {

    this.name = name;

    }

    @Override

    public int hashCode() {

    final int prime = 31;

    int result = 1;

    result = prime * result + id;

    return result;

    }

    @Override

    public boolean equals(Object obj) {

    if (this == obj)

    return true;

    if (obj == null)

    return false;

    if (getClass() != obj.getClass())

    return false;

    Teacher other = (Teacher) obj;

    if (id != other.id)

    return false;

    return true;

    }

    @Override

    public String toString() {

    return "Teacher [id=" + id + ", name=" + name + "]";

    }

    package com.inspiration.examples.collection.sort;

    import java.util.Comparator;

    public class TeacherComparator implements Comparator{

    @Override

    public int compare(Teacher o1, Teacher o2) {

    return o1.getId()-o2.getId();

    }

    TreeMap本身使用红黑树算法实现。

    展开全文
  • Java高级之HashMap中的keySet()方法

    千次阅读 2021-02-11 20:53:44
    keySet()方法的源码为: public Set<K> keySet() { Set<K> ks = keySet; if (ks == null) { ks = new KeySet(); keySet = ks; } return ks; } 注释为: /** * 获取HashMap的键的集合,以...

    keySet()方法的源码为:

        public Set<K> keySet() {
            Set<K> ks = keySet;
            if (ks == null) {
                ks = new KeySet();
                keySet = ks;
            }
            return ks;
        }

    注释为:

        /**
         * 获取HashMap的键的集合,以Set<K>保存
         * @return 返回key的集合
         */
        public Set<K> keySet() {
            /*
                说明:
                    1.可以看到其实该方法中,并没有将HashMap中的键添加到Set集合中,那么是如何实现的呢?
                    2.但实际上,我们访问Set集合,根本就无法通过索引,而是需要通过迭代器Iterator才能访问到元素,foreach本质上也是迭代器
                    3.这里的 ks 就仅仅只是一个Set引用,指向HashMap内部类KeySet的一个实例,重点在于该实例拥有自己的迭代器,当我们在使用增强for循环时才会调用该迭代器,也才会输出我们想要的东西
             */
            // 获取keySet
            Set<K> ks = keySet;
            // 判断ks是否为null,如果为null,表示为空
            if (ks == null) {
                // 实例化KeySet对象
                ks = new KeySet();
                // 然后将ks设置给keySet
                keySet = ks;
            }
            // 返回ks
            return ks;
        }

    为了理解该方法参考了:源码解析HashMap的keySet()方法

    但发现还是无法深入理解,最后查看增强for循环,得到了灵感。

    所谓的增强型for循环,即是如下格式的for循环,其中遍历的目标可以是数组,也可以是集合(较为常用):

    for(数据类型 变量名 :遍历的目标){ 
        // 
    }

    例如:

    public class Demo {
        public static void main(String[] args) {
            int[] arr=new int[]{1,2,3,4,5};
            for (int i : arr) {
                System.out.println(i);
            }
        }
    }

    面对这样的代码即使进行debug调试,可能也看不出来什么,但我们可以查看它的字节码文件(即后缀为.class的文件),里面会得到我们想要的。

    该Demo.class的内容为:

    public class Demo {
        public Demo() {
        }
    
        public static void main(String[] args) {
            int[] arr = new int[]{1, 2, 3, 4, 5};
            int[] var2 = arr;
            int var3 = arr.length;
    
            for(int var4 = 0; var4 < var3; ++var4) {
                int i = var2[var4];
                System.out.println(i);
            }
    
        }
    }

    可以看到如果增强型for循环如果遍历的目标是数组,那么最终编译使用的是for循环,得到变量的值进行输出

    那么下面来看看使用增强型for来遍历List集合

    public class Demo {
        public static void main(String[] args) {
            List<String> list=new ArrayList<>();
            list.add("唐僧");
            list.add("孙悟空");
            // 使用增强型for遍历循环List集合
            for (String s : list) {
                System.out.println(s);
            }
        }
    }

    编译后的字节码文件Demo.class内容如下:

    public class Demo {
        public Demo() {
        }
    
        public static void main(String[] args) {
            List<String> list = new ArrayList();
            list.add("唐僧");
            list.add("孙悟空");
            Iterator var2 = list.iterator();
    
            while(var2.hasNext()) {
                String s = (String)var2.next();
                System.out.println(s);
            }
    
        }
    }

    可以看到如果增强型for循环如果遍历的目标是集合,那么最终编译使用的是迭代器,得到变量的值进行输出

    正是因为可以查看编译后的字节码,所以我们可以来查看keySet()方法运行后的结果,先运行下面的代码:

    public class Demo {
        public static void main(String[] args) {
            Map<String,String> map=new HashMap<>();
            map.put("abc","123");
            map.put("efg","456");
            // 使用增强型for遍历循环List集合
            Set<String> keySet = map.keySet();
            for (String key : keySet) {
                System.out.println(key);
            }
        }
    }

    查看编译生成的字节码文件Demo.class

    public class Demo {
        public Demo() {
        }
    
        public static void main(String[] args) {
            Map<String, String> map = new HashMap();
            map.put("abc", "123");
            map.put("efg", "456");
            Set<String> keySet = map.keySet();
            Iterator var3 = keySet.iterator();
    
            while(var3.hasNext()) {
                String key = (String)var3.next();
                System.out.println(key);
            }
    
        }
    }

    那么查看iterator()方法的源码,即迭代器的源码,该类在Set接口中定义了方法,而在HashMap在类KeySet中实现了该方法。

    而我们知道类KeySet在keySet()方法中实例化了

    在iterator()方法中又实例化了KeyIterator这个类对象,那么查看该类

    这是一个next()方法,表示获取下一个元素,在编译后的字节码文件中,我们看到就是通过next()方法得到键key的。

    在next()方法中的返回语句中又调用了nextNode()方法,nextNode().key就是键值对中的键,即我们需要的结果。

    nextNode()方法的源代码如下:

    下面注释这个方法:

     /**
      * 获取下一个结点
      *
      * @return 返回下一个结点信息
      */
     final Node<K, V> nextNode() {
         // 局部变量,保存哈希桶数组table
         Node<K, V>[] t;
         // 局部变量,保存当前结点的下一个结点
         Node<K, V> e = next;
         // 如果修改次数不对,那么多线程修改了HashMap
         if (modCount != expectedModCount)
    	 // 则抛出异常
           throw new ConcurrentModificationException();
         // 如果下一个结点是null
         if (e == null)
         // 则抛出NoSuchElementException异常
           throw new NoSuchElementException();
         // 当前的链表遍历完了就开始遍历下一个链表
         if ((next = (current = e).next) == null && (t = table) != null) {
    		 do {
    		  } while (index < t.length && (next = t[index++]) == null);
         }
         // 返回下一个结点
         return e;
     }

    实际上就是遍历循环的时候获取下一个结点,而nextNode().key就得到了键的值。

    所以遍历循环map.keySet()在编译时分为了三步完成:

    • 第一步:获取到keyset的迭代器。
    • 第二步:调用hasNext()进行while循环。
    • 第三步:通过next()获取键key的值

    到此,已经完成了keySet()方法的解析,主要作用就是实例化KeySet类对象,该类带有一个迭代器方法,使得可以循环遍历通过keySet()方法得到的Set集合。

    总结:keySet()方法本质上是实例化KeySet类对象,然后获得该类自带的iterator()方法,从而能够获得key的集合

    参考链接:

    展开全文
  • 第一种遍历方式(采用keySet):HashMap hashmap = new HashMap();Iterator iterator = hashmap.keySet().iterator();while (iterator.hasNext()) {hashmap.get(iterator.next());}}第二种遍历方式(采用entrySet):...

    第一种遍历方式(采用keySet):

    HashMap hashmap = new HashMap();

    Iterator iterator = hashmap.keySet().iterator();

    while (iterator.hasNext()) {

    hashmap.get(iterator.next());

    }

    }

    第二种遍历方式(采用entrySet):

    HashMap hashmap = new HashMap();

    Iterator iterator = hashmap.entrySet().iterator()

    while (iterator .hasNext()) {

    Entry entry = (Entry) iterator .next();

    entry.getValue();

    }

    }

    JDK官方解释:

    keySet:返回此映射中所包含的键的 set 视图。该集合受映射的支持,所以映射的变化也反映在该集合中,反之亦然。该集合支持元素的移除,通过 Iterator.remove、Set.remove、removeAll、retainAll 和 clear 操作,从该映射中移除相应的映射关系。它不支持 add 或 addAll 操作。

    entrySet:返回此映射所包含的映射关系的 collection 视图。在返回的集合中,每个元素都是一个 Map.Entry。该集合受映射的支持,所以映射的变化也反映在该集合中,反之亦然。该集合支持元素的移除,通过 Iterator.remove、Collection.remove、removeAll、retainAll 和 clear 操作,从该映射中移除相应的映射关系。它不支持 add 或 addAll 操作。

    测试:创建两个HashMap,每个map中放入100万条数据,对其进行遍历,统计遍历所用的时间。

    测试结果:(本机测试,机器不同速度也会不同)使用keySet遍历所用时间为200毫秒左右;使用entrySet遍历所用时间为120毫秒左右

    测试代码:(可直接拷贝运行)

    import java.util.Calendar;

    import java.util.HashMap;

    import java.util.Iterator;

    import java.util.Map.Entry;

    public class HashMapTest {

    public static void main(String[] args) {

    //第二种遍历方式

    HashMap hashmap = new HashMap();

    for (int i = 0; i < 1000000; i++) {

    hashmap.put(i, "");

    }

    long bs = Calendar.getInstance().getTimeInMillis();

    Iterator iterator = hashmap.keySet().iterator();

    while (iterator.hasNext()) {

    hashmap.get(iterator.next());

    }

    System.out.println(Calendar.getInstance().getTimeInMillis() - bs);

    hashmap = null;//将对象赋值为null,不然内存溢出(仅针对本人笔记本……)

    iterator = null;//将对象赋值为null,不然内存溢出(仅针对本人笔记本……)

    //第二种遍历方式

    HashMap hashmap2 = new HashMap();

    for (int i = 0; i < 1000000; i++) {

    hashmap2.put(i, "");

    }

    long bs2 = Calendar.getInstance().getTimeInMillis();

    Iterator it2 = hashmap2.entrySet().iterator();

    while (it2.hasNext()) {

    Entry entry = (Entry) it2.next();

    entry.getValue();

    }

    System.out.println(Calendar.getInstance().getTimeInMillis() - bs2);

    }

    }

    keySet:由hashMap获取keySet,将keySet遍历,转为iterator,遍历iterator,从map中取出对应key的value

    entrySet:由hash获取entrySet,entrySet中包含了key和value,遍历entrySet即可取出value

    展开全文
  • for(String key : j.keySet()){ int count = j.getInt(key); String stars = ""; for(int i=0; i stars += ""; } stars += ""; if(count){ for(int i=0; i<(5-count); i++){ stars += ""; } } jb.add(key,stars); }...
  • keySet()和entrySet()

    2021-04-21 15:25:36
    keySet()和entrySet(),是Map集合中的两种取值方法。 与get(Objectkey)相比,get(Objectkey)只能返回到指定键所映射的值,不能一次全部取出。而keySet()和entrySet()可以。 Map集合中没有迭代器,Map集合取出键值...
  • 可以使用keySet()类java.security.Provider中的方法使用不可修改的Set视图来查看提供程序中的属性键。此方法不需要任何参数,并且根据需要返回属性键的不可修改的Set视图。演示此的程序如下所示-示例importjava....
  • Java LinkedHashMap keySet()方法java.util.LinkedHashMap.keySet()用于返回Map中所有key的Set视图。1 语法public Set keySet()2 参数无3 返回值返回Map中所有key的Set视图。4 示例package com.yiidian;/*** 一点...
  • 发现 Set和HashMap之间还是有很多需要注意的地方:HashMap map = new HashMap();map.put("1", "aa");...1. map的keySet()方法只返回一个set实例,所以当从key1中删除一个对象时候,其他也将会受到影响。2. 针对...
  • hashMap通过keyset遍历时,先调用keySet()方法,该方法返回hashMap中存储的key的集合ks,然后再执行内部类 final class KeySet 中的iterator(),iterator() 返回一个HashMap.KeyIterator()对象。 KeyIterator对象...
  • 使用keySet()从JSONObject提取密钥

    千次阅读 2021-03-15 04:11:21
    ArrayList keys = (ArrayString) posts.keyset(); 问题是无法找到合适的变量类型,在其中我可以存储从 keyset() 方法获得的结果。 我尝试搜索答案,但是在大多数情况下,使用 keys() 来提取密钥(由于某种原因...
  • 本文为大家分享了Map集合中利用keySet方法获取所有的元素值,供大家参考,具体内容如下/*---------------------------Map集合中利用keySet方法获取所有的元素值:....keySet方法:将Map中的所有key值存入到Set集合中...
  • HashMap h=new HashMap<>();for(int i=0; ih.put(str.charAt(i),str.charAt(i...}Set keys=h.keySet();Character [] arr=new Character[keys.size()];keys.toArray(arr);String ans="";for(int i=0; ians+=arr...
  • HashMap之keyset() 方法底层原理 获取HashMap所有的键,通常调用方法keyset()即可返回所有的key集合。那么keyset()的工作原理是什么?它真的会维护一个Set吗,当Map的键值对发生变化,就来更新这个Set? 如果真的是...
  • 对于读取Map的所有键值集合有一个合适的方法:Set sets = map.keySet(); 如果想要直接遍历可以采用: Set<Integer> sets = map.keySet(); Iterator<Integer> it=sets.iterator(); while(it.hasNext()...
  • map.keySet()

    2021-07-08 16:22:10
    System.out.println(map.keySet()); Set<String> strings = map.keySet(); System.out.println("-----分割线-----"); for(String map1 : map.keySet()){ System.out.println(map1); String string = map.keySet()....
  • keySet 还有一种是keySet(), keySet是键的集合,Set里面的类型即key的类型 Set<String> set = map.keySet(); for (String s:set) { System.out.println(s+","+map.get(s)); } 五种遍历Map方式: public static void ...
  • Java TreeMap keySet()方法

    2021-03-15 14:42:29
    Java TreeMap keySet()方法java.util.TreeMap.keySet()返回Map中所有Entry(键值对)的集合。1 语法public Set keySet()2 参数无3 返回值返回Map中所有Entry(键值对)的集合。4 示例package com.yiidian;/*** 一点教程...
  • Java中map.keySet()的含义

    2021-10-28 15:08:48
    一句话总结:.keySet()方法获取map中所有的key(键) 代码如下: public static void main(String[] args) { Map<String,String> map1 = new HashMap<String, String>(); map1.put("键1","值JAVA"); map...
  • /** * 用例主要用来说明keyset转换既定类型数组的问题。 */ public class KeySetToStringArray { public static void main(String[] args) { Map target = new LinkedHashMap(){{ put("key 1", "value 1"); put(...
  • 描述所述的keySet()方法被用来获得此映射中包含的键的Set视图。声明以下是java.util.HashMap.keySet()方法的声明。public Set keySet()参数NA返回值方法调用返回此映射中包含的键的set视图。异常NA实例以下示例显示...
  • ResourceBundle类keySet()方法keySet()方法在java.util包中可用。keySet()方法用于从此ResourceBundle及其超级捆绑包中获取所有现有键,以在Set中进行查看。keySet()方法是一种非静态方法,只能通过类对象访问,如果...
  • Map集合中values,keySet,entrySet的区别以及用法。 1.先来看一下阿里java编码规范是怎么解释的。 再来看定义: 在Map集合中 values():方法是获取集合中的所有的值----没有键,没有对应关系,这里要注意,valus...
  • 编译是用java8,但是运行的时候用的是java7,在运行的时候会报错,经排查是用到了ConcurrentHashMap的keySet()方法, 如下是java7ConcurrentHashMap的keySet()方法源码: publicSet<K>keySet() { Set<K...
  • Java集合类中的 Map.ketSet() ...语法:keySet()典型应用获取Map对象的所有键名,然后迭代输出所有键名。代码如下:public static void main(String[] args){ Map map = new HashMap(); //定义Map集合 map.put("ap...
  • 我们通常说,keySet()返回所有的键,values()返回所有的值,其实是不太对的,因为无论是keySet()和values(),其实都没有实质的内容,且容我慢慢说来。他们前者返回了一个Set,后者返回了一个Collection,但是Set和...
  • 1 /*---------------------------2 Map集合中利用keySet方法获取所有的元素值:3 ....keySet方法:将Map中的所有key值存入到Set集合中,4 ....利用Set集合提供的迭代器获取到每一个key值,再通过key值获得相应的...
  • 2019-11-16package ...import java.util.*;/*** @author: ZH* @date: 2019/10/25 10:45* @description: Map对象中的keySet()、entrySet()和Map.Entry用法*/public class MapEntryTest {public static void ma...
  • Java Map entrySet() keySet() values()顺序是一致的 Byalzhang|8月 25, 2018 0 Comment 一个小例子,把map的entry,key和value转换成数组,测试print出来的顺序是不是一样。 01 02 03 04 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 155,008
精华内容 62,003
关键字:

keyset