泛型数组java
1. 泛型和数组以及java是如何实现泛型的
要区分数组和泛型容器的功能,这里先要理解三个概念:协变性(covariance)、逆变性(contravariance)和无关性(invariant)。
若类A是类B的子类,则记作A ≦ B。设有变换f(),若:
当A ≦ B时,有f(A)≦ f(B),则称变换f()具有协变性;
当A ≦ B时,有f(B)≦ f(A),则称变换f()具有逆变性;
如果以上两者皆不成立,则称变换f()具有无关性。
在Java中,数组具有协变性,而泛型具有无关性,示例代码如下:
Object[] array = new String[10];
//编译错误
ArrayList<Object> list=new ArrayList<String>();
这两句代码,数组正常编译通过,而泛型抛出了编译期错误,应用之前提出的概念对代码进行分析,可知:
1、String ≦ Object
2、数组的变换可以表达为f(A)=A[],通过之前的示例,可以得出下推论:
f(String) = String[] 以及 f(Object) = Object[];
4、通过代码验证,String[] ≦ Object[] 是成立的,由此可见,数组具有协变性。
2. java 泛型数组怎么实例化
思路:
1 获取泛型的实际类型;
2 调用构造方法 进行实例化;
3. java为什么不支持泛型数组
由于JVM泛型的擦除机制,在运行时JVM是不知道泛型信息的,所以可以给oa[1]赋上一个ArrayList<Integer>而不会出现ArrayStoreException,但是在取出数据的时候却要做一次类型转换,所以就会出现ClassCastException,如果可以进行泛型数组的声明,上面说的这种情况在编译期将不会出现任何的警告和错误,只有在运行时才会出错。而对泛型数组的声明进行限制,对于这样的情况,可以在编译期提示代码有类型安全问题,比没有任何提示要强很多。
基于以上的原因,Java不支持声明泛型数组,更确切地表达是:数组的类型不可以是类型变量,除非是采用通配符的方式,
4. JAVA怎么初始化泛型数组
首先由于Java泛型的实现,不可以使用如下的代码:
public class GenSet<E> {
private E a[];
public GenSet() {
a = new E[INITIAL_ARRAY_LENGTH]; // error: generic array creation
}
}
那么我们如何在保持类型安全的同时实现这一点?
我在Java论坛上看到了这样的解决方案:
import java.lang.reflect.Array;
class Stack<T> {
public Stack(Class<T> clazz, int capacity) {
array = (T[])Array.newInstance(clazz, capacity);
}
private final T[] array;
}
在这里,我们需要讨论"checked" and "unchecked"。
Checked:strong typing。GenSet明确知道它包含的对象类型(即它的构造函数是使用Class <E>参数显式调用的,当方法传递非类型E的参数时,方法将抛出异常。请参阅Collections.checkedCollection。
在这种情况,我们需要这样写:
public class GenSet<E> {
private E[] a;
public GenSet(Class<E> c, int s) {
// Use Array native method to create array
// of a type only known at run time
@SuppressWarnings("unchecked")
final E[] a = (E[]) Array.newInstance(c, s);
this.a = a;
}
E get(int i) {
return a[i];
}
}
Unchecked: weak typing。实际上没有对作为参数传递的任何对象进行类型检查。
在这种情况,我们需要这样写:
public class GenSet<E> {
private Object[] a;
public GenSet(int s) {
a = new Object[s];
}
E get(int i) {
@SuppressWarnings("unchecked")
final E e = (E) a[i];
return e;
}
}
请注意,数组的组件类型应该是类型参数的擦除:
public class GenSet<E extends Foo> { // E has an upper bound of Foo
private Foo[] a; // E erases to Foo, so use Foo[]
public GenSet(int s) {
a = new Foo[s];
}
...
}
所有的这些都源于Java中泛型一个的特性但也是一个weakness:它是使用擦除实现的,因此除非实施一些显式机制(type-checking),否则“泛型”类不知道它们在运行时创建的类型参数,故无法提供 type-safety。
5. java中关于泛型与数组的疑问
public static void main(String[] args) {
// 不能使用泛型数组
// Cannot create a generic array of List<String>
//List<String>[] lists = new List<String>[10];
// 但是你可以使用集合数组, 如果你非要这样做的话
List[] test2 = new List[10];
// 我不确定你这样做的动机是什么, 如果非要使用到泛型集合数组的话, 也可以这样
// Key: 索引
// Value: 泛型集合
// 缺点: 索引需要自己维护
Map<Integer, List<String>> collectionArray = new LinkedHashMap<Integer, List<String>>();
}
6. java 泛型数组add出错
一楼说的在理。
因为list里放的是对象是引用类型的,如果你一直new,那么改变的是同一个对象值。
7. JAVA为什么不让创建泛型数组
首先,觉得定制java标准的完全可以让java创建泛型数组;只是权衡了一下,觉得还是禁止了的好,一下就说说揣测:
(1):如果写如下代码是可以的:
可以发现,堆中的第0个元素是List了,但是arr[0]还是指向了它,如果是普通变量,这是不可能的;所以,即便是引入了泛型,也不是安全的;
总结:由于编译器会加上string转化,造成ClassCastException;泛型本来就是为了安全,如果不能保证数组的安全,这就是一样的。
8. 请问,Java中,泛型数组的数组怎么初始化(就是ArrayList数组)
既然你暗示就是ArrayList了,
首选就从Arraylist想了
可以试试:
import java.util.ArrayList;
public class Test{
public static void main(String[]args){
ArrayList<ArrayList<Integer>> als = new ArrayList<ArrayList<Integer>> ();
ArrayList<Integer> a1 = new ArrayList<Integer>();
ArrayList<Integer> a2 = new ArrayList<Integer>();
ArrayList<Integer> a3 = new ArrayList<Integer>();
ArrayList<Integer> a4 = new ArrayList<Integer>();
//下面是添加行,你可以用循环添加固定的行
//每一列就是一个ArrayList<Integer>,你可以任意添加,长度不固定吧
als.add(a1);
als.add(a2);
als.add(a3);
als.add(a4);
System.out.println(als.size());
}
}
tao_3000的方法可行,只是Integer[]创建时要指定维数
可以自己写个算法自动增加维数
对于你说的数据量问题,个人理解是这样的:
达到了几十万几百万的数据量的时候,我想大概就是从数据库中吧数据读取出来,进行批量的处理或者更新之类的操作。
你说得很对,如此庞大的数据量肯定会使效率降低,
但是我们完全可以一次从数据库中读取几百条记录,进行操作
关于如何从数据库中一次读取很少的记录,jdbc和hibernate都有相应的实现
在者,数据量过大,呵呵,JVM可能崩溃哦 *_*
9. java泛型数组
publicclassDemoFanXing{
publicstaticvoidmain(String[]args){
Arr<Integer>a=newArr<Integer>();
a.setArray(1,2,3,4,5,6);
for(intx:a.getArray()){
System.out.print(x+"");
}
}
}
classArr<T>{
privateT[]arr;
//public<T>voidsetArray(T...arg),多了一个<T>
publicvoidsetArray(T...arg){
this.arr=arg;
}
publicT[]getArray(){
returnarr;
}
}