你应该更新的Java知识
原文链接:http://www.blogbus.com/dreamhead-logs/236028457.html
你应该更新的Java知识之常用程序库(一)
你应该更新的Java知识之常用程序库(二)
你应该更新的Java知识之构建工具
你应该更新的Java知识之Observer
你应该更新的Java知识之集合初始化
你应该更新的Java知识之集合操作
你应该更新的Java知识之惰性求值
你应该更新的Java知识之Optional
你应该更新的Java知识之Optional高级用法
在传统的Java里,为了表示一个集合,我们常常会写出这样的代码:
public class People {private List people;public void setPeople(List people) {this.people = people;}public List getPeople() {return this.people;}...
}
严格说来,这样的代码存在缺陷。虽然貌似List被封装到People里,但实际上,这个List的引用却暴露在外面,这个类的用户可以轻松地拿到List的引用,随意修改。所以,下面是一种更严谨的写法:
public class People {private List people;public void setPeople(List people) {this.people.addAll(people);}@SuppressWarnings("unchecked")public List getPeople() {return (List)this.people.clone();} ...
}
这里的做法基本思路是,做一个副本,保证内部引用(这里的people)不会传播到外面。但在实际编写代码的时候,大多数人都不会这么做,能否意识到这样的问题只是一个方面,这样的代码写起来,也要比原来的那种写法麻烦得多。按照许多公司的做法,这种要求只能放到代码规范里,但无论如何,在程序世界里,人为规定永远是最容易忽略的约定。
不过,在真实世界中,即便是我们写的只是上面的最简单那种形式,却很少出现问题。原因何在呢?因为大多数情况下,我们编写这样程序的时候,会有一种隐形的约定,这个“List”是不变的。我们设置(set)完这个List之后,基本上不会留着它的引用在做任何操作;而得到(get)它之后,也基本上不会去修改它。
在这种情况下,我们使用的实际上是一个不变的List。既然是一个不变的List,那不如就更直接地把它表现出来。
Guava为我们提供了不变集合的概念,对应着各种具体类型,有ImmutableList、ImmutableSet,还有ImmutableMap。从名字上,我们不难看出它们的用法。
Guava不变集合的做法并不是另起炉灶,而是遵循了Java已有集合框架的约定。比如,通过查阅文档,我们不难发现,ImmutableList就是一个List,只不过使用这个“List”,只不过,当我们尝试调用诸如add、set之类试图修改集合的方法时,它会抛出异常。正是有了这样的基础,不变集合可以和很多已有的类库、框架配合在一起。
有了这个基础,我们把不变集合的概念应用于之前的代码,它就是下面这个样子:
public class People {private ImmutableList people;public void setPeople(ImmutableList people) {this.people = people;}public ImmutableList getPeople() {return this.people;} ...
}
这样一来,代码依然很简单,但是,意义却与从前完全不一样了。我们不必再为可能存在的隐忧顾虑了:一旦元素放到集合里,就不可能修改它了,因为它是不可变的。
对于使用这段代码的人来说,getter自不必说,如往常一样使用,setter也不费力。只是当做字面量使用的集合,我们已经在《你应该更新的Java知识之集合初始化》中讨论过了。如果要适配于现有程序库,把一个已有的List转成ImmutableList也不复杂,一个简单的copyOf方法就可以实现:
List existingPeople = ... ImmutableList immutablePeople = copyOf(existingPeople);
为了让讨论更完整,这里不得不提到另外一个不变接口的选择:Iterable。它是从Java 5开始进入JDK的一个接口:
public interface Iterable {Iterator iterator();
}
作为一个Java程序员,我们对Iterator简直再熟悉不过了,有了Iterator,我们就可以遍历一个集合。所以,在一些情况下,我们也可以使用Iterable表示一个不变集合。大多数Java已有的集合类都实现了这个接口。
既然它是JDK里的东西,为什么不把它优先推荐呢?原因有几个。最重要的一个原因在于我们熟知的Iterator,它有一个方法叫做remove,可能大多数Java程序员已经习惯性地忽略了这个方法,但它就在哪里,它是一个可以“改变”集合的方法,所以,从语义上说,它不是一个很好的选择。另外,从已有的代码习惯来说,很多程序员还是很喜欢用List、Set作为接口,所以,ImmutableList从心理上来说,更接近已有的习惯。剩下的一个点似乎不那么重要,有些代码真的需要使用到特定类型的接口。不过,就大多数代码而言,我们只是要得到的一个集合,做一些操作,而这些操作我们在《你应该更新的Java知识之集合操作》中做了一些讨论。
在函数式编程中,不变是提升程序稳定性一个很重要的概念。既然我们大多数情况下实际用到的是不变集合,那就不妨直接把它表现出来。
你应该更新的Java知识相关推荐
- 你应该更新的Java知识之常用程序库
些库有的解决了平时常见又重要的问题,有的则让Coding变得更惬意,值得全速跟进了解! 原文 在很多人眼中,Java已经是一门垂垂老矣的语言,但并不妨碍Java世界依然在前进.如果你曾离开Java,云 ...
- java 声明一个bus类_第11章 新特性 – 你应该更新的Java知识之Observer - Java 基础入门笔记...
作为一个Java程序员,不熟悉设计模式简直不好意思和人打招呼,而Observer模式可以说是位列最常用的设计模式之列,虽然有时候在具体代码里,它不一定叫这个名字,比如改头换面叫个Listener,但模 ...
- 8张图带你轻松温习Java知识
转载自 8张图带你轻松温习Java知识 1 字符串不变性 下面这张图展示了这段代码做了什么 [code ]String s = "abcd"; s = s.concat(&quo ...
- 最全面的Java面试题-----是你更好的掌握java知识
最全面的Java面试题-----是你更好的掌握java知识 目录 l 概念题--- 1 一. JAVA基础--- 1 1) 面向对象的特征--- 1 2) 什 ...
- 001 JAVA知识体系
JAVA知识体系 j2se 1.Java语言基础 具体包括:1.对象的初始化:2.继承时,对象的初始化过程:3.关于构造方法:4.有关public.private和protected:5.抽象类:6. ...
- 【Scala教程】如何在已掌握的Java知识基础上快速上手Scala?【个人学习记录】
如何在已掌握的Java知识基础上学习Scala 前言 正文开始! 1. 编译运行 2. 声明变量 3. 输出 4. 显式指定变量类型 5. 范围区间 6. 写入文本文件 7. 读取文本文件 8. if ...
- 万字 Java 知识地图助你成为 Offer 收割机
点击关注"码海" 右上角"设为星标"好文章送达比别人快 我相信这些读者或多或少都有一些 Java 基础,但由于看不到全貌,学了一段时间很容易迷失.所以我在寻思着 ...
- JAVA知识体系之多线程篇
目录 1.线程概述 1.1 线程的定义 1.2 多线程的优势 1.2.1 更多的处理器核心 1.2.2 更快的响应时间 1.3 多线程的挑战 1.3.1 上下文切换 1.3.2 死锁 1.3.3 资源 ...
- java知识体系-最新总结(2022版)
目录 Java面试总结 基础知识 Java概述 基础语法 面向对象 集合框架 IO流 网络编程 常用API 常用工具类库 单元测试 异常 日志 工具 IDEA Eclipse & STS Ma ...
最新文章
- 对《软件工程》第四章的理解
- Monkey基本使用(转载)
- 全球及中国铝拉丝润滑剂行业竞争格局及运营前景研究报告2021-2027年
- ALV TREE学习笔记
- Windows7 Credential Manage
- ARM中各始终之间的关系,FCLK HCLK PCLK的关系
- wikipedia_教职员工可以通过Wikipedia进行教学吗?
- Java逆序列化报错serialVersionUID不同
- ZetCode Java 教程
- 硬干货!一张图弄清楚在ESXi下如何进行网络抓包
- 中国大陆身份证正则表达式(严格验证省份和日期)
- Groovy 教程系列(一)-- Groovy 入门
- Linux后台运行程序
- 关于IDEA下载安装,jpcap与wincap的一些使用方法
- win10下安装deepin双系统的坑:安装完成一直黑屏进不去系统
- python四叶玫瑰数,任意位数自幂数寻找|Python练习系列[4]
- 【spark使用】4. Dataset转换算子使用
- Js数组里删除指定的元素(不是指定的位置)
- 海淘转运攻略之2017年黑色星期五海淘转运公司对比推荐
- Oracle 查询:一小时内、一天内、一周内等