使用 ENUMMAP 替代序数索引
import java.util.Arrays;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; public class Herb {
public enum Type {
ANNUAL, PERENNTAL, BIENNIAL
} private final String name;
private final Type type; Herb(String name, Type type) {
this.name = name;
this.type = type;
} @Override
public String toString() {
return name;
} public static void main(String[] args) {
// 将集合放到一个按照类型的序数进行索引的数组中来实现 替换
Herb[] garden = { new Herb("一年生1", Type.ANNUAL), new Herb("一年生2", Type.ANNUAL), new Herb("两年生1", Type.BIENNIAL),
new Herb("两年生2", Type.BIENNIAL), new Herb("多年生1", Type.PERENNTAL), new Herb("多年生2", Type.PERENNTAL) }; // @SuppressWarnings("unchecked")//产生泛型数组,且手工操作索引
// Set<Herb>[] herbsByType = (Set<Herb>[]) new Set[Herb.Type.values().length];
// for (int i = 0; i < herbsByType.length; i++) {
// herbsByType[i] = new HashSet<Herb>();
// }
// for (Herb h : garden) {
// herbsByType[h.type.ordinal()].add(h);
// //System.out.println(h.type);
// }
// for (int i = 0; i < herbsByType.length; i++) {
// System.out.printf("%s: %s%n", Herb.Type.values(), herbsByType[i]);
// } Map<Herb.Type, Set<Herb>> herbsByType = new EnumMap<Herb.Type, Set<Herb>>(Herb.Type.class);
for (Herb.Type t : Herb.Type.values()) {
herbsByType.put(t, new HashSet<Herb>());
}
for (Herb h : garden) {
herbsByType.get(h.type).add(h);
}
System.out.println(herbsByType); //如果采用的是stream
long startTime = System.currentTimeMillis();
// 这段代码的问题在于,它选择了自己的 map 实现,而实际上它不是 EnumMap,所以它不会将版本的空间和时间性能与显式 EnumMap 匹配。
System.out.println(Arrays.stream(garden).collect(Collectors.groupingBy(p -> p.type)));
long endTime = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime - startTime) + "ms");
结果:{PERENNTAL=[多年生1, 多年生2], ANNUAL=[一年生1, 一年生2], BIENNIAL=[两年生1, 两年生2]}
程序运行时间:45ms
// 要纠正这个问题,可以使用 Collectors.groupingBy 的三参数形式,它允许调用者使用 mapFactory 参数指定 Map 实现:
long startTime2 = System.currentTimeMillis();
System.out.println(Arrays.stream(garden)
.collect(Collectors.groupingBy(p -> p.type, () -> new EnumMap<>(Type.class), Collectors.toSet())));
long endTime2 = System.currentTimeMillis();
System.out.println("程序运行时间:" + (endTime2 - startTime2) + "ms");
}
}
结果: {ANNUAL=[一年生2, 一年生1], PERENNTAL=[多年生1, 多年生2], BIENNIAL=[两年生2, 两年生1]}
程序运行时间:1ms
使用 ENUMMAP 替代序数索引的更多相关文章
- Effective Java 第三版——37. 使用EnumMap替代序数索引
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- 用EnumMap代替序数索引
用EnumMap代替序数索引 有时候,会见到利用ordinal方法来索引数组的代码.例如下面这个简化的类,表示一种烹饪用的香草: public class Herb { public enum T ...
- 【Effective Java】9、使用EnumMap代替序数索引
package cn.xf.cp.ch02.item33; import java.util.EnumMap; import java.util.HashSet; import java.util.M ...
- 第33条:用EnumMap代替序数索引
有时候,会见到利用ordinal方法来索引数组的代码.例如下面这个简化的类,表示一种烹饪用的香草: public class Herb { public enum Type { ANNUAL, PER ...
- Effective Java 第三版——35. 使用实例属性替代序数
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- effective-java学习笔记---使用实例属性替代序数35
永远不要从枚举的序号中得出与它相关的值; 请将其保存在实例属性中: public enum Ensemble { SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUIN ...
- 《Effective Java 第三版》目录汇总
经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...
- Effective.Java第34-44条(枚举)
34. 使用枚举类型替代整型常量 常量的语义表达不清晰,只能靠前面的名称来区分.枚举具有可读性.更安全.更强大等优势.而且枚举类型对象之间的值比较可以使用==来比较值是否相等的,不是必须使用equa ...
- [Effective Java 读书笔记] 第6章 枚举和注解
第三十条 用enum代替int 总得来说,使用enum有几点好处 1.编译时的类型安全, 2.可以保证就是自己定义的值,不会有月结风险, 3.每个枚举类型有自己的命名空间 4.枚举可以添加任意的方法和 ...
随机推荐
- Python 测试代码 初学者笔记
单元测试 每完成一个单元测试,Python都会打印一个字符: 测试通过打印一个句点:测试引发错误打印E:测试导致断言失败打印F 模块unittest import unittest from name ...
- openlayers画区域
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- gulp常用插件之gulp-size使用
更多gulp常用插件使用请访问:gulp常用插件汇总 gulp-size这是一款显示项目的大小插件. 更多使用文档请点击访问gulp-size工具官网. 安装 一键安装不多解释 npm install ...
- bugku-sql注入2(学习到有用的东西)
这道题只能说坑啊,特别是最后找密码参数那里,真的是磕磕碰碰啊... 但是做完题的整个过程还是学到了很多有用的技巧. 直接来吧: 看了下提示,真的是全都过滤了吗,点进去是一个登录页面 哎,又是一个pos ...
- vue项目中使用element ui上传图片到七牛
1.获取token值 后台有接口调用直接返回token值 //请求后台拿七牛云token async getQiniuToken() { //token let uploadtoken = await ...
- 错误 CS8107 C# 7.0 中不支持功能“xxxxxx”。请使用 7.1 或更高的语言版本。
解决方法:项目右键属性 —> 生成 —> 找到最下面的高级按钮,点击高级按钮 —> 常规 —> 语言版本 —> 选择 C#最新次要版本,或者比当前版本更高的版本即可,点击 ...
- Codeforces Round #624 (Div. 3) F. Moving Points 题解
第一次写博客 ,请多指教! 翻了翻前面的题解发现都是用树状数组来做,这里更新一个 线段树+离散化的做法: 其实这道题是没有必要用线段树的,树状数组就能够解决.但是个人感觉把线段树用熟了会比树状数组更有 ...
- Conference deadlines
1. NLP/IR/DM/ML Conference Deadlines(Updating) Two Principles of Deadlines:1. All deadlines converge ...
- 题解 P1056 【排座椅】
题目地址:https://www.luogu.com.cn/problem/P1056 题解原地址:https://createsj.blog.luogu.org/solution-p1056 由于题 ...
- Python原来这么好学-1.3节: 知识要点总结与内容复习
这是一本教同学们彻底学通Python的高质量学习教程,认真地学习每一章节的内容,每天只需学好一节,帮助你成为一名卓越的Python程序员: 本教程面向的是零编程基础的同学,非科班人士,以及有一定编 ...