这可能是一个愚蠢的问题,但Java中是否有一种类型的集合可以保存不同类型的原语?我目前正在创建一种格式化两种类型对象的方法,并且我试图将参数存储在数组中,以避免使用带有十个+参数的方法,而是使用两个数组来保存值并传递相反,他们。
这些类型将是字符串,整数和布尔值的组合。
答案 0 :(得分:4)
Java中的基元可以装入对象中。类型Object
可以保存String
,int
和boolean
类型的值,方法是将原始int
值存储为Integer
个对象和原语boolean
值为Boolean
个对象。这通常可以在没有程序员明确地包装或展开它们的情况下进行,这称为自动装箱。
因此,任何包含Object
类型值的集合或数组,例如Object[]
,List<Object>
等,都可以保存您的值。
例如:
Object[] array = new Object[] { 1, 2, true, "hi" };
List<Object> list = new ArrayList<Object>();
list.add(5);
list.add(false);
list.add("test");
对于方法的变量参数,只需使用Object...
:
void myMethod(Object... params) {
// ...
}
处理数组或Object
值集合时,可以使用instanceof
和强制转换来查找类型并正确处理它们。
当自动装箱以输入Object
时,基元会直接装入Object
值。在以下代码中:
short shortValue = 0;
int myPrimitive = shortValue;
Object myObject = shortValue;
myPrimitive
的类型为int
,但myObject
的类型为Short
。你问了一个Object
,你有一个!请注意您对Object
类型对象的假设,因为原则上您不能假设Object
以外的其他任何内容。
幸运的是,您不必总是为每个原始数字类型检查Object
。在大多数情况下,它足以将其强制转换为Number
,然后使用例如.intValue()
来获取int类型的值。也就是说,代码如下:
double x = 2.3;
Object o = x;
int i = ((Number) o).intValue();
相当于:
double x = 2.3;
int i = (int) x;
答案 1 :(得分:2)
可以在Java中保存整数的唯一“集合”是一个数组,它只能保存单个类型的基元。
如果需要收集多种类型的基元,可以创建一个具有多个基本成员的类,然后使用任何要存储该类的多个实例的Collection。
答案 2 :(得分:2)
假设你真的需要这样一个集合,你想要避免拳击价值的成本,你可以通过小心支持已经实现的原始集合such as Trove自己实现这样的集合。由于您没有指定所需的集合类型,让我们看一下将原始整数映射到您命名的值的示例映射:
class PrimitiveMap {
final TIntBooleanMap booleans;
final TIntIntMap ints;
final TIntObjectMap<String> strings;
// Constructor omitted
void putBoolean(int index, boolean value) {
removeIndex(index);
booleans.put(index, value);
}
boolean getBoolean(int index) {
booleans.get(index);
}
// similarly for the other collection types
private removeIndex(int index) {
booleans.remove(index);
ints.remove(index);
strings.remove(index);
}
}
明显的缺点是你需要记住插入的元素的类型。或者,您可以在访问集合时使用盒装值,然后在存储值之前解析该框:
public void put(Object value) {
if(value instanceof Boolean) {
putBoolean((Boolean) value);
} else if(value instanceof Integer) {
putInteger((Integer) value);
} else if(value instanceof String) {
putString((String) value);
}
throw new IllegalArgumentException("Illegal value = " + value);
}
public Object get(int index) {
boolean booleanValue = booleans.get(index);
if(booleanValue != booleans.getNoEntryValue()) {
return booleanValue;
}
int intValue = ints.get(index);
if(intValue != ints.getNoEntryValue()) {
return intValue;
}
String stringValue = strings.get(index);
if(stringValue != null) {
return stringValue;
}
return null;
}
请注意,如果您真的想要优化内存占用,这种方法可以获得回报,因为您可以避免保留对装箱对象的引用的开销。我假设您需要维护大量的集合才能衡量差异。在实施此类集合之前,请务必检查您的应用程序的足迹。
此方法对于列表的工作方式类似,其中实现也将由每个基元类型的映射支持,只有访问API不同。对于集合,您可以执行类似的操作,即用TXXXSet
备份每个基元集合。