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 替代序数索引的更多相关文章

  1. Effective Java 第三版——37. 使用EnumMap替代序数索引

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  2. 用EnumMap代替序数索引

    用EnumMap代替序数索引   有时候,会见到利用ordinal方法来索引数组的代码.例如下面这个简化的类,表示一种烹饪用的香草: public class Herb { public enum T ...

  3. 【Effective Java】9、使用EnumMap代替序数索引

    package cn.xf.cp.ch02.item33; import java.util.EnumMap; import java.util.HashSet; import java.util.M ...

  4. 第33条:用EnumMap代替序数索引

    有时候,会见到利用ordinal方法来索引数组的代码.例如下面这个简化的类,表示一种烹饪用的香草: public class Herb { public enum Type { ANNUAL, PER ...

  5. Effective Java 第三版——35. 使用实例属性替代序数

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. effective-java学习笔记---使用实例属性替代序数35

    永远不要从枚举的序号中得出与它相关的值; 请将其保存在实例属性中: public enum Ensemble { SOLO(1), DUET(2), TRIO(3), QUARTET(4), QUIN ...

  7. 《Effective Java 第三版》目录汇总

    经过反复不断的拖延和坚持,所有条目已经翻译完成,供大家分享学习.时间有限,个别地方翻译得比较仓促,希望有疑虑的地方指出批评改正. 第一章简介 忽略 第二章 创建和销毁对象 1. 考虑使用静态工厂方法替 ...

  8. Effective.Java第34-44条(枚举)

    34.  使用枚举类型替代整型常量 常量的语义表达不清晰,只能靠前面的名称来区分.枚举具有可读性.更安全.更强大等优势.而且枚举类型对象之间的值比较可以使用==来比较值是否相等的,不是必须使用equa ...

  9. [Effective Java 读书笔记] 第6章 枚举和注解

    第三十条 用enum代替int 总得来说,使用enum有几点好处 1.编译时的类型安全, 2.可以保证就是自己定义的值,不会有月结风险, 3.每个枚举类型有自己的命名空间 4.枚举可以添加任意的方法和 ...

随机推荐

  1. Android studio中修改xml文件无效问题

    昨天遇到的这个问题,在修改布局xml文件后保存,但运行时布局却并没有被修改,也就是说我的修改无效,今天参照了这篇文章中的方法终于解决了: https://blog.csdn.net/l_o_s/art ...

  2. BZOJ 4238: 电压 DFS树

    分类讨论一下奇环和偶环的情况. code: #include <bits/stdc++.h> #define N 200006 #define setIO(s) freopen(s&quo ...

  3. #4864. [BeiJing 2017 Wc]神秘物质 [FHQ Treap]

    这题其实挺简单的,有个东西可能稍微难维护了一点点.. \(merge\ x\ e\) 当前第 \(x\) 个原子和第 \(x+1\) 个原子合并,得到能量为 \(e\) 的新原子: \(insert\ ...

  4. PAT 基础编程题目集 6-7 统计某类完全平方数 (20 分)

    本题要求实现一个函数,判断任一给定整数N是否满足条件:它是完全平方数,又至少有两位数字相同,如144.676等. 函数接口定义: int IsTheNumber ( const int N ); 其中 ...

  5. RSA学习档案

    RSA 学习档案 基本原理 随机选择两个质数p,q模数n=p*qφ(n)=(p−1)(q−1)选择加密指数e: 1 < e < φ(n)计算机密指数d: e*d % φ(n) = 1c = ...

  6. JavaScript 13 Ajax技术(未完)

    <body> <!-- 添加文档主体内容 --> <header> <nav>JavaScript - Ajax - 读取XML文件</nav&g ...

  7. C++&C语言 -> //有一头母牛,它每年年初生一头小母牛。每头小母牛从第四个年头开始,每年年初也生一头小母牛。请编程实现在第n年的时候,共有多少头母牛?

    /*    a                  b                          c       d 1  5                   5               ...

  8. Linux虚拟化 xen的工具栈介绍

    试验环境centos6.10 xen的工具栈介绍: 查看xl目录的帮助:xl help 查看xen下安装了哪些虚拟机:xl list # xl list Domain-0 Name ID Mem VC ...

  9. Oracle 中的 Incarnation 到底是个什么?概念理解篇

    高中时候,我深深“爱”上了一位女孩子.那个年纪确实不懂什么是真正的“爱”,反正每天满脑子都是她,只要见到她就会紧张和激动,确切的说是深深的喜欢.你告诉我这叫初恋?不,我的初恋应该是小学3年级,三六班. ...

  10. java 学习(day1)

    之前学java没好好听课,会一点又不熟练,于是准备重新开始学一些细节,记录每日所学新知识. a+b java的a+b很有意思,当你输出的是" "+a+b,先假设a=2,b=3.然后 ...