`
ajoo
  • 浏览: 452759 次
社区版块
存档分类
最新评论

瓜娃之走马观花 (1) - List和Map

阅读更多


花开花落,花落花开。少年子弟江湖老,红颜少女的儿子都会打酱油反三俗了.

蓦然回首, 那个仿佛刚刚还在上幼儿园, 拉着我的手让我带着到麦当劳买鸡块冰激凌吃的小屁孩儿; 上了小学, 抱着我给买的盗版commando苦苦钻研攻略的小表弟, 开始写java程序了!

暑假去小表弟学校宿舍晃了一下. 书桌上随手堆着的可乐矿泉水瓶; 书桌下凌乱的鞋子, 鼠标; 寝室门上的个性标语; 隔壁在炎夏里半裸着看片子(木有看清是女主是否半裸)的猥琐男生, 都让俺情不自禁地小资起来: 唉, 世界是你们的了!

唯一地遗憾是没有重温一下女生寝室的风光 --- 上了年纪了, jailbreak门口大妈的身手不再了呀!

小兄弟是个努力的好童鞋. 于是咱自然当仁不让开始介绍UML, SOA, 4GL, J2EE, Agile Programming, JSR168X --- 噢, 不好意思, 又不小心yy了, 俺是粗淫, 这些说实话不懂地.

咳嗽, 是介绍JUnit, TDD, 和瓜娃 --- 就是Google Collection的重装上阵: Guava.


一. ListsMaps

介绍瓜娃主要是觉得它是个老老实实的能帮助写代码的工具库. 不用把它当作正儿八经的什么东西学习 (说实话, 那里面的东西俺估计也就接触过两成了不起了), 把那个jar文件放到你的classpath里, 然后哪怕你就知道一个库函数呢, 对景的时候也是个帮手啊.

比如, 最简单地, 用java5以上的话(2010年了, 还在用上古神器jdk1.3或者1.4的首长请举手. 敬礼! 首长辛苦了!), 你怎么new一个ArrayList呢? 这样吧?

List<String> list = new ArrayList<String>();


怎么new一个HashMap呢? 是不是这样?
Map<String, Integer> map = new HashMap<String, Integer>();


对俺们这些用惯了瓜娃的懒人, 写那个<>里面的东东两次就觉得累得慌, 除非一些特殊的场合不想依赖瓜娃的jar文件的, 俺们一般都改写成:

List<String> list = Lists.newArrayList();

Map<String, Integer> list = Maps.newHashMap();


Lists和Maps是两个工具类, Lists.newArrayList()其实和new ArrayList()几乎一模一样, 唯一它帮你做的(其实是javac帮你做的), 就是自动推导(不是"倒")尖括号里的那坨叉叉.

这两个东西要说技术含量, 附加价值差不多趋近于0. 但是越是这种简单的不用脑子的东西, 越是让人惊讶地有邪异的吸引力. 我就看过好几个人说, 他们使用瓜娃的主要目的, 就是newArrayList()和newHashMap(). 毕竟, 这东西每个人每时每刻差不多都要用到吧?

当然, 瓜娃提供的远不止这两毛五, 买一根小豆冰棍儿都不够. 比如, 除了new一个空的ArrayList, 你还想往里放点数据. 直接用jdk的话, 大概是这样:

List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);


用Lists是这样:
List<Integer> list = Lists.newArrayList(1, 2, 3);


嗯, 是不是有点意思了? 值一个"可爱多"了吧?


二. ImmutableListImmutableMap

现在主流java社区倾向于同意, immutable对象(就是说状态不变)是个好东西. 它能让程序逻辑变得简单易懂, 而且减少出错的可能性.

JDK目前不提供immutable集合. 瓜娃提供的最主要的immutable集合, 是ImmutableList, ImmutableSet和ImmutableMap.
顾名思义, 一旦你创建了一个ImmutableList或者ImmutableMap, 你就再也不能改变它了. 它就像你记忆中初恋的那个她, 不管时光荏苒, 沧海桑田, 永远年轻美丽语笑嫣然 --- 当然, 前提是你还活着.

那么怎么创建ImmutableList呢? 嗯, 除非语言直接提供支持, 这应该是最简单的方式了:
ImmutableList<Integer> list = ImmutableList.of(1, 2, 3);

ImmutableMap一样简单:
ImmutableMap<String, Integer> map = ImmutableMap.of(
    "1", 1,
    "2", 2,
    "3", 3
);


对比一下用HashMap的情况:

Map<String, Integer> map = new HashMap<String, Integer>();
map.put("1", 1);
map.put("2", 2);
map.put("3", 3);



还是前者舒服吧?

那么, 假设你所有的不是事先知道的一些常量. 比如说, 你要从一个数据库里读出一些基本信息保存在内存里. 用of()就不好使了, 这时候, 可以用builder模式:
ImmutableMap.Builder<String, Integer> builder = ImmutableMap.builder();
for (...) {
  builder.put(name, age);
}
ImmutableMap<String, Integer> map = builder.build();


ImmutableList和ImmutableMap最常用的就是创建一些集合常量 (这些常量都是static final的).

另外一个主要的用途, 是作为其它Immutable对象内部使用的数据结构.


三. 讨论

一个也许会存在争议, 但是瓜娃开发组强烈推荐的使用方法, 是凡是可能的情况下, 给你的函数的返回类型用ImmutableList和ImmutableMap, 而不是它们实现的接口: List和Map. 比如:

ImmutableList<String> getNames();
ImmutableMap<String, Integer> getAgeMap();

而不是:
List<String> getNames();
Map<String, Integer> getAgeMap();


为什么这样呢? 这是因为immutable集合是一类特殊集合, 它们不象ArrayList, HashMap那样是纯粹的实现细节, 相反, 这些类型携带了重要的语义信息: 它们是不可变的.

如果调用者使用了list.add()或者map.put(), 得到的将是UnsupportedOperationException异常.

通过返回ImmutableMap和ImmutableList, 函数签名清楚地告诉调用者什么可以做, 什么不可以做. 这对大型程序中团队协作, 代码理解和维护好处多多.

实际上, 最有争议的, 是在jdk的集合框架设计上. Sun把List和Map的接口设计为mutable(可变的), 但是同时允许实现类不实现某些函数, 比如add(), put(). 一些貌似爱思考地程序员(包括俺)就想啦: 为啥你不干脆把写操作分离出来呢? 这样当一个人拿到ImmutableList的时候, 他根本就没有add()可以调用, 更甭说运行时抛异常了?

Sun对此专门有个回答. 是否信服就由你了. 不过不管喜不喜欢, 我们今天所有的就是这个设计: 一个List可能是可变的也可能是不可变的. 大概还是不要钻牛角尖, 入乡随俗吧.

未完待续
31
3
分享到:
评论
12 楼 Tyrion 2013-01-04  
我就喜欢看这种轻松幽默的技术文章
11 楼 huang_yong 2010-11-25  
Guava非常值得学习,感谢ajoo精彩的讲解!
10 楼 Javakeith 2010-11-13  
希望LZ继续独特的神笔!
9 楼 tamsiuloong 2010-08-20  
对后面的用法不怎么感冒  反而前一段叙事还不错。
8 楼 ajoo 2010-08-14  
mercyblitz 写道
ajoo 写道
区别还是有的.
3. "unmodifiable"不等于immutable. 它只是一个view. 这个集合还是可能改变的. 比如:
List<Integer> list = new ArrayList<Integer>();
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
// unmodifiableList是空
list.add(1);
// unmodifiableList里面有1了.


所以不能保证immutable.



嗯,修改UnmodifiableList的底层List是可以改变内部的对象。

immutable难道是复制集合元素,然后不再被修改?

是的. ImmutableList做了一个defensive copy. 而且它不允许null.

往好的方面想, 这样你每一次遍历或者get()都比一个藏在unmodifiableList内部的一个藏在synchronizedList内部的ArrayList快.

而且ImmutableList作为一个类型名字, 可以让代码里什么可改什么不可改清清楚楚.
7 楼 ajoo 2010-08-14  
ZHH2009 写道
Java7可以这么玩了:

旧的方式:Map<String, Integer> map = new HashMap<String, Integer>();

新的方式:Map<String, Integer> map = new HashMap<>();

貌似新的语法比这个还少敲几个字符啊:

Map<String, Integer> map = Maps.newHashMap();
====================================================对比下长度
Map<String, Integer> map = new HashMap<>()


:shock: 

没错. 等java7上市, Maps和Lists就都可以安息了.

而且, 如果传说中的closure真的出现, 那个代表了落后生产力的Function以及Predicate也都去死吧!

其实, 对java7这个语法, 俺还是有所不满. 为啥不是
Map<String, Integer> map = new HashMap();

?

为了向后兼容1.4吗? 现在还真有神仙在用1.4?
6 楼 mercyblitz 2010-08-14  
ajoo 写道
区别还是有的.
3. "unmodifiable"不等于immutable. 它只是一个view. 这个集合还是可能改变的. 比如:
List<Integer> list = new ArrayList<Integer>();
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
// unmodifiableList是空
list.add(1);
// unmodifiableList里面有1了.


所以不能保证immutable.



嗯,修改UnmodifiableList的底层List是可以改变内部的对象。

immutable难道是复制集合元素,然后不再被修改?
5 楼 ZHH2009 2010-08-14  
Java7可以这么玩了:

旧的方式:Map<String, Integer> map = new HashMap<String, Integer>();

新的方式:Map<String, Integer> map = new HashMap<>();

貌似新的语法比这个还少敲几个字符啊:

Map<String, Integer> map = Maps.newHashMap();
====================================================对比下长度
Map<String, Integer> map = new HashMap<>()


:shock: 
4 楼 ajoo 2010-08-13  
嗯. 俺不作evil很久了. 低调, 低调啊. 
3 楼 denis 2010-08-13  
今天打开greader,突然发现了一个熟悉的名字:ajoo,才发现时间实在是过的够快的,ajoo童鞋闭关很久了吧?文笔依旧很神器,哈哈。
2 楼 ajoo 2010-08-12  
区别还是有的.

1. UnmodifiableList不是公开的. 没法用.
2. UnmodifiableList不存在象of()这些方便使用的函数. 而guava的主要作用就是简化代码.
3. "unmodifiable"不等于immutable. 它只是一个view. 这个集合还是可能改变的. 比如:
List<Integer> list = new ArrayList<Integer>();
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
// unmodifiableList是空
list.add(1);
// unmodifiableList里面有1了.


所以不能保证immutable.
1 楼 mercyblitz 2010-08-12  
博主说的有道理,不过这些东西JDK早就有了,只是没有暴露出来。

比如java.util.Collections.UnmodifiableList

相关推荐

    第1讲-引论-走马观花看导论.pptx

    第1讲-引论-走马观花看导论.pptx

    单片机实例-走马观花

    【单片机实例-走马观花】是一个适合初学者的实践项目,旨在通过一个具体的走马灯(或称为流水灯)实验,帮助学习者掌握单片机的基础操作和编程技巧。走马灯通常指的是LED灯按照特定顺序依次点亮或熄灭,形成流动的...

    关于走马观花灯的单片机实训报告概要.pdf

    走马观花灯是一种常见的灯光装饰,通过编程和控制能够实现多样的动态效果。这篇实训报告主要探讨了基于单片机实现可调控走马灯的设计与实现过程,旨在提升学生对于单片机应用和硬件电路设计的理解。 首先,报告的...

    Java程序设计高晓黎走马观花看PPT教案学习.pptx

    这份名为"Java程序设计高晓黎走马观花看PPT教案学习.pptx"的学习材料似乎提供了关于Java核心概念的概览,包括程序结构、运行机制、GUI界面、JVM的工作原理和垃圾回收机制。 首先,Java程序的结构框架是理解任何编程...

    Flex从入门到实践——源代码(11章)

    Flex是Adobe公司开发的一种用于构建富互联网应用程序(RIA)的框架,主要基于ActionScript和MXML语言。这个压缩包文件包含的是"Flex从入门到实践"教程的源代码,共11章,提供了深入学习Flex开发的实战示例。通过这些...

    Nexys3学习手记3:硬件外设走马观花

    【Nexys3学习手记3:硬件外设走马观花】 在探索Nexys3开发板的硬件世界时,了解其结构和组件至关重要。Nexys3是一款基于Spartan-6 FPGA(XC6SLX16)的教育与实验平台,它拥有丰富的外设,便于学习和实践数字系统...

    八年级地理下册 第七章 第二节 澳门特别行政区的旅游文化特色 知识拓展 走马观花澳门博彩业素材 湘教版.doc

    八年级地理下册 第七章 第二节 澳门特别行政区的旅游文化特色 知识拓展 走马观花澳门博彩业素材 湘教版.doc

    leetcode小岛出水口-LeetCode:LeetCode走马观花

    01.两数之和 02.两数相加 03.无重复字符的最长子串 05.最长回文子串 06.Z字型变换 07.整数反转 08.字符串转换整数 09.回文数 10.正则表达式匹配 11.盛最多水的容器 12.整数转罗马数字 13.罗马数字转整数 14.最长公共...

    Proto3语言指南-简体中文版

    花了一个周末的时间把它走马观花的学习了一下,顺便将官方的指南翻译了出来,这个应该是最新的---其他地方还没发现有! 首先申明,哥们儿英语高中水平,借助了必应词典勉强将其意译了出来,如果你发现翻译中有纰漏,...

    丛台2019年事业编招聘考试真题及答案解析下载版(1).docx

    正确的顺序是3-2-1-5-4。 10. **逻辑推理**: - 第10题是逻辑推理题,所有甲属于乙,有些甲属于丙,所有乙属于丁,没有戊属于丁。不能推出的是"有些甲属于戊",因为没有戊属于丁,所以戊不可能通过乙间接属于甲。 ...

    阅读方法有哪些.docx

    #### 1. 翻阅一本书 - **定义**:这是一种快速浏览书籍内容的方法。 - **特点**:主要目的是了解书籍的基本结构和大概内容。 - **应用场景**: - 在图书馆寻找特定主题的资料时。 - 对某本书感兴趣但不确定是否...

    五年级上册,语文选择题.pdf

    这篇资料主要包含的是小学五年级上册语文的选择题,涵盖了词语理解、句子含义解析、诗词理解、阅读理解和语言艺术等多个方面。以下是对这些知识点的详细解释: 1. 文学理解: - "你们是吃饭长大的;也是读书长大的...

    小学教育必背成语归类大全.doc

    - 走马观花、手舞足蹈等成语描述了具体的动作和行为。 - 前俯后仰、奔走相告、跋山涉水则展现了人的活动和奋斗。 8. **描写人间情谊**: - 恩重如山、生死相依、肝胆相照等成语表达了深厚的情感联系和忠诚。 9....

    2014_2015句子练习——陈晖.ppt

    1. 成语填空: - 人声鼎沸:形容人群的声音嘈杂,像锅里的水烧开一样喧闹。 - 大名鼎鼎:形容名声非常大,广为人知。 - 天下奇观:指罕见而奇特的景象或事情。 - 走马观花:形容快速地看,没有仔细欣赏。 - ...

    江苏省泰州中学2019届高三语文第四次模拟试题含解析

    题目中通过比较“悠远”和“幽远”的区别、“记忆犹新”与“历历在目”的含义以及“浮光掠影”和“走马观花”的不同,引导学生选择最适合语境的词语。第二题是句子排序题,测试学生的语言逻辑和连贯性,需要将六个...

    三年级上册成语归类大全.doc

    【成语是中国传统文化中的瑰宝,它们以简洁的形式承载着丰富的哲理和文化内涵。这篇文档“三年级上册成语归类大全.doc”旨在帮助学生系统学习和掌握这些成语,按照不同的主题进行分类,以便更好地理解和应用。以下是...

    巴音郭楞事业编招聘2020年考试真题及答案解析打印版(1).docx

    “浅尝辄止”、“走马观花”、“浮光掠影”、“蜻蜓点水”等词语形象地描绘了早期海洋探索的局限性。 ### 知识点二:可再生能源 1. **知识点概述**: - 定义了可再生能源的概念:从自然界获取、可再生且对环境...

    小学生课外知识集锦.doc

    1. **描写人的品质**: - 平易近人:形容人态度谦和,容易接近。 - 持之以恒:指做事有恒心,坚持到底。 - 锲而不舍:形容有毅力,不断努力,不轻易放弃。 - 废寝忘食:形容工作或学习非常投入,忘记了吃饭和...

    小学成语归类大全_—精华版.doc

    小学成语是中华传统文化的重要组成部分,包含了丰富的智慧和人生哲理。这些成语被广泛应用于日常对话、写作和语文学习中,帮助孩子们理解复杂的情感、行为和情境。以下是对这些成语进行的详细分类及其含义: 1. ...

    乐都事业编招聘2017年考试真题及答案解析网友整理.docx

    ### 1. 投资与中国经济增长 - **主要观点**:投资仍然是推动中国经济增长的关键因素,但其性质已经发生变化。 - **变化趋势**: - 过去的投资往往受到地方政府的驱动。 - 当前的投资更多地由企业的利润水平和盈利...

Global site tag (gtag.js) - Google Analytics