在Java中,创建一个通用的解析字符串缓存(多个结果类型)
我试图创建一个通用的解析字符串缓存,以防止反复重建同一个对象。基本上,我正在构建的是以下内容:在Java中,创建一个通用的解析字符串缓存(多个结果类型),java,Java,我试图创建一个通用的解析字符串缓存,以防止反复重建同一个对象。基本上,我正在构建的是以下内容: public class ParsedStringCache { // static Map<Pair<String, Parser<T>>, T> _cache // = new HashMap<Pair<String, Parser<T>>, T>(); public interface
public class ParsedStringCache {
// static Map<Pair<String, Parser<T>>, T> _cache
// = new HashMap<Pair<String, Parser<T>>, T>();
public interface StringParser<T> {
public T parseString(String stringToParse);
}
public static <T> T getParsedObject(String stringToParse, Parser<T> parser) {
return parser.parseString(stringToParse);
}
}
公共类ParsedStringCache{
//静态映射缓存
//=新HashMap();
公共接口字符串分析器{
公共T parseString(String stringToParse);
}
公共静态T getParsedObject(字符串stringToParse,解析器){
返回parser.parseString(stringToParse);
}
}
在我尝试实际缓存结果之前,这一切都很好,例如,通过使用类似于上面代码中注释掉的hashmap的东西,这将本质上记住getParsedObject的结果。有没有一种相当简单的方法可以避免强制转换呢?我会让缓存成为解析器的一部分。我肯定您会遇到某种编译错误,需要解决,但下面是我将要做的基本操作
import java.util.*;
abstract class Parser<T> {
private Map<String,T> cache = new HashMap<String,T>();
public final T parseString(String str) {
T result = cache.get(str);
if(result == null) {
result = parseString0(str);
cache.put(str,result);
}
return result;
}
protected abstract T parseString0(String str);
}
public class IntParser extends Parser<Integer> {
protected Integer parseString0(String str) {
return Integer.parseInt(str.trim());
}
}
public class LongParser extends Parser<Long> {
protected Long parseString0(String str) {
return Long.parseLong(str.trim());
}
}
class ParserTest {
public static void main(String[] args) {
Parser<Integer> intParse = new IntParser();
Parser<Long> longParse = new LongParser();
Long long1 = longParse.parseString("10000");
Long long2 = longParse.parseString("20000");
Long long3 = longParse.parseString("30000");
Long equalLong = longParse.parseString("20000"); // repeat long2
Long fakeLong = new LongParser().parseString("20000"); // repeated with fake
System.out.println("Expecting true: " + (long2 == equalLong));
System.out.println("Expecting false: " + (fakeLong == equalLong));
}
}
C:\Documents and Settings\glowcoder\My Documents>javac Parser.java
C:\Documents and Settings\glowcoder\My Documents>javac IntParser.java
C:\Documents and Settings\glowcoder\My Documents>javac LongParser.java
C:\Documents and Settings\glowcoder\My Documents>javac ParserTest.java
C:\Documents and Settings\glowcoder\My Documents>java ParserTest
Expecting true: true
Expecting false: false
import java.util.*;
抽象类解析器{
私有映射缓存=新的HashMap();
公共最终解析字符串(字符串str){
T result=cache.get(str);
如果(结果==null){
结果=0(str);
cache.put(str,result);
}
返回结果;
}
受保护的抽象T parseString0(String str);
}
公共类IntParser扩展了语法分析器{
受保护的整数parseString0(字符串str){
返回Integer.parseInt(str.trim());
}
}
公共类长语法分析器扩展语法分析器{
受保护的长parseString0(字符串str){
返回Long.parseLong(str.trim());
}
}
类ParserTest{
公共静态void main(字符串[]args){
Parser intParse=新的IntParser();
Parser longParse=新的LongParser();
Long long1=longParse.parseString(“10000”);
Long long2=longParse.parseString(“20000”);
Long long3=longParse.parseString(“30000”);
Long equalLong=longParse.parseString(“20000”);//重复long2
Long fakeLong=new LongParser().parseString(“20000”);//用false重复
System.out.println(“应为true:+(long2==equalLong));
System.out.println(“预期为false:+(fakeLong==equalLong));
}
}
C:\Documents and Settings\glowcoder\My Documents>javac Parser.java
C:\Documents and Settings\glowcoder\My Documents>javac IntParser.java
C:\Documents and Settings\glowcoder\My Documents>javac LongParser.java
C:\Documents and Settings\glowcoder\My Documents>javac ParserTest.java
C:\Documents and Settings\glowcoder\My Documents>java ParserTest
期待真实:真实
期望为假:假
我会保持对他们的管理,但会添加收集信息和向中央经理报告的方法。显然,您需要向解析器添加更多的方法来跟踪缓存。或者(这可能是一个更好的主意),您可以将缓存逻辑整合到一个缓存类中,并让管理器跟踪这些缓存
通过这种方式,您可以让缓存本身确定如何修剪其信息。它可以是最古老的,可以是大小,可以是各种各样的标准。也许它有用户信息,你希望你的付费用户更多地留在缓存中
import java.util.*;
class ParserCacheManager {
private Set<Parser<?>> parsers = new HashSet<Parser<?>>();
public void addParser(Parser<?> p) { parsers.add(p); }
public int size() {
int size = 0;
for(Parser<?> p : parsers) size += p.cacheSize();
return size;
}
public void trimToSize(int maxSize) {
while(size() > maxSize) {
Parser<?> p = largestParser();
p.trimToPercent(0.90);
}
}
/**
* This would be better perhaps with a set sorted by
* size, or something like that. But this works for example.
*/
private Parser<?> largestParser() {
Parser<?> largest = null;
for(Parser<?> p : parsers) {
if(largest == null || p.size() > largest.size())
largest = p;
}
return largest;
}
}
import java.util.*;
类ParserCacheManager{
私有集>();
public void addParser(Parser p){parsers.add(p);}
公共整数大小(){
int size=0;
for(Parser p:parsers)size+=p.cacheSize();
返回大小;
}
公共空间修剪大小(int maxSize){
while(size()>maxSize){
Parser p=largestParser();
p、 三倍体(0.90%);
}
}
/**
*如果有一个按排序的集合,这可能会更好
*大小,或类似的东西。但这是工作的例子。
*/
私有解析器largestParser(){
解析器最大=空;
for(解析器p:parsers){
如果(最大==null | | p.size()>最大的.size())
最大=p;
}
回报最大;
}
}
我将使缓存成为解析器的一部分。我肯定您会遇到某种编译错误,需要解决,但下面是我将要做的基本操作
import java.util.*;
abstract class Parser<T> {
private Map<String,T> cache = new HashMap<String,T>();
public final T parseString(String str) {
T result = cache.get(str);
if(result == null) {
result = parseString0(str);
cache.put(str,result);
}
return result;
}
protected abstract T parseString0(String str);
}
public class IntParser extends Parser<Integer> {
protected Integer parseString0(String str) {
return Integer.parseInt(str.trim());
}
}
public class LongParser extends Parser<Long> {
protected Long parseString0(String str) {
return Long.parseLong(str.trim());
}
}
class ParserTest {
public static void main(String[] args) {
Parser<Integer> intParse = new IntParser();
Parser<Long> longParse = new LongParser();
Long long1 = longParse.parseString("10000");
Long long2 = longParse.parseString("20000");
Long long3 = longParse.parseString("30000");
Long equalLong = longParse.parseString("20000"); // repeat long2
Long fakeLong = new LongParser().parseString("20000"); // repeated with fake
System.out.println("Expecting true: " + (long2 == equalLong));
System.out.println("Expecting false: " + (fakeLong == equalLong));
}
}
C:\Documents and Settings\glowcoder\My Documents>javac Parser.java
C:\Documents and Settings\glowcoder\My Documents>javac IntParser.java
C:\Documents and Settings\glowcoder\My Documents>javac LongParser.java
C:\Documents and Settings\glowcoder\My Documents>javac ParserTest.java
C:\Documents and Settings\glowcoder\My Documents>java ParserTest
Expecting true: true
Expecting false: false
import java.util.*;
抽象类解析器{
私有映射缓存=新的HashMap();
公共最终解析字符串(字符串str){
T result=cache.get(str);
如果(结果==null){
结果=0(str);
cache.put(str,result);
}
返回结果;
}
受保护的抽象T parseString0(String str);
}
公共类IntParser扩展了语法分析器{
受保护的整数parseString0(字符串str){
返回Integer.parseInt(str.trim());
}
}
公共类长语法分析器扩展语法分析器{
受保护的长parseString0(字符串str){
返回Long.parseLong(str.trim());
}
}
类ParserTest{
公共静态void main(字符串[]args){
Parser intParse=新的IntParser();
Parser longParse=新的LongParser();
Long long1=longParse.parseString(“10000”);
Long long2=longParse.parseString(“20000”);
Long long3=longParse.parseString(“30000”);
Long equalLong=longParse.parseString(“20000”);//重复long2
Long fakeLong=new LongParser().parseString(“20000”);//用false重复
System.out.println(“应为true:+(long2==equalLong));
System.out.println(“预期为false:+(fakeLong==equalLong));
}
}
C:\Documents and Settings\glowcoder\My Documents>javac Parser.java
C:\Documents and Settings\glowcoder\My Documents>javac IntParser.java
C:\Documents and Settings\glowcoder\My Documents>javac LongParser.java
C:\Documents and Settings\glowcoder\My Documents>javac ParserTest.java
C:\Documents and Settings\glowcoder\My Documents>java ParserTest
期待真实:真实
期望为假:假
我会让他们保持现状,但我要补充一点
Cache<String, T> parsedObjectCache = CacheBuilder.newBuilder()
.expireAfterAccess(10, TimeUnit.MINUTES)
.build(
new CacheLoader<String, T>() {
public T load(String str) throws MyParseException {
return parse(str); //called either on or from inside a Parser<T>
}
});