zoukankan      html  css  js  c++  java
  • Java 集合

     

    Java集合:

      Java集合主要负责保存、承装其他数据,因此集合类也被称为容器类;

      Java集合大致可分为Set、List、Queue、Map四种,其中Set代表无序,不可重复的集合;List代表有序,可重复的集合;Map则代表具有映射关系的集合,Java5后又增加了Queue体系集合,代表一种队列集合的实现;

      所有的集合类都在java.util包下;Java5还在java.util.concurrent包下提供了一些多线程支持的集合类

    Java集合与数组的区别:

      数组长度不可变化,一旦在初始化的时候指定了数组长度,这个数组长度就是不可变的,如果需要保存数量变化的数据,数组就无能为力了;

      数组无法保存具有映射关系的数据,如成绩表:语文-70,数学-80;

      数组元素既可以是基本类型的值,也可以是对象(其实是对象的引用变量),而集合中只能保存对象(其实是对象的引用变量)

    Java集合体系:

      Java集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口,这两个接口又包含了一些子接口或实现类Collection体系:

      Set和List接口是Collection接口派生的两个子接口,分别代表了无序集合和有序集合

      Queue是Java提供的队列实现

    Map体系:

      Map接口有众多实现类,这些实现类在功能、用法上存在一定的差异,但他们都有一个功能特征:Map保存的每项数据都是key-value对

    Set集合之HashSet:

      HashSet按照Hash算法存储集合的元素,因此具有很好的存取和查找性能;

      当向HashSet集合中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据这个hashCode值决定该对象在HashSet中存储的位置;如果有两个元素通过equals()方法比较返回true,但它们的hashCode()方法返回值不等,HashSet会把他们存储在不同的位置,依然可以添加成功;

      也就是说,HashSet集合判断两个元素相等的标准是两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法返回值也相等

      特点:

        1 不能保证元素的排列顺序

        2 HashSet不是同步的,如果多线程同时访问一个HashSet,假设有两个或两个以上的线程同时修改了HashSet集合时,必须通过代码保证同步

        3 集合元素可以为null

    hashCode()方法重写的基本规则:
      
      1 程序运行过程中,同一对对象多次调用hashCode()应返回相同的值
      2 对象中用作equals()方法比较标准的实例变量,都应该用于计算hashCode
      3 如果需要把某个类的对象保存到HashSet集合中,重写这个类的equals()方法和hashCode()方法时,应该尽量保证两个对象通过equals()方法比较返回true时,他们的hashCode()方法返回值也相等


    如果两个对象通过equals()方法返回true,但这两个对象的hashCode()方法返回不同的hashCode时,这将导致HashSet会把这两个对象保存在Hash表的不同位置,从而使两个对象都可以添加成功,这就与Set集合的规则冲突了
    如果两个对象的hashCode()方法返回值相同,但他们通过equals方法比较返回false时更麻烦:
      因为两个对象的hashCode()值相同,HashSet试图将他们保存在同一位置,但又不行(否则只会剩下一个对象),所以实际上会在这个位置用链式结构来保存多个对象;
      而HashSet访问集合元素时也是根据元素的hashCode值来快速定位的,如果HashCode中两个以上的元素具有相同的hashCode,将会导致性能下降


    hashCode()方法是不是对HashSet十分重要?

      hash算法的功能是,他能保证快速查找的被检索的对象,hash算法的价值在与速度;当需要查询集合中的某个元素时,hash算法可以直接根据元素的hashCode计算出元素的存储位置,从而快速定位元素
      

     为什么不直接使用数组,还需要HashSet?

       数组元素的索引是连续的。而且数组的长度是固定的,无法自由增加数组的长度;而HashSet使用hashCode计算元素的存储位置,从而可以自由增加HashSet的长度,并且可以根据元素的hashCode来快速访问元素

    
    

     Set集合之LinkedHashSet:

      LinkedHashSet是HashSet的子类。也是根据元素的hashCode值确定元素的存储位置,同时使用链表维护元素的次序,这样是的元素看起来是以插入的顺序保存的

        LinkedHashSet需要维护元素插入的顺序,因此性能略低于HashSet的性能,但在迭代访问Set全部元素时将有很好的性能,因为他用链表来维护内部顺序

     List集合之ArrayList:

      List判断两个对象相等的标准是equals()方法比较返回true即可;

      List增加了sort()和erplaceAll()两个常用的默认方法,其中,sort()方法需要一个Comparator对象来控制元素排序

    ArrayList的底层实现:
    为什么ArrayList可以变长?

      ArrayList和Vector都是基于数组实现的List类,所以ArrayList和Vector类封装了一个动态的、可再分配的Object[]数组;
      ArrayList或Vector对象使用initialCapacity参数来设置该数组的长度,当向ArrayList或Vector中添加元素超出了该数组的长度后,他们的initialCapaticy会自动增加;
      通常,我们不需要关心initiaCapaticy,但如果向ArrayList或Vector集合中添加大量元素时,可使用ensureCapaticy(int minCapaticy)方法一次性的增加initialCapaticy,这可以减少再分配的次数,提高性能
      如果开始就知道ArrayList或Vector集合需要保存多少元素,则可以在创建它们时就指定initialCapaticy大小
      如果创建空的ArrayList或Vector集合时不指定initialCapaticy参数,则Object[]的长度默认为10

    List集合之Vector:

      ArrayList和Vector都是基于数组实现的List类,所以ArrayList和Vector类封装了一个允许再分配的Object[]数组;

      ArrayList是线程不安全的,当多个线程访问同一个ArrayList集合时,如果有一个线程修改了ArrayList集合,则程序必须手动保证该集合的同步性,但是Collections工具类,会将一个ArrayList变为线程安全的

     List集合之LinkedList:

      LinkedList可以根据索引来随机访问集合中的元素;

      除此之外,LinkedList还实现了Deque接口,可以被当成双端队列使用,因此,既可以被当成栈来用,也可以当成队列使用;

    ArrayList和LinkedList的区别:
     
      LinkedList与ArrayList、ArrayDeque的实现机制不同,ArrayList和ArrayDeque内部使用数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能;
      而LinkedList内部使用连标的形式来保存集合中的元素,因此随机访问性能较差,但在插入、删除时性能比较出色

     Map集合之HashMap:

       如果将Map里的所有value放在一起看,非常类似于一个List:

        元素与元素之间可以重复;

        每个元素可以根据索引来查找,只是Map中的索引不再使用整数值,而是以另一个对象作为索引:如果要从List集合中取出元素,则需要提供元素的数字索引;如果要从Map中取出元素,则需要提供元素的key索引,因此,Map有时也被称为字典或关联数组

      如何保证键不能重复(和HashSet相同)
        int hashCode()
       Boolean equals(Object obj)


    public
    int hashCode() { return name.hashCode()+age*33; } public boolean equals(Object obj) { if(!obj instanceof Student) throw new ClassCastException("类型转换异常"); Student stu = (Student)obj; return this.name.equals(stu.name) && this.age==stu.age; }

    Map集合之Hashtable:

      HashMap和Hashtable都是Map接口的典型实现类,他们之间的关系类似于ArrayList和Vector的关系;

      HashTable是一个古老的Map实现类,出现的时候Java还没有提供Map接口,所以它包含了两个繁琐的方法:elements()和keys();

      Java8改进了HashMap的实现,使用HashMap存在key冲突时依然具有较好的性能

    HashMap与Hashtable的区别:

      Hashtable是一个线程安全的Map实现,而HashMap是线程不安全的实现,所以HashMap比Hashtable的性能高一点;但如果有多个线程访问同一个Map对象时,使用Hashtable实现类会更好;

      Hashtable不允许使用null作为key和value,但是如果试图将null值放入Hashtable中,将会引发NullPointerException异常;但是HashMap可以使用null作为key或value;

      与Vector类似的是,尽量少用Hashtable,即使需要创建线程安全的Map实现类,也无须使用Hashtable实现类,可以通过Collections工具类把HashMap变为线程安全的

    Java集合遍历的方法:

      Iterator:

    Set<K> keyset()

    得到所有键的集合存储到一个Set中,并返回一个Set集合,因为Set有迭代器,所以使用迭代器迭代,每次迭代出一个键,再根据键获取值

    Set<String> keys = map.keySet();  
    Iterator<String> ite = keys.iterator();  
    while(ite.hasNext())  
    {  
         String key = ite.next();  
         String value = map.get(key);  
         System.out.println(key + "=" + value);  
    }  

    ****************************************************** Set
    <Map.Entry<K, V>> entrySet()   
      Map.Entry
    <K, V>映射关系类型   Entry是定义在Map中的一个静态接口,有了集合中的键值对,才会存在映射关系,所以映射关系是对集合内部事物的描述,所以定义在Map内部   得到每个键值对对应的映射关系类型的值,存到Set集合汇总,并返回该集合,因为Set有迭代器,每次迭代出来的是一个映射类型的值,从这个映射关系类型的值中,即可以得到键,也可以得到值 Set<Map.Entry<String, String>> entry = map.entrySet(); Iterator<Map.Entry<String, String>> ite = keys.iterator(); while(ite.hasNext()) { Map.Entry<String, String> en = ite.next(); String key = en.getKey(); String value = en.getValue(); System.out.println(key + "=" + value); }

      foreach:

     for(数据类型 变量名: 被遍历的数组或Collection集合)
     {
        //使用foreach循环迭代访问集合元素时,该集合不能被改变,否则会引发ConcurrentModificationException异常
     }
    
      HashMap<String, String> map = new HashMap<>();
      map.put("001", "aaa");
      map.put("002", "bbb");
    
      for(String key: map.keySet())
      {
        String value = map.get(key);
        System.out.println(key + "= " + value);
      }
    
      或:
    
      for(Map.entry<String, String> en: map.entrySet())
      {
        String key = en.getKey();
        String value = map.getValue();
        System.out.println(key + "= " + value);
      }

    Arrays工具类: 

     操作数组的工具类
     工具类汇总的方法基本都是静态的
    
     Arrays.toString(arr):把数组中的内容转成字符串
    Arrays.asList(arr):数组转集合  数组转成的集合不能进行添加和删除  因为数组的长度是固定的  数组只能存储对象
    为什么要数组转集合?
      
      集合的方法多:
       迭代:
       Iterator<String> ite = list.iterator();      while(ite.hasNext())      {   
            System.out.println(ite.next());
         }
     int [] arr = {1, 2, 3};
     List list = Aarrays.asList(arr);
     System.out.print(list.size());

    为什么list长度为1? 数组只能存储对象arr是个int数组 集合存储的是引用类型的对象    因为数组是引用类型的
    List将arr整体作为一个对象存入集合    所以长度为1

    Collections工具类:

    操作集合的工具类
    
    Collections.sort():排序
      按照集合中对象所属的类自身具备的比较方式进行排序的
        即int compareTo()方法
      按照自定义的比较方式对集合中的对象
        实现Comparator<String>接口
        重写compare方法
        传入实现接口的类的对象
    
    Collections.reverseOrder():翻转输出结果
      没有参数则翻转默认的比较方式
    如何得到和比较值相反的比较方式?
    
     Comparator com = Collections.reverseOrder(new ComByLength()); Collections.sort(list, com); System.out.println(list);
    自己实现max?
    
      public static <E extends Compare<? super E>> getMax(Clooection<? extends E> col)
      {
          Iterator<? extends E> ite = col.iterator();
           E obj = ite.next();//得到集合中的一个对象
    
          while(ite.hasNext())
          {
              E object = ite.next();
              int num = obj.compareTo(object);
              if(num < 0)
                 obj = object;
          }
            return obj;
      }

     集合转数组

    Collections.toArray(T[] a):
      给定的数组长度大于集合中对象的个数,则使用给定的数组
      给定的数组长度小于集合中对象的个数,会创建一个新的数组织,数组长度和集合对象个数相同
      给定的数组长度和集合中对象个数相同
      集合转数组可以防止数据被随意的添加或删除,因为数组长度是固定的
  • 相关阅读:
    Android x86 镜像分析之四
    Android x86 镜像分析之三
    Android x86 镜像分析之二
    Android x86镜像分析
    tizen镜像制作
    完成登录与注册页面的前端
    JavaScript 基础,登录前端验证
    CSS实例:图片导航块
    导航,头部,CSS基础
    web基础,用html元素制作web页面
  • 原文地址:https://www.cnblogs.com/roxy/p/7304952.html
Copyright © 2011-2022 走看看