我需要对各种原始类型执行算法; 算法基本相同,但变量的类型除外.所以,例如,
/**
* Determine if <code>value</code> is the bitwise OR of elements of <code>validValues</code> array.
* For instance, our valid choices are 0001, 0010, and 1000.
* We are given a value of 1001. This is valid because it can be made from
* ORing together 0001 and 1000.
* On the other hand, if we are given a value of 1111, this is invalid because
* you cannot turn on the second bit from left by ORing together those 3
* valid values.
*/
public static boolean isValid(long value, long[] validValues) {
for (long validOption : validValues) {
value &= ~validOption;
}
return value == 0;
}
public static boolean isValid(int value, int[] validValues) {
for (int validOption : validValues) {
value &= ~validOption;
}
return value == 0;
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能避免这种重复?我知道没有办法对原始数组进行泛化,所以我的双手似乎很紧张.我有原始数组的实例,而不是说Number对象的盒装数组,所以我也不想去那条路.
我知道有很多关于数组,自动装箱等原语的问题,但我还没有看到它以这种方式制定,我还没有看到如何与这些数组交互的决定性答案.
我想我可以这样做:
public static<E extends Number> boolean isValid(E value, List<E> numbers) {
long theValue = value.longValue();
for (Number validOption : numbers) {
theValue &= ~validOption.longValue();
}
return theValue == 0;
}
Run Code Online (Sandbox Code Playgroud)
然后
public static boolean isValid(long value, long[] validValues) {
return isValid(value, Arrays.asList(ArrayUtils.toObject(validValues)));
}
public static boolean isValid(int value, int[] validValues) {
return isValid(value, Arrays.asList(ArrayUtils.toObject(validValues)));
}
Run Code Online (Sandbox Code Playgroud)
这真的好多了吗?这种方式将创建比原始实现更多的对象,尽管它会干掉源代码.对此事的任何想法都将不胜感激.
我之前问了一个类似的问题(用Java管理高度重复的代码和文档),并注意到源代码在其处理原始数组类型的算法中java.util.Arrays是高度重复的.
实际上,源代码包含以下注释:
七种原始类型中的每一种的代码大致相同.这就是生活.
我接受的答案建议使用代码生成器,让您使用代码模板.还有一条评论称Sun/Oracle内部也使用了模板系统.
你也可以使用反射来减少重复,但这可能很慢,也许不值得努力.如果您想测试其性能,此片段演示了该技术:
import java.lang.reflect.Array;
static long maskFor(Class<?> c) {
return (
c.equals(int.class) ? 1L << Integer.SIZE :
c.equals(short.class) ? 1L << Short.SIZE :
c.equals(byte.class) ? 1L << Byte.SIZE :
0
) - 1;
}
public static void reflectPrimitiveNumericArray(Object arr) throws Exception {
int length = Array.getLength(arr);
Class<?> componentType = arr.getClass().getComponentType();
long mask = maskFor(componentType);
System.out.format("%s[%d] = { ", componentType, length);
for (int i = 0; i < length; i++) {
long el = Array.getLong(arr, i) & mask;
System.out.print(Long.toBinaryString(el) + " ");
}
System.out.println("}");
}
Run Code Online (Sandbox Code Playgroud)
您可以传递int[]for arr和其他原始数组类型.一切都被投入long,通过位屏蔽来解决符号扩展问题.
reflectPrimitiveNumericArray(new byte[] { (byte) 0xF0 });
// byte[1] = { 11110000 }
reflectPrimitiveNumericArray(new int[] { 0xF0F0F0F0 });
// int[1] = { 11110000111100001111000011110000 }
reflectPrimitiveNumericArray(new long[] { 0xF0F0F0F0F0F0F0F0L });
// long[1] = { 1111000011110000111100001111000011110000111100001111000011110000 }
Run Code Online (Sandbox Code Playgroud)
如果你在看java.util.Arrays,你会看到,即使他们不得不专门所有的算法(binarySearch,equals,等),每个基本类型.
如果性能是一个问题,我不建议依赖自动装箱,但如果不是(在您进行了分析之后),它将是一个有效的选项.
| 归档时间: |
|
| 查看次数: |
691 次 |
| 最近记录: |