java之集合综述

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29726359/article/details/87904696

java之集合

集合的根

  • Collection是所有集合的根接口。一些Collection一些子类有些允许有重复元素,有些不允许,一些子类示例中存放的元素是有序的,有些事无序的。
  • 集合公有方法:add、addAll、clear、contains、isEmpty、iterator、remove、size、toArray。

集合框架图

在这里插入图片描述

List、Queue、Set依然是接口

迭代器

  • 我们知道for循环可以遍历数组,这种方法的缺点是事先我们必须知道集合的数据结构,如果我们换一种数据结构的话,for循环可能会不适用,比如set集合,事实上几乎每一种集合都有独自的访问方法,这样代码就不可复用。为什么解决问题,迭代器诞生了。

  • 迭代器用一种兼容的机制,可以遍历任何数组结构的集合。

  • 方法啊:hasNext、next、remove。

  • 使用迭代器器时,集合就不能有remove操作,否则会报错。

  • 示例代码

        public static void displayElem(Iterator<String> its){
            while(its.hasNext()){
                System.out.println(its.next());
            }
    
        }
        public static void main(String[] args) {
            List<String>list = new ArrayList<String>();
            list.add("test1");
            list.add("test2");
            list.add("test3");
            list.add("test4");
            displayElem( list.iterator());
    
            List<String>list1= new LinkedList<String>();
            list1.add("test5");
            list1.add("test6");
            list1.add("test7");
            list1.add("test8");
            displayElem( list1.iterator());
    
            Set<String> set = new HashSet<>();
            set.add("test9");
            set.add("test11");
            displayElem( set.iterator());
        }
    
  • 结果

    test1
    test2
    test3
    test4
    test5
    test6
    test7
    test8
    test9
    test11
    
  • 迭代器remove方法使用

    • 使用迭代器时,集合remove方法不能使用,否则会报错

          public static void main(String[] args) {
              List<String> all = new ArrayList<String>();
              all.add("a");
              all.add("b");
              all.add("c");
              all.add("d");
      
              Iterator<String> iterator=all.iterator();//实例化迭代器
              while(iterator.hasNext()){
                  String str=iterator.next();//读取当前集合数据元素
                  if("b".equals(str)){
                      all.remove(str);
                  }else{
                      System.out.println( str+" ");
                  }
              }
              System.out.println("\n删除\"b\"之后的集合当中的数据为:"+all);
          }
      
      a 
      Exception in thread "main" java.util.ConcurrentModificationException
      	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
      	at java.util.ArrayList$Itr.next(ArrayList.java:851)
      	at deidaiqi.main(deidaiqi.java:41)
      
    • 可以用迭代器本身的remove方法来进行替换

      扫描二维码关注公众号,回复: 5376868 查看本文章
        List<String> all = new ArrayList<String>();
              all.add("a");
              all.add("b");
              all.add("c");
      
              Iterator<String> iterator = all.iterator();//实例化迭代器
      
              while(iterator.hasNext()){
                  String str=iterator.next();//读取当前集合数据元素
                  if("b".equals(str)){
                      //all.remove(str);//使用集合当中的remove方法对当前迭代器当中的数据元素值进行删除操作(注:此操作将会破坏整个迭代器结构)使得迭代器在接下来将不会起作用
                      iterator.remove();
                  }else{
                      System.out.println( str+" ");
                  }
              }
              System.out.println("\n删除\"b\"之后的集合当中的数据为:"+all);
      }
      
      a 
      c 
      
      删除"b"之后的集合当中的数据为:[a, c]
      

