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

Java开发中的高频Collections用法总结与Java平台实现源代码查看方式的更多相关文章
- java 开发中 dom4j的简单用法
Java中处理XML的方式有很多种,个人任务dom4j还是比较好用的.下面介绍以下简单的使用方法 先把import补充上 import org.dom4j.Document; import org.d ...
- Java开发中常见的危险信号(上)
本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...
- 编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则)
编写高质量代码:改善Java程序的151个建议(第一章:JAVA开发中通用的方法和准则) 目录 建议1: 不要在常量和变量中出现易混淆的字母 建议2: 莫让常量蜕变成变量 建议3: 三元操作符的类型务 ...
- [ 转载 ] Java开发中的23种设计模式详解(转)
Java开发中的23种设计模式详解(转) 设计模式(Design Patterns) ——可复用面向对象软件的基础 设计模式(Design pattern)是一套被反复使用.多数人知晓的.经过分类 ...
- paip.java 开发中web server的选择jboss resin tomcat比较..
paip.java 开发中web server的选择jboss resin tomcat比较.. 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attilax的专 ...
- Java开发中常见的危险信号(中)
本文来源于我在InfoQ中文站原创的文章,原文地址是:http://www.infoq.com/cn/news/2013/12/common-red-flags-in-java-1 Dustin Ma ...
- Java开发中文件读取方式总结
JAVA开发中,免不了要读文件操作,读取文件,首先就需要获取文件的路径. 路径分为绝对路径和相对路径. 在文件系统中,绝对路径都是以盘符开始的,例如C:\abc\1.txt. 什么是相对路径呢?相对路 ...
- java开发中遇到的问题及解决方法(持续更新)
摘自 http://blog.csdn.net/pony12/article/details/38456261 java开发中遇到的问题及解决方法(持续更新) 工作中,以C/C++开发为主,难免与其他 ...
- 在Java 线程中返回值的用法
http://icgemu.iteye.com/blog/467848 在Java 线程中返回值的用法 博客分类: Java Javathread 有时在执行线程中需要在线程中返回一个值:常规中我们 ...
随机推荐
- stanford-parser使用说明
主意:本说明文档针对stanford-parser-full-2014-06-16.不同版本的parser,其功能和表示形式可能会略有不同.但总体不会有太大差异 Stanford parser是一款较 ...
- JAVA学习博客---2015-8
八月份的学习博客,今天已经是九月四号了,补上吧.现在我又回到C++了,JAVA的基本的东西都懂了,但是更好的掌握JAVA,我必须原路返回去学习C++,当初为了更快的学JAVA,其实我得C++都是跳着看 ...
- oracle ORA-12514: TNS: no listener 解决方案
服务端:oracle 11g 客户端: pl/sql 问题描述: 用客户端 pl/sql 连接登录的时候,提示 "ORA-12514: TNS: no listener". 在服务 ...
- Swift 对比学习 (二)
书接上回,可以作为参数和返回值的函数数型,以及嵌套函数,绝对继承了动态语言的优良传统: 函数嵌套了,那必然少不了闭包问题,Swift的闭包表达式语法也蛮有趣的. { (paraeeters) -> ...
- CodeIgniter2.2.0-在控制器里调用load失败报错的问题
报错如下: hello A PHP Error was encountered Severity: Notice Message: Undefined property: Test::$load Fi ...
- .NET Core下使用gRpc公开服务(SSL/TLS)
一.前言 前一阵子关于.NET的各大公众号都发表了关于gRpc的消息,而随之而来的就是一波关于.NET Core下如何使用的教程,但是在这众多的教程中基本都是泛泛而谈,难以实际在实际环境中使用,而该篇 ...
- 设计模式之美:Interpreter(解释器)
索引 意图 结构 参与者 适用性 效果 相关模式 实现 实现方式(一):Interpreter 模式结构样式代码. 实现方式(二):解释波兰表达式(Polish Notation). 意图 给定一个语 ...
- iOS——自定义Segue实现总结
在阅读了iOS 8自定义动画转场上手指南后,刚开始不理解,后来慢慢消化了,现在总结如下: 1. 自定义Segue关键在于继承UIStoryboardSegue并重写perform方法 2. 动画可以在 ...
- Js~动态判断PC和手机浏览器
这个只是一个小知识,也是在网上找的,挺好用! 动态判断浏览器是PC还是移动端! <script> var browser={ versions:function(){ var u = na ...
- Python学习--06切片
Python里提供了切片(Slice)操作符获取列表里的元素. 示例: >>> L = [1,2,3,4,5] # 取前2个元素,传统方法 >>> [L[0],L[ ...