巧妙利用JDK1.8新特性解决多if判断及其性能测试
2016-07-30 17:13
585 查看
先说说场景,最近接第三方的足球走地数据,需要将这些数据入库,设计到一个足球的eventType的整理,我们自己的库中有一套我们自己的eventType,这些eventType包括进球,红黄牌等事件。第三方数据可能将两个队的进球事件分开成HomeGoal和AwayGoal事件,而在我们的库中将这两个事件合并成一个事件Goal。
将第三方的事件对应到我们自己库中的事件,在解决方式上你可能想到的第一个方法是使用if或者switch case,或者某种设计模式。我想说这些方式都不可取,先说if和switch case,eventType种类太多,当前有20多种,还不能保证以后只减不增,用if或者switch case,你确定你要写20++种if或case判断吗?再说使用设计模式,使用策略模式?不管使用何种设计模式,面对20++种eventType,需要20++个类,还要随着以后eventType的动态增加来随时增加类,随时维护代码。违背原则。
那是不是就要问了,那有什么好的解决方案呢?我建议的解决方案是使用enum+jdk1.8新特性。前提是你的项目使用了jdk1.8哦。
enum类可以这样定义:
使用jdk1.8新特性中的stream().filter()结合lamda表达式,可以这样处理。直接返回MatchEventType中的name属性,即返回我们自己的这一套eventType。
我做了一个简单的性能测试:
咱既然选择了使用jdk1.8,那么也要明白jdk1.8相对于其他的版本来说有什么新的特性功能,试着去使用它们,给自己带来方便,会有意想不到的效果。
将第三方的事件对应到我们自己库中的事件,在解决方式上你可能想到的第一个方法是使用if或者switch case,或者某种设计模式。我想说这些方式都不可取,先说if和switch case,eventType种类太多,当前有20多种,还不能保证以后只减不增,用if或者switch case,你确定你要写20++种if或case判断吗?再说使用设计模式,使用策略模式?不管使用何种设计模式,面对20++种eventType,需要20++个类,还要随着以后eventType的动态增加来随时增加类,随时维护代码。违背原则。
那是不是就要问了,那有什么好的解决方案呢?我建议的解决方案是使用enum+jdk1.8新特性。前提是你的项目使用了jdk1.8哦。
enum类可以这样定义:
<span style="font-size:18px;">import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.zhangyu.databus.core.enums.MatchEventType; import com.zhangyu.databus.fetch.enums.BetgeniusSports; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; /** * Created by zhudan on 2016/7/26. */ public enum BetgeniusEventType { ALL(-1, "全部",MatchEventType.ALL), AWAY_GOAL(0, "AwayGoal",MatchEventType.SCORE), AWAY_PENALTY(1, "AwayPenalty",MatchEventType.PENALTY), AWAY_DANGEROUS_FREEKICK(2, "AwayDangerousFreeKick",MatchEventType.DANGEROUS_FREE_KICK), AWAY_CORNER(3, "AwayCorner",MatchEventType.CORNER), AWAY_ATTACKING_FREEKICK(4, "AwayAttackingFreeKick",MatchEventType.DANGEROUS_FREE_KICK), AWAY_DANGEROUS_ATTACK(5, "AwayDangerousAttack",MatchEventType.DANGEROUS_ATTACK), AWAY_CORNER_DANGER(6, "AwayCornerDanger",MatchEventType.DANGEROUS_CORNER), AWAY_ATTACK(7, "AwayAttack",MatchEventType.ATTACK), AWAY_FREEKICK(8, "AwayFreeKick",MatchEventType.FREE_KICK), AWAY_SAFE(9, "AwaySafe",MatchEventType.BALL_SAFE), SAFE(10, "Safe",MatchEventType.BALL_SAFE), HOME_SAFE(11, "HomeSafe",MatchEventType.BALL_SAFE), HOME_FREEKICK(12, "HomeFreeKick",MatchEventType.FREE_KICK), HOME_ATTACK(13, "HomeAttack",MatchEventType.ATTACK), HOME_CORNER_DANGER(14, "HomeCornerDanger",MatchEventType.DANGEROUS_CORNER), HOME_DANGEROUS_ATTACK(15, "HomeDangerousAttack",MatchEventType.DANGEROUS_ATTACK), HOME_ATTACKING_FREEKICK(16, "HomeAttackingFreeKick",MatchEventType.DANGEROUS_FREE_KICK), HOME_CORNER(17, "HomeCorner",MatchEventType.CORNER), HOME_DANGEROUS_FREEKICK(18, "HomeDangerousFreeKick",MatchEventType.DANGEROUS_FREE_KICK), HOME_PENALTY(19, "HomePenalty",MatchEventType.PENALTY), HOME_GOAL(20, "HomeGoal",MatchEventType.SCORE), YELLOWCARDDANGER(21, "YellowCardDanger",MatchEventType.POSSIBLE_YELLOW_CARD), //TODO AWAY_SAFE_FREEKICK(22, "AwaySafeFreeKick",MatchEventType.FREE_KICK), HOME_SAFE_FREEKICK(23, "HomeSafeFreeKick",MatchEventType.FREE_KICK); private static Logger logger = LoggerFactory.getLogger(BetgeniusSports.class); private static final Object _LOCK = new Object(); private static Map<Integer, BetgeniusEventType> _MAP; private static Map<String, BetgeniusEventType> _NAME_MAP; private static Map<String, BetgeniusEventType> _STATE_MAP; private static List<BetgeniusEventType> _LIST; private static List<BetgeniusEventType> _ALL_LIST; static { synchronized (_LOCK) { Map<Integer, BetgeniusEventType> map = new HashMap<>(); Map<String, BetgeniusEventType> nameMap = new HashMap<>(); Map<String,BetgeniusEventType> stateMap=new HashMap<>(); List<BetgeniusEventType> list = new ArrayList<>(); List<BetgeniusEventType> listAll = new ArrayList<>(); for (BetgeniusEventType item : BetgeniusEventType.values()) { map.put(item.getValue(), item); nameMap.put(item.getName(), item); listAll.add(item); if (!item.equals(ALL)) { list.add(item); } } _MAP = ImmutableMap.copyOf(map); _NAME_MAP = ImmutableMap.copyOf(nameMap); _STATE_MAP=ImmutableMap.copyOf(stateMap); _LIST = ImmutableList.copyOf(list); _ALL_LIST = ImmutableList.copyOf(listAll); } } private int value; private String name; private MatchEventType matchEventType; BetgeniusEventType(int value, String name, MatchEventType matchEventType) { this.value = value; this.name = name; this.matchEventType=matchEventType; } public String getName() { return name; } public int getValue() { return value; } public MatchEventType getMatchEventType(){ return matchEventType; } public static BetgeniusEventType get(int value) { try { return _MAP.get(value); } catch (Exception e) { logger.error(e.getMessage(), e); return null; } } public static BetgeniusEventType getByName(String name) { try { return _NAME_MAP.get(name); } catch (Exception e) { logger.error(e.getMessage(), e); return null; } } public static List<BetgeniusEventType> list() { return _LIST; } public static List<BetgeniusEventType> listAll() { return _ALL_LIST; } public static Map<String, BetgeniusEventType> getBetgeniusStateMap(){ return _STATE_MAP; } }</span>拿AWAY_GOAL(0,"AwayGoal",MatchEventType.SCORE)进行说明,0不用说,仅仅是个序号,"AwayGoal"是第三方数据的eventType,MatchEventType.SCORE是我们自己的一套eventType,enum类中的listAll和list方法,分别返回不同结构的list,其中我使用到了listAll方法,接着往下看。
使用jdk1.8新特性中的stream().filter()结合lamda表达式,可以这样处理。直接返回MatchEventType中的name属性,即返回我们自己的这一套eventType。
<span style="font-size:18px;">BetgeniusEventType.listAll().stream(). filter((s) -> s.getName().equals("AwayGoal")). findFirst().get().getMatchEventType().getName()</span>那这同普通的在for循环下取值然后进行if判断有什么优势呢?
我做了一个简单的性能测试:
<span style="font-size:18px;">public static void main(String[] args) { long foreachstart = System.currentTimeMillis(); for (BetgeniusEventType type:BetgeniusEventType.listAll() ) { if(type.getName().equals("AwaySafe")){ System.out.println(type.getName()); } } long foreachend = System.currentTimeMillis(); System.out.println(foreachstart-foreachend); long filterstart=System.currentTimeMillis(); System.out.println(BetgeniusEventType.listAll().stream(). filter((s) -> s.getName().equals("AwaySafe")). findFirst().get().getName()); long filterend=System.currentTimeMillis(); System.out.println(filterstart-filterend); }</span>测试结果如下:
咱既然选择了使用jdk1.8,那么也要明白jdk1.8相对于其他的版本来说有什么新的特性功能,试着去使用它们,给自己带来方便,会有意想不到的效果。
相关文章推荐
- JDK动态代理VS CgLib
- Java IO与NIO的一些文件拷贝测试
- Ubuntu 安装 JDK 问题
- 推荐六款WEB上传组件性能测试与比较第1/10页
- C#代码性能测试类(简单实用)
- asp 性能测试报告 学习asp朋友需要了解的东西
- 使用console进行性能测试
- jdk与jre的区别 很形象,很清晰,通俗易懂
- jdk中String类设计成final的原由
- win7下安装 JDK 基本流程
- jdk环境变量配置
- win2003 jsp运行环境架设心得(jdk+tomcat)
- windows linux jdk安装配置方法
- Java编程之jdk1.4,jdk1.5和jdk1.6的区别分析(经典)
- 详解JDK 5 Annotation 注解之@Target的用法介绍
- PHP框架性能测试报告
- 简单记录Cent OS服务器配置JDK+Tomcat+MySQL
- Android开发的IDE、ADT、SDK、JDK、NDK等名词解释
- Java4Android开发教程(一)JDK安装与配置
- 1亿条记录的MongoDB数据库随机查询性能测试