列表

  • List是个接口,本身不能被实例化,可以实例化其子类。

  • ArrayList

    • 底层数组,特点在于查询速度很快;但是插入,删除元素的时候稍慢.

    • 线程不安全

    • 示例代码

         public static void sop(Object o){
              System.out.println(o);
          }
      
              List list = new ArrayList();
              list.add("a");// 向集合中追加元素
              sop(list);
              list.add(1, "b");// 向集合的制定位置中追加元素,其他后移
              sop(list);
              list.addAll(list);// 向集合追加一个collection,只可追加collection,由于java不提供collection的实现,由它的下级接口来实现
              list.addAll(4, list);// 与上述含义相同, “4”意为追加元素所放的位置
              sop(list);
              int i = list.size();// 长度
              System.out.println(i);
              list.get(0);// 根据元素下标来取集合中的元素
              list.remove(7);// 根据集合中元素下标位置来删除元素
              sop(list);
              // 此方法是用来比较的,与equals比较相似,现在list的元素中有[a, b, a, b, a, b, a],来和"a,b,c"比较会返回false,
              // 但是注意再用来比较String字符串的时候会进行局部的比较,两组字符串部分相同的情况下会返回true
              System.out.println(list.contains("a,b,c"));
              //为了将List转为数组,JDK提供了toArray
              //实现方式一:
              String [] array=(String[]) list.toArray(new String[list.size()]);
              for(String arrays: array) {
                  System.out.print(arrays+" ");
              }
              //方式二:
              String [] arr=new String [list.size()];
              list.toArray(arr);
              for(String arrs: arr) {
                  System.out.print(arrs+" ");
              }
              //在集合中判断是否为空 ,不空返回false,空会返回true,常常会与null!=list来共同判定集合是否为空,
              //null!=list和list.isempty最大的区别是:一个人要喝水,前者判断是否有水杯,后者判断的是水杯是否有水
              System.out.println(list.isEmpty());//false
              System.out.println(null!=list);//true
              //该方法去比较两个对象时,首先先去判断两个对象是否具有相同的地址,如果是同一个对象的引用,则直接放回true;如果地址不一样,
              //则证明不是引用同一个对象,接下来就是挨个去比较两个字符串对象的内容是否一致,完全相等返回true,否则false。
              //这里会涉及到hashcode相关内容,我会单独开一篇来介绍
              list.equals(arr);//false
              //在集合中查找元素 ,"a"如果有 ,返回所查找元素的下标,如果不存在则返回-1
              System.out.println(list.indexOf("a"));
              //打印集合元素
              //方式一:
              Iterator it=list.iterator();
              while(it.hasNext()) {
                  String string=(String) it.next();
                  System.out.print(string+" ");
              }
              //方式二:
              for (Object o:list) {
                  System.out.print(o+" ");
              }
              //方式三:
              for(int s=0;s<list.size();s++) {
                  System.out.print(list.get(s)+" ");
              }
              //将list释放,元素清空,且无返回值
              list.clear();
              sop(list);
      }
      
    [a]
    [a, b]
    [a, b, a, b, a, b, a, b]
    8
    [a, b, a, b, a, b, a]
    false
    a b a b a b a a b a b a b a false
    true
    0
    a b a b a b a a b a b a b a a b a b a b a []
         ```
    
    
  • Vector

    • 底层数据结构为数组。

    • Vector比ArrayList出现的早,相当于ArrayList的前身,大多数情况下使用ArrayLsit,因为效率较高。

    • Vector线程安全。

    • 与ArrayList区别

      在这里插入图片描述

  • LinkedList(双向队列)

    • 底层链表:查询速度非常慢,需重头开始遍历,直到遍历到要查询的那一元素位置。但是插入速度非常快。

    • 示例代码,这里只举linkList特有的方法。

      public static void main(String[] args) {
           LinkedList<String>linkedList = new LinkedList<String>();
           linkedList.add("test1");//添加
           linkedList.add("test2");
           linkedList.add("test3");
           linkedList.add("test4");
           linkedList.add("test5");
           sop(linkedList);
           linkedList.addFirst("test6");
           sop(linkedList);
           linkedList.addLast("test7");
           sop(linkedList);
           //获取链表的头
           sop(linkedList.element());
           //获取第一元素
              sop(linkedList.getFirst());
              //获取最后一个元素
              sop(linkedList.getLast());
              //找到并移除此列表的头
              System.out.println(linkedList.poll());
              sop(linkedList);
              //找到并移除链表第一个元素
              System.out.println(linkedList.removeFirst());
              sop(linkedList);
              //找到并移除链表最后一个元素
              System.out.println(linkedList.removeLast());
              sop(linkedList);
      }
      

  • set元素是无序的,元素不可重复。

  • 无序性:

    • 当输入的值大小和底层数组大小差不多的时候,HashSet的输入顺序是无序的,但输出是有序的,因为这些数的哈希值,在底层是顺序拍的,故输出也是有序的。

        public static void sop(Object o){
              System.out.println(o);
          }
          public static void main(String[] args) {
           HashSet hashSet = new HashSet();
           hashSet.add("java01");
           hashSet.add("java02");
           hashSet.add("java03");
           hashSet.add("java04");
           hashSet.add("java05");
           hashSet.add("java06");
           hashSet.add("java07");
           sop(hashSet);
      }
      
      [java07, java06, java05, java04, java03, java02, java01]
      
    • 输入无序,而当输入的值大小和底层数组相差很大时,大的数的哈希值有可能是小于比他小的数的,这时候输出的结果就是无序的。

           HashSet<Integer> hashSet = new HashSet();
           hashSet.add(1);
           hashSet.add(10000000);
           hashSet.add(20);
           hashSet.add(123344);
           hashSet.add(9000);
           hashSet.add(122344);
           hashSet.add(234);
           sop(hashSet);
         Iterator<Integer> iterator = hashSet.iterator();
         while(iterator.hasNext()){
             System.out.print(iterator.next()+" ");
         }
      
      [1, 123344, 20, 10000000, 9000, 122344, 234]
      1 123344 20 10000000 9000 122344 234 
      
  • HashSet

    • 底层哈希表
      • 没放一个
    • 他的方法和list大同小异
    • set是如何自动去重的
      • 当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象也拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放进哈希表中,如果返回的是false,就会把这个值存放在哈希表中。
      • 对象内容一样,哈希值是一样的。
  • 特殊

    • TreeSet:TreeSet 是一个有序的集合,它的作用是提供有序的Set集合。

    • LinkedHashSet(哈希链表): 查询慢,增删快。 有序的,存放顺序和取出顺序一致。

映射

  • HashMap:key->value方式保存。key不允许重复。无序存放

猜你喜欢

转载自blog.csdn.net/qq_29726359/article/details/87904696