在Java中,是否可以编写单个函数或类来处理任意多维ArrayList?
In Java, is writing a single function or class to handle arbitrary multidimensional ArrayList possible?
在C++中,我可以编写 2 个模板类,例如:
#include <stdio.h>
#include <vector>
template <typename T>
class Printer{
public:
static void print(T& v){
printf("%d ",v.getValue());
}
};
template <typename T,typename Alloc>
class Printer<std::vector<T,Alloc> >{
public:
static void print(std::vector<T,Alloc>& v){
for(T& e : v){
Printer<T>::print(e);
}
printf("n");
}
};
以便它可以接受任意自定义对象类型并在vector
vector
中vector
...(无穷大嵌套vector
):
class Student{
public:
int value;
Student(int value){ this->value=value; }
int getValue() const { return this->value; }
};
class Teacher{
public:
int value;
Teacher(int value){ this->value=value; }
int getValue() const { return this->value*10; }
};
int main(){
std::vector<Student> v2 = {Student(10),Student(20)};
Printer<std::vector<Student> >::print(v2);
std::vector<std::vector<Teacher> > v3 = {{Teacher(30),Teacher(40)},{Teacher(50),Teacher(60),Teacher(70)}};
Printer<std::vector<std::vector<Teacher> > >::print(v3);
return 0;
}
前提是自定义对象Student
和Teacher
具有getValue()
功能。
但是在 Java 中,我怎么能写出像上面这样接受两者的东西
ArrayList<Student > v2;
和
ArrayList<ArrayList<Teacher> > v3;
(也ArrayList
在ArrayList
ArrayList
中......)以通用方式?
当我尝试转换代码时,很少出现问题,首先,泛型对象方法无法编译:
public static void <T> print(T t){
System.out.print(t.getValue());
}
而且我不知道如何将std::vector< T , Alloc >
转换为 Java,因为ArrayList
只接受 1 个模板参数。
注意:我希望vector成为专用模板,因为当我想添加对int
的支持时:
std::vector<int> v1={1,2};
Printer<std::vector<int> >::print(v1);
我可以添加
template <>
class Printer<int>{
public:
static void print(int& v){
printf("%d ",v);
}
};
到代码。
有一个简单但非常丑陋的解决方案:转向原始类型,或者因为这是非常糟糕的做法,那就去? extends Object
。你看,最后,Java 泛型根本不是现代C++模板的匹配。泛型不是模板 - 例如:不能将它们用于基元类型,例如int
。您只能使用List<Integer>
。或者一些T extends Number
,当你需要一个需要双精度、浮点数、...对象也是如此。
关键是:最终,在运行时,所有这些"泛型"都消失了。所有这些列表都只包含对象。
所以,从理论上讲,如果你真的想要一个"解决方案",那么你可以选择
void foo(List<? extends Object> thingies)
避免所有类型的信息...并在运行时执行反射魔术,以确定如何处理该列表的确切内容。
"更多Java"解决方案需要您退后一步。如前所述,Java并不C++,所以你根本不应该期望Java具有相同水平的"表现力"。
相反:学习如何正确使用Java泛型和Java类型系统;并基于这些知识构建解决方案*。
或者换句话说:如果您需要C++解决方案,请使用C++。Java永远不会满足这个要求(至少不是100%)。
您可以通过instanceof
检查来做到这一点:
public static <T> void print(List<? extends T> list) {
for (final T t : list) {
if (t instanceof List) print((List) t);
else System.out.println(t);
}
}
但是,当然,如果方法未在接口中的任何位置或某处定义,则不能T.getValue()
使用方法。如果T
是接口
public interface T {
String getValue();
}
那么你有这样的东西
public static void print(List<? extends Object> list) {
for (Object t : list) {
if(t instanceof T) System.out.println(((T)t).getValue());
else if (t instanceof List) print((List) t);
else continue; // I don't know this type.
}
}
但它随后会附加到您的接口T
。问题实际上在于您无法访问未定义的方法,至少没有反射。C++到底是怎么做到的?
编辑:这当然是行不通的,如果你有一个T
的实现,它也实现了List
接口。
- 用于矢量处理的多个线程
- Valgrind:可以处理更多可能丢失的字节吗?
- RPN计算器c++错误处理和多个运算符
- 在Java中,是否可以编写单个函数或类来处理任意多维ArrayList?
- 如何处理来自多个窗口的消息
- C++标准是否允许复制任意多态数据结构?
- 如何在 C++ 中处理任意维向量
- 如何在不同情况下处理具有多个法线的顶点
- 如何处理 Win32 多行编辑控件中的输入键
- 如何在大型项目中预处理具有多个 #include 文件的单个源文件
- 处理"returning"多个值的函数的模板
- 如何在bison中优雅地处理具有多个组件的规则
- 以多态的方式处理非多态对象,不会产生性能开销
- 可以用C++std::vector同时处理来自多线程的push_back
- 如何处理具有多个子窗体的事件'Tab Control'
- 处理需要多行初始化'const'对象
- 有没有可能创建一个数组,在初始化时我们不知道元素的数量?(处理遗传/多态性)
- 在打字稿中,如何编写一个函数来处理任意维度数组(例如:<number>Array,Array<Array<number>>,...)?
- c++处理Linux多线程程序中的按键操作
- 如何在OpenGL中处理包含多个对象的动画