java 容器类及其数据结构

 这里写图片描述

线程安全与否

安全:Vector、HashTable、StringBuffer

不安全:ArrayList、LinkedList、HashMap、StringBuilder 

非线程安全容器变得线程安全 
使用

  • Listlist=Collections.synchronizedList(new ArrayList());
  • set = Collections.synchronizedSet(new HashSet());
  • map = Collections.synchronizedMap(new HashMap())

序列化可以使得线程变安全。

容器类 UnsupportedOperationException

List list = Arrays.aslIst(); 引起的异常,可以参考

https://blog.csdn.net/liu_005/article/details/74091805

原因:List 、Collection 这种父类没有实现add()方法,抛出了异常,而其最底层的子类ArrayList ,LinkedList实现了,所以不会由问题。

数据结构

ArrayList 底层数组

LinkedList 双向链表

HashMap :数组 + 链表结构。key-value封装成一个Entry对象存储到一个Entry数组中,位置(数组下标)由key的哈希值与数组长度计算而来。

TreeMap/TreeSet :

只要带Tree的容器结构,其对象必须实现Comparable 接口,否则会报错

java.lang.ClassCastException: com.sjh.collection.People cannot be cast to java.lang.Comparable

比如定义个People 实体类:


public class People {

    int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public People(int age) {
        this.age = age;
    }
}

 测试代码:

 TreeSet<People> peopleTreeSet = new TreeSet<>();
        peopleTreeSet.add(new People(1));
        peopleTreeSet.add(new People(3));
        peopleTreeSet.add(new People(2));
        Iterator<People> peopleIterator = peopleTreeSet.iterator();
        while (peopleIterator.hasNext()){
            System.out.println(peopleIterator.next().getAge());
        }

运行时  peopleTreeSet.add(new People(1)); 就会报错,如前面的提示所说。另外,注意基本数据结构比较特殊,它们默认实现了Comparable 接口,所以没有问题。

 

Set :维护一个Map来存储数据的,利用Map结构key值唯一性,HashSet、TreeSet分别默认维护一个HashMap、TreeMap

HashSet :哈希散列集,底层由HashMap支持的,主要使用hashCode()和equal()方法确保Key值不可重复性来保证元素的唯一性

 

 

散列——为速度而散列

 

散列:可以参考书 数据结构,里面有专门一章节讲解这个,如果想要搞明白可以看书,这里简单写一些东西。

理想的散列表数据结构时一个包含一些项的固定大小的数组;数组里面存放的是项的关键信息,这个称为 key。理想的情况是一个项对应一个数组的位置,但是由于数组固定,而集合是不固定的,如果二者一一分配,就叫完美散列,但集合数据多于数组长度之后,就会存在冲突,多个项会到相同index位置上。而散列的关键问题就是解决这个冲突?于是就产生了不同的算法,有分离链接法、双散列等等。这就是整个散列的原因和中心思想。

 

这里写图片描述

HashMap 、HashTable 、ConcurrentHashMap  的区别和联系

HashMap 的性能要犹豫HashTable ,且key可以为null,线程不安全;

HashTable :废弃类,性能不足HashMap,线程安全,key不能为null;(性能不好,由于线程安全使用的是对象锁synchronized) 

ConcurrentHashMap  :HashTable的优化类,性能好于HashTable,线程安全,key不能为null;

 

Map 遍历

/**
* 最常见也是大多数情况下用的最多的,一般在键值对都需要使用
 */
Map <String,String>map = new HashMap<String,String>();
map.put("熊大", "棕色");
map.put("熊二", "黄色");

方法一
for(Map.Entry<String, String> entry : map.entrySet()){
    String mapKey = entry.getKey();
    String mapValue = entry.getValue();
    System.out.println(mapKey+":"+mapValue);
}

方法二
//key
for(String key : map.keySet()){
    System.out.println(key);
}
//value 也可以通过value = map.get(key)
for(String value : map.values()){
    System.out.println(value);
}

方法三
Iterator<Entry<String, String>> entries = map.entrySet().iterator();
while(entries.hasNext()){
    Entry<String, String> entry = entries.next();
    String key = entry.getKey();
    String value = entry.getValue();
    System.out.println(key+":"+value);
}

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值