使用 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.枚举可以添加任意的方法和 ...
随机推荐
- JS DOM属性+JS事件
DOM属性 console.log(ele.attributes) 获取ele元素的属性集合 ele.attributes.getNamesItem(attr).nodeValue 获取指定属性值 e ...
- win10c盘被下满文件解决办法
今天更新系统,发现一个巨坑,好不容易软件配置的环境,开始以为是病毒,重装后在弄发现还是这个问题.经过两天的亲测解决办法: win7 svchost.exe占用内存和CPU很高,电脑很卡的解决方法:ht ...
- 按钮控制彩灯实验 CSU - 1770 树状数组 差分变单点修改
#include<iostream> #include<algorithm> #include<cstring> using namespace std; ; in ...
- JVM的小理解
1.开发人员编写Java代码(.java文件),然后将之编译成字节码(.class文件),再然后字节码被装入内存,一旦字节码进入虚拟机,它就会被解释器解释执行,或者是被即时代码发生器有选择的转换成机器 ...
- PHP Files functions
simple functions <?php $docRoot = $_SERVER['DOCUMENT_ROOT']; //readfile($docRoot."/orders/or ...
- UI中class的用法:
easyui的引入:<link rel="stylesheet" type="text/css" href="easyui/themes/def ...
- Python中numpy模块的简单使用
# encoding:utf-8 import numpy as np data1 = np.array([1, 2, 3, 4, 5]) print(data1) data2 = np.array( ...
- C#调用WSDL接口
http://www.cnblogs.com/wlming/p/8032782.html
- [CF994B] Knights of a Polygonal Table - 贪心,堆
有 n 个骑士想决战.每个骑士都有能力值(互不相同),且身上带有一些金币.如果骑士 A 的能力值大于骑士 B ,那么骑士 A 就可以杀死骑士 B ,并获得骑士 B 身上的所有金币.但就算是骑士也不会残 ...
- execute、executeUpdate、executeQuery的区别
链接:https://blog.csdn.net/u012501054/article/details/80323176 链接:https://blog.csdn.net/CNAHYZ/article ...