Java工具: 一个类型安全的 WeakArray
2012-10-02 09:20
267 查看
有的地方要用一个简单的数组缓存运算结果,空间换时间,但是要求万一内存不够,要这些结果能被释放(WeakReference),所以有了这个工具类。
上一篇文章里用来计算阶乘的工具类 Calculator,可以使用 WeakArray 来cache运算结果,修改如下:
/* * Copyright 2012 raistlic (raistlic@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.lang.ref.WeakReference; import java.util.Iterator; /** * This class simply encapsulates an array to be used as a cache, which holds * weak references. * * It is intended to store "not so important" contents, which can be GCed * when required. * * The iterator of this class can be used to iterate it, or remove elements * from it, removing elements using the iterator will not effect the subsequent * elements' positions. * * @author raistlic * @date 27/09/2012 */ public class WeakArray<E> implements Iterable<E> { @SuppressWarnings({"unchecked", "rawtypes"}) private WeakReference<E>[] data; public WeakArray(int size) { if( size < 0 ) throw new IllegalArgumentException("Invalid array size: " + size); data = (WeakReference<E>[])new WeakReference[size]; } public int length() { return data.length; } public void set(int index, E element) { // potentially throws ArrayIndexOutOfBoundsException if( get(index) != element ) data[index] = new WeakReference<E>(element); } public E get(int index) { // potentially throws ArrayIndexOutOfBoundsException WeakReference<E> ref = data[index]; return ref == null ? null : ref.get(); } public void remove(int index) { // potentially throws ArrayIndexOutOfBoundsException data[index] = null; } @Override public Iterator<E> iterator() { return new IndexIterator(); } private class IndexIterator implements Iterator<E> { private int index = 0; @Override public boolean hasNext() { return index < length(); } @Override public E next() { // potentially throws ArrayIndexOutOfBoundsException E result = get(index); index++; return result; } @Override public void remove() { // potentially throws ArrayIndexOutOfBoundsException WeakArray.this.remove(index); index++; } } }
上一篇文章里用来计算阶乘的工具类 Calculator,可以使用 WeakArray 来cache运算结果,修改如下:
/* * Copyright 2012 raistlic (raistlic@gmail.com) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.math.BigInteger; /** * This class is intended to provide convenient facilities for * frequently used maths calculations that {@code java.lang.Math} * does not cover. * * @date 08/08/2012 * @author raistlic */ public final class Calculator { private Calculator() {} private static final WeakArray<BigInteger> FACT_POOL = new WeakArray<BigInteger>(1024); public static BigInteger factorial(int number) { if( number < 0 ) throw new IllegalArgumentException(); BigInteger result = null; if( number < FACT_POOL.length() ) result = FACT_POOL.get(number); if( result == null ) { int lastCachedIndex = lastCachedFactIndex(number); if( lastCachedIndex > 0 ) result = FACT_POOL.get(lastCachedIndex); if( result == null ) result = BigInteger.ONE; for(int i = Math.max(2, lastCachedIndex+1); i <= number; i++) { result = result.multiply(BigInteger.valueOf(i)); if( i < FACT_POOL.length() ) FACT_POOL.set(i, result); } } return result; } private static int lastCachedFactIndex(int number) { for(int i=Math.min(number, FACT_POOL.length()-1); i>=0; i--) { if( FACT_POOL.get(i) != null ) return i; } return -1; } }
相关文章推荐
- 一个关于Java程序安全意识重构的工具
- java 定义一个类型安全的Map
- [Groovy]如何定义和使用一个Java里的Enum类型
- Q:java中关于String类型的一个问题
- 【JAVA基础】0012--------判断String类型的XML中是否存在某一个节点
- java程序中,如何安全的结束一个正在运行的线程?interrupt()
- java中的类型安全问题-Type safety: Unchecked cast from Object to ... 或者 Type safety: Unchecked cast from Type to Class<T>
- Java 并发专题 : CyclicBarrier 打造一个安全的门禁系统
- 2013年8月17日、二维数组定义的格式|用java表现一个描述小汽车|基本数据类型参数传递|
- Java判断一个数的取值范围和类型。
- 【Java工具】将一个对象转换成Map
- JAVA的一个String连接小工具
- java中表示一个文件的File类型详解
- java 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。
- Java面向对象【经典案例】强制/自动类型转换与类型安全的转换
- Java利用反射来获取一个方法的 范型化参数 Vector<Integer>的类型
- Java写的一个记事本工具
- 想开发一个java自动化测试工具
- 一个奇妙的java坑:Long 类型的比较
- 一个很好的Java查BUG工具