zoukankan      html  css  js  c++  java
  • 容器

    数组本身也是容器,是一个简单的线性序列,访问效率非常高。但是数组本身不够灵活,一开始就要定义数组的元素。

    collection(集合/容器)

    set无顺序不重复(hashSet),list有顺序可以重复(ArrayList,LinkedList)。

    map 存放键值对。

    泛型:贴标签,建立类型安全的集合,本质就是数据类型的参数化,告诉编译器在调用的时候必须传入参数类型。

    List中的方法:addAll(Collection B):把B中所有的元素都加到A里面

    removeAll(Collection B):移除本容器中和B容器中共有的元素。

    retainAll(Collection B):移除A容器中AB容器中非交集的元素。

    List:是有序的,可重复的容器。

    有序:List中的每个元素都有索引标记。可以根据元素的索引标记(在List中的位置)访问元素,从而精确控制这些元素。

    可重复:List允许加入重复的元素。更确切的讲,List通常允许满足e1.equals(e2)的元素重复加入容器。

    List中常用的三种实现类:ArrayList、LinkedList和Vector。

    ArrayList的底层实现是数组。

    ArrayList中的add方法是一个重载的方法,可以在指定的位置插入一个数据。add(index,E);

    remove(index):删除指定位置的元素。

    set(index,E)将指定位置的数据设置为E,相当于修改替换。

    get(index):获取索引地址的数据。

    indexOf(Object o) 如果查到,返回索引第一次出现的位置,如果没有查到,返回-1。

    lastIndexOf(Object o) 如果查到,返回索引最后一次出现的位置,如果没有查到,返回-1。

    ArrayList

    底层是数组的方式实现存储。特点是:查询效率高,增删效率低,线程不安全。我们一般使用它。

    数组的长度是有限的,ArrayList是可以存放任意长度,底层自动扩容。定义一个更长的数组,老的复制到新的里面。默认长度是10,可以new ArrayList(size)来定义内部数组的长度。新长度等于老数组长度加老数组的一半

    Old = Old+(Old>>1);

    add与remove底层都是数组的拷贝,remove是自己拷贝自己,报后面的所有元素向前移动一个位置。

    LinkedList

    底层使用双向链表实现存储,特点是查询效率低,增删效率高,线程不安全。

    双向链表也叫双链表,是链表的一种,没一个节点包含三部分,上一个节点、下一个节点、数据。

    Vector

    也是用数组实现的,但是相关方法都加了同步检查,因此“线程安全,效率低”。

    建议:

    需要多线程时用Vector

    不存在线程安全的时候,查找多的用ArrayList,增删多的时候用LinkList。

     

    Map

    Map用来存储键值对,Map中存储的键值对是通过键来标识,所以键不能重复。如果重复,新的覆盖旧的。判断是否重复用的是Equals方法。

    Map接口实现类有HashMap、TreeMap、HashTable、Properties等。

    HashMap底层实现采用了哈希表,这是一种非常重要的数据结构。

    哈希表的基本结构就是“数组+链表”。

    数组:占用空间连续,寻址容易,查询速度快,但是增加删除的效率非常低。

    链表:占用空间不连续。寻址困难,查询速度慢。但是增加和删除的效率非常高。

    主要的存储结构是 Node(key value next hash),是一个单项列表。

    每个节点Node 由key、value、next、hash四部分组成。

    然后把节点放入Node[]数组中,数组中的每个元素都是一个链表。

     

     

    hashMap的存储过程

    1.先计算键对象的hashcode(),然后通过hash()算法计算出应该存储的位置【将hashcode与数组大小相除取余,余数就是节点存放的数组下标,后来改成了位运算,hashcode&(length-1)也是取余,但是长度必须是2的倍数。后来又进行了两次散列处理,是结果更加的散列。】

    Jdk8中,当链表的长度大于8时,链表就转换为红黑树,增加了查询效率。

    hashMap的取值过程

    先计算键对象的hashcode,然后通过hash()算法算得hash值(node中的hash值)定位到存储的位置,然后通过Equals方法去找对应key进行比较,然后找到value从而找到准确的内容。

    java规定:相同的对象的hashcode是相同的

    扩容问题:hashMap数组桶的初始值是16,当元素达到数组桶的0.75倍时,将发生扩容,变成原来的2倍。扩容的本质是定义新的更大的数组,并将就数组内容挨个拷贝到新数组中。

    JDK8将链表在大于8,数组总容量大于64 的情况下把链表变为红黑二叉树。
    除了添加,其他效率都高了。

    TreeMap

    排序的情况下才使用TreeMap,TreeMap的底层是典型的红黑二叉树,每个节点都存储了本身数据、左节点、右节点、父节点、以及节点颜色。

    遍历时按照key递增的方式进行排序。

    Comparable接口

    Comparable接口的方法中有一个compareTo方法 重写compareTo方法定义比较对象,返回值负数对应的是小于,正数是大于,0是等于。
    class Emp  implements Comparable<Emp>  {
        int id;
        String name;
        double salary;
        
        public Emp(int id, String name, double salary) {
            super();
            this.id = id;
            this.name = name;
            this.salary = salary;
        }
    
        @Override
        public String toString() {
            return  "id:"+id+",name:"+name+",salary:"+salary;
        }
        
        @Override
        public int compareTo(Emp o) {        //负数:小于,0:等于,正数:大于
            
            if(this.salary>o.salary){
                return 1;
            }else if(this.salary<o.salary){
                return -1;
            }else{
                if(this.id>o.id){
                    return 1;
                }else if(this.id<o.id){
                    return -1;
                }else{
                    return 0;
                }
            }
            
        }
        
    }

    HashMap与HashTable的区别

    1、HashMap:线程不安全,效率高。允许key或value为null。

    2、HashTable:线程安全,效率低。不允许key或value为null。

     

    set接口

    没有顺序,不可重复。只能遍历查找;不可重复指不允许加入重复的元素(新元素如果和Set中的某个元素通过equals()方法对比为true,则不能加入)。Set中只能放一个null元素,不能放入多个。

    Set常见的实现类有:HashSet,TreeSet等,通产使用HashSet。

    HashSet

    HashSet也是采用的哈希算法实现的,底层实际用的是HashMap实现的(HashSet本质就是一个简化版的HashMap),因此,查询效率和增删效率都比较高。

    HashSet就是一个hashMap,存储的值就是map的键,所以不能重复。

    TreeSet

    TreeSet的底层是TreeMap,也是用map的键进行set值的存储,也是按照元素递增的方式进行存储。自定义排序也用实现Comparable接口实现CompareTo方法。

    Iterator迭代器

    可遍历List Set Map

    以hasNext和Next配合使用。

    其中Map需要先用keySet获取键,然后迭代器遍历键的set获取值。或者使用entrySet直接获取Set<Entry<K,V>>然后进行遍历。

    Collections工具类

    对Set、List、Map进行排序、填充、查找元素的辅助方法。

    void sort(List)对List容器内的元素进行排序,排序的规则是按照升序进行排序。自定义的类使用COmparable接口。

    void shuffle(List) 随机排序 打乱顺序

    void reverse(List)逆序排序 12345 --> 54321 132-->231

    void fill(List,Object)用一个特定的对象重写整个List容器。

    int binarySearch(List,Object)对于顺序的List容器,采用折半查找(二分法)的方法查找特定的对象。

  • 相关阅读:
    存储过程,触发器,函数 学习总结
    发布软件之前,怎样告诉用户怎么用
    一种小项目开发结构
    错误记录 两种实现方法
    模具行业生产知识
    请大家警惕这个散播木马的网站 www.zzyqr.com,本文简要地分析了它通过网页的传播方式
    如何保证开发过程中对数据库结构的更新顺利地迁移到产品服务器上。
    三层开发中容易犯的错误
    全局程序集缓存导致cs0006编译错误:找不到元数据文件错误
    for VS. foreach 那个性能更高,为什么,怎么选择
  • 原文地址:https://www.cnblogs.com/hg1205/p/12834789.html
Copyright © 2011-2022 走看看