一个简单的Java模板工具类(二)—简单表达式解析实现

以前写过一个, 用正则比较不高效, 所以用表达式解析方式又实现了一个, 练手.

以前的: http://my.oschina.net/haogrgr/blog/222349

现在的:

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 非常非常简单的模板实现
 * 
 * @author desheng.tu
 * @date 2015年6月23日 下午4:38:05
 *
 */
public class SimpleTmpl {

	public static void main(String[] args) {
		String t1 = "你好 $$name$$, 您的验证码是:$$code$$";
		String t2 = "你好 #{name}, 您的验证码是:${code}";

		Map<String, Object> param = MapBuilder.makeO("name", "haogrgr").build("code", "1314");
		for (int i = 0; i < 100; i++) {
			SimpleTempletUtil.render(t1, param);
			Templ.of(t2).render(param);
		}

		String result = "";
		long start = 0;

		start = System.currentTimeMillis();
		for (int i = 0; i < 100000; i++) {
			param.put("code", i);
			result = SimpleTempletUtil.render(t1, param);
		}
		System.out.println(System.currentTimeMillis() - start);
		System.out.println(result);

		start = System.currentTimeMillis();
		Templ templ = Templ.of(t2);
		for (int i = 0; i < 100000; i++) {
			param.put("code", i);
			result = templ.render(param);
		}
		System.out.println(System.currentTimeMillis() - start);
		System.out.println(result);

	}

}

abstract class Exp {

	abstract String resolve(Map<String, Object> context);

	static Exp of(String exp) {
		Objects.requireNonNull(exp);
		if (exp.startsWith("#{") || exp.startsWith("${")) {
			return new VarExp(exp);
		}
		return new StrExp(exp);
	}
}

class StrExp extends Exp {

	String value;

	StrExp(String exp) {
		this.value = exp;
	}

	@Override
	public String resolve(Map<String, Object> context) {
		return this.value;
	}

	@Override
	public String toString() {
		return "StrExp [value=" + value + "]";
	}

}

class VarExp extends Exp {

	String varName;
	String defaultValue;
	Boolean nullable = false;

	VarExp(String varName, String defaultValue, Boolean nullable) {
		this.varName = varName;
		this.defaultValue = defaultValue;
		this.nullable = nullable;
	}

	VarExp(String exp) {
		Objects.requireNonNull(exp);
		if (!(exp.startsWith("#{") || exp.startsWith("${")) || !exp.endsWith("}")) {
			throw new IllegalArgumentException("表达式[" + exp + "]必须类似于#{}或${}");
		}

		String[] nodes = exp.substring(2, exp.length() - 1).split(",");
		if (nodes.length > 2) {
			throw new IllegalArgumentException("表达式[" + exp + "]只能出现一个‘,‘");
		}

		this.varName = nodes[0].trim();
		this.defaultValue = nodes.length == 2 ? nodes[1].trim() : "";
		this.nullable = exp.startsWith("$");
	}

	@Override
	public String resolve(Map<String, Object> context) {
		Object value = context.get(varName);
		if (value == null && nullable) {
			value = defaultValue == null ? "" : defaultValue;
		}
		if (value == null) {
			throw new NullPointerException("上下文中没有指定的变量:var=" + varName + " map=" + context);
		}
		return value.toString();
	}

	@Override
	public String toString() {
		return "VarExp [varName=" + varName + ", defaultValue=" + defaultValue + ", nullable="
				+ nullable + "]";
	}

}

class Templ {

	List<Exp> exps = new ArrayList<>();

	static Templ of(String templStr) {
		Objects.requireNonNull(templStr, "模板为空");

		Templ templ = new Templ();
		StringBuilder sb = new StringBuilder();

		char[] chars = templStr.toCharArray();
		for (int i = 0; i < chars.length; i++) {
			switch (chars[i]) {
			case ‘#‘:
			case ‘$‘:
				if(i < chars.length - 1 && chars[i+1] == ‘{‘){
					templ.addExp(Exp.of(sb.toString()));
					sb.setLength(0);
				}
				sb.append(chars[i]);
				break;
			case ‘}‘:
				sb.append(‘}‘);
				if(sb.charAt(1) == ‘{‘){
					templ.addExp(Exp.of(sb.toString()));
					sb.setLength(0);
				}
				break;
			default:
				sb.append(chars[i]);
				break;
			}
		}

		if(sb.length() > 0){
			templ.addExp(Exp.of(sb.toString()));
		}

		return templ;
	}

	Templ addExp(Exp exp) {
		Objects.requireNonNull(exp, "表达式为空");
		exps.add(exp);
		return this;
	}

	String render(Map<String, Object> context) {
		StringBuilder sb = new StringBuilder(128);
		for (Exp exp : exps) {
			sb.append(exp.resolve(context));
		}
		return sb.toString();
	}

}
时间: 2024-10-01 02:42:11

一个简单的Java模板工具类(二)—简单表达式解析实现的相关文章

一个简单的Java文件工具类

1 package com.xyworkroom.ntko.util; 2 3 import java.io.File; 4 import java.io.FileInputStream; 5 import java.io.FileOutputStream; 6 import java.io.IOException; 7 import java.io.InputStream; 8 import java.io.OutputStream; 9 10 import javax.servlet.htt

iOS开发—音频的播放的简单介绍和封装工具类

iOS开发—音频的播放的简单介绍和封装工具类 一.音效的播放简单介绍 简单来说,音频可以分为2种 (1)音效 又称“短音频”,通常在程序中的播放时长为1~2秒 在应用程序中起到点缀效果,提升整体用户体验 (2)音乐 比如游戏中的“背景音乐”,一般播放时间较长 框架:播放音频需要用到AVFoundation.framework框架 二.音效的播放 1.获得音效文件的路径 NSURL *url = [[NSBundle mainBundle] URLForResource:@"m_03.wav&qu

java常用工具类(java技术交流群57388149)

package com.itjh.javaUtil; import java.util.ArrayList; import java.util.List; /** * * String工具类. <br> * * @author 宋立君 * @date 2014年06月24日 */ public class StringUtil { private static final int INDEX_NOT_FOUND = -1; private static final String EMPTY =

Java Properties工具类详解

1.Java Properties工具类位于java.util.Properties,该工具类的使用极其简单方便.首先该类是继承自 Hashtable<Object,Object> 这就奠定了Properties类的本质其实是一个HashTable,那么对于各种工具类的典型特性就是在HashTable的基础之上做各种封装,以降低操作的难度.说白了,本质上还是key = value结构,只不过key和value都是字符串而已.可以理解成为一个简化版的Map<String, String&g

zookeeper-kafka(集群版)安装部署以及java调用工具类

Kafka安装部署文档 ■ 文档版本 V1.0 ■ 操作系统 CentOS Linux release 7.3.1611 ■ 编写人员 闫立雄 ■ 文档日期 2019-01-06 一.  概述 该文档详细描述了在Linux环境下安装Kafka和ZooKeeper的全过程,文档中以kafka_2.11-1.1.0.tgz和zookeeper-3.4.12.tar.gz为例. 二.  安装ZooKeeper 2.1  下载ZooKeeper 方式1   http://mirrors.shu.edu.

25.大白话说java并发工具类-CountDownLatch,CyclicBarrier,Semaphore,Exchanger

1. 倒计时器CountDownLatch 在多线程协作完成业务功能时,有时候需要等待其他多个线程完成任务之后,主线程才能继续往下执行业务功能,在这种的业务场景下,通常可以使用Thread类的join方法,让主线程等待被join的线程执行完之后,主线程才能继续往下执行.当然,使用线程间消息通信机制也可以完成.其实,java并发工具类中为我们提供了类似"倒计时"这样的工具类,可以十分方便的完成所说的这种业务场景. 为了能够理解CountDownLatch,举一个很通俗的例子,运动员进行跑

20Spring_JdbcTemplatem模板工具类

JdbcTemplate 是Spring提供简化Jdbc开发模板工具类.为了更好的了解整个JdbcTemplate配置数据库连接池的过程,这篇文章不采用配置文件的方式,而是采用最基本的代码 的方式来写.后一篇文章会讲配置文件的方式. 1.Spring 对一下的持久层技术支持 2.jdbcTemplate快速入门 第一步:在项目中导入jar包 其中Spring核心包有四个,日志包有两个,测试包一个.如下 因为要用到jdbcTemplate所以还要导入以下两个jar包 spring-jdbc-3.2

java中Color类的简单总结

java中Color类的简单总结 1.颜色的常识 任何颜色都是由三原色组成(RGB),JAVA中支持224为彩色,即红绿蓝分量取值 介于0-255之间(8位表示) 2.Color类中的常量 public final static Color black = new Color(0,0,0); public final static Color bule = new Color(0,0,255); . . 有很多这样的常量,可供我们直接类名去调用而不需要去实例化. 3.Color中的构造函数 pu

黑马程序员——Java集合工具类和泛型

Collections工具类和泛型 Collections和Collection Collections和Collection是不同的,Collections是工具类,用来操作集合的,而Collection是集合接口.Collections中有一系列的静态方法用来操作集合,但是不能更改集合内容.比如不能set()不能remove()元素,可以替换全部元素或者添加同一个元素. static List<String> list =Arrays .asList("one Two three