zoukankan      html  css  js  c++  java
  • Java开发中的高频Collections用法总结与Java平台实现源代码查看方式

    一生二,二生三,三生万物,基础永远是一个计算机人的立身之本,相信看到这篇文章的人一般都知道数据结构这门课程,要不也不会找到我的这篇文章。数据结构这门课程的分析奠定了工程师对各种平台中的容器类,集合类的理解基础,正如好多人所说的,如果你对某个平台的集合类理解的不透彻,很可能,你并不是不会使用那个平台上的代码,而是数据结构没理解透彻。

    Windows NT平台上,MFC, ATL提供的集合类很少,而且功能很弱,这就导致了事实上的标准成了STL,相比于.Net 和 Java平台 STL在使用上稍显逊色,但是效率上应该是更胜一筹。但是不管哪种实现,都是基于数据结构的理论基础的,本文将讨论的是Java平台的高频集合类的使用方法。

    首先要讨论的是LinkedList, 当我们需要经常性的插入或者删除元素的时候,我们的选择是LinkedList,因为没有移动元素的开销,但是Java中的LinkedList有一个怪癖,大家可能需要注意一下,每当需要删除元素的时候,需要先调用一次迭代器的next(), 然后是remove(), 使用起来稍显不自然。

    public class LinkedListTest
    {
       public static void main(String[] args)
       {
          List<String> a = new LinkedList<>();
          a.add("Amy");
          a.add("Carl");
          a.add("Erica");
    
    
          List<String> b = new LinkedList<>();
          b.add("Bob");
          b.add("Doug");
          b.add("Frances");
          b.add("Gloria");
    
          // merge the words from b into a
          ListIterator<String> aIter = a.listIterator();
          
          //Iterator<String> aIter = a.iterator();
          Iterator<String> bIter = b.iterator();
          
          while (bIter.hasNext())
          {        
             if (aIter.hasNext()) aIter.next();
             aIter.add(bIter.next());
          }
    
          System.out.println(a);
    
          // remove every second word from b
    
          bIter = b.iterator();
          while (bIter.hasNext())
          {
             bIter.next(); // skip one element
             if (bIter.hasNext())
             {
                bIter.next(); // skip next element
                bIter.remove(); // remove that element 
             }
          }
    
          System.out.println(b);
    
          // bulk operation: remove all words in b from a
    
          a.removeAll(b);
    
          System.out.println(a);
       }
    }

    LinkedList在对数据进行查找的时候,时间复杂度是O(n)的,当对查找需求比较高的时候就需要使用更加高效率的容器,比如HashSet, 其对元素的查找可以达到线性时间复杂度。

    public class SetTest
    {
       public static void main(String[] args)
       {
          Set<String> words = new HashSet<String>(); // HashSet implements Set
          long totalTime = 0;
    
          Scanner in = new Scanner(System.in);
          while (in.hasNext())
          {
             String word = in.next();
             long callTime = System.currentTimeMillis();
             words.add(word);
             callTime = System.currentTimeMillis() - callTime;
             totalTime += callTime;
          }
    
          Iterator<String> iter = words.iterator();
          for (int i = 1; i <= 20 && iter.hasNext(); i++)
             System.out.println(iter.next());
          System.out.println(". . .");
          System.out.println(words.size() + " distinct words. " + totalTime + " milliseconds.");
       }
    }

    HashSet对元素的迭代访问是随机顺序的,所以如果对顺序比较敏感,可能就要考虑TreeSet,插入后的元素自动排序,输出时是有序的集合。

    public class TreeSetTest
    {  
       public static void main(String[] args)
       {  
          SortedSet<Item> parts = new TreeSet<>();
          parts.add(new Item("Toaster", 1234));
          parts.add(new Item("Widget", 4562));
          parts.add(new Item("Modem", 9912));
          System.out.println(parts);
    
          SortedSet<Item> sortByDescription = new TreeSet<>(new
             Comparator<Item>()
             {  
                public int compare(Item a, Item b)
                {  
                   String descrA = a.getDescription();
                   String descrB = b.getDescription();
                   return descrA.compareTo(descrB);
                }
             });
    
          sortByDescription.addAll(parts);
          System.out.println(sortByDescription);
       }
    }

     

    还记得数据结构中的小根堆吧?Java中也有相应的实现,他的名字是priorityQueue, 这个小根堆本身的迭代是无序的,但是小根堆保证每次删除的元素都是集合中最小的一个,也就是根。

    public class PriorityQueueTest
    {
       public static void main(String[] args)
       {
          PriorityQueue<GregorianCalendar> pq = new PriorityQueue<>();
          pq.add(new GregorianCalendar(1906, Calendar.DECEMBER, 9)); // G. Hopper
          pq.add(new GregorianCalendar(1815, Calendar.DECEMBER, 10)); // A. Lovelace
          pq.add(new GregorianCalendar(1903, Calendar.DECEMBER, 3)); // J. von Neumann
          pq.add(new GregorianCalendar(1910, Calendar.JUNE, 22)); // K. Zuse
    
          System.out.println("Iterating over elements...");
          for (GregorianCalendar date : pq)
             System.out.println(date.get(Calendar.YEAR));
          System.out.println("Removing elements...");
          while (!pq.isEmpty())
             System.out.println(pq.remove().get(Calendar.YEAR));
       }
    }

    大家在使用Set类集合的时候有个不方便的地方就是,如果我需要查找一个元素,我得先知道这个元素的详细信息,所有的信息,而不能通过关键字查找,Map的出现解决了这个问题, Map本身是一个键值对,可以通过键来取值,这就大大方便了查找,但是付出的代价是多存储了一个键。

    public class MapTest
    {
       public static void main(String[] args)
       {
          Map<String, Employee> staff = new HashMap<>();
          staff.put("144-25-5464", new Employee("Amy Lee"));
          staff.put("567-24-2546", new Employee("Harry Hacker"));
          staff.put("157-62-7935", new Employee("Gary Cooper"));
          staff.put("456-62-5527", new Employee("Francesca Cruz"));
    
          // print all entries
    
          System.out.println(staff);
    
          // remove an entry
    
          staff.remove("567-24-2546");
    
          // replace an entry
    
          staff.put("456-62-5527", new Employee("Francesca Miller"));
    
          // look up a value
    
          System.out.println(staff.get("157-62-7935"));
    
          // iterate through all entries
    
          for (Map.Entry<String, Employee> entry : staff.entrySet())
          {
             String key = entry.getKey();
             Employee value = entry.getValue();
             System.out.println("key=" + key + ", value=" + value);
          }
       }
    }

    另外,Java语言本身是开源的,所有这些集合类的实现也是开源的,如果我们能够学习和调试这些大师们写的代码,无疑会使我们的学习事半功倍,那么怎么进行设置才能调试这些平台源码呢?

    1. 必须安装JDK, JRE是不行的

    2. 在配置项目的时候选择JDK下的JRE

    3. 在你想研究的类或者函数上按键F3, 更多快捷键请参考下文, 具体设置请参看下图。

    http://www.cnblogs.com/pugang/p/4471558.html

  • 相关阅读:
    【AtCoder】Tenka1 Programmer Contest(C
    【AtCoder】AGC024
    【AtCoder】ARC098题解
    java反射机制详解 及 Method.invoke解释
    Spring切入点表达式常用写法
    border-radius 样式表CSS3圆角属性
    jquery判断自己是父节点的第几个子节点
    Spring事务配置的五种方式
    Spring中PropertyPlaceholderConfigurer的使用
    js中使用s(c)标签
  • 原文地址:https://www.cnblogs.com/pugang/p/4471661.html
Copyright © 2011-2022 走看看