13、集合2

一、HashMap和Hashtable排序

  将HashMap转换成List之后才能排序,排序之后的循环输出使用list的迭代器,不能使用map的迭代器。

public class G {
    public static void main(String[] args) {
        Map<String,Integer> map=new HashMap<>();
        map.put("a",1);
        map.put("b",2);
        map.put("c",3);
        map.put("d",4);
        Set<String> ss=map.keySet();
        Iterator<String> it=ss.iterator();
        while(it.hasNext()){
            String key=it.next();
            System.out.println(key+":"+map.get(key));
        }
        List<Map.Entry<String,Integer>> list=new ArrayList<>(map.entrySet());
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return -(o1.getKey().compareTo(o2.getKey()));
            }
        });
        Iterator<Map.Entry<String,Integer>> it1=list.iterator();
        while(it1.hasNext()){
            System.out.println(it1.next());
        }
    }
}

二、ConcurrentHushMap 当前HashMap

  HashMap在并发编程过程中使用非同步可能导致死循环,因为插入过程不是原子操作,每个HashEntry是一个链表节点,很可能在插入的过程中,已经设置了后节点,实际还未插入,最终反而插入在后节点之后,造成链中出现环。只有一把锁,有获取意向的线程数目增加,导致大量线程处于轮询或阻塞状态。导致同一个时间段有效执行的线程的增量远不及线程总体增量。

  HashTable因为内部是采用synchronized来保证线程安全的,但在线程竞争激烈的情况下HashTable的效率下降的很快,因为synchronized关键字会造成代码块或方法成为临界区(对同一个对象加互斥锁),当一个线程访问临界区的代码时,其他线程也访问同一临界区时,会进入阻塞或轮询状态。

  在查询时,尤其能够体现出CocurrentHashMap在效率上的优势,HashTable使用Sychronized关键字,会导致同时只能有一个查询在执行,而Cocurrent则不采取加锁的方式,而是采用volatile关键字,虽然会牺牲效率,但是性能稍好。

  CocurrentHashMap利用锁分段技术增加了锁的数目,从而使争夺同一把锁的线程得到了控制。

  锁分段技术就是对数据集进行分段,每段竞争一把锁,不同数据段的数据不存在锁竞争,从而有效提高并发访问效率。

Synchronized和volatile的区别

  

cocurrenthashmap结构(segment看成hashmap数组形式的锁,一个segment单元对应一个链表结构hashentry数组,每个hashentry是一个链表结构。segment守护者一个Hashentry数组你的元素)

concurrentHashMap使用场景:

  

用法:

public class H {
    public static void main(String[] args) {
        Map<Integer,String> map=new ConcurrentHashMap<>();
        map.put(1,"A");
        map.put(2,"B");
        map.put(3,"C");
        map.put(4,"D");
        Set<Integer> s=map.keySet();
        Iterator<Integer> it=s.iterator();
        while(it.hasNext()){
           Integer key=it.next();
            System.out.println(key);
        }
    }
}

三、Properties

  用文件流读取文件内容,是HashTable的儿子,安全

  

public class I {
    public static void main(String[] args) {
        Properties pro=new Properties();
        try {
            pro.load(new FileInputStream(new File("src/com/zxc/M/obj")));
            Set<Map.Entry<Object,Object>> ss=pro.entrySet();
            Iterator<Map.Entry<Object,Object>> it=ss.iterator();
            while(it.hasNext()){
                Map.Entry e=it.next();
                System.out.println(e.getKey()+"="+e.getValue());

            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

四、Set接口

  不允许包含相同元素(如果有重复会被覆盖),Set判断两个对象是否相同需要采用equals方法进行判断。

  HashSet是其实现类,有以下特点

HashSet当存入一个元素时,会调用该元素的hashCode()方法来得到该元素的hashCode值,之后以该值的顺序进行存储。

  

原文地址:https://www.cnblogs.com/television/p/8428239.html