Java中泛型嵌套举例

本文深入讲解Java泛型的使用,包括泛型类、泛型方法、泛型嵌套等内容,并通过具体实例展示了如何创建泛型类及进行泛型操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package tk.zhangwei.Generic;

public class Student<T> {
    private T name;

    public T getName() {
        return name;
    }

    public void setName(T name) {
        this.name = name;
    }


}
package tk.zhangwei.Generic;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

/***
 * 泛型嵌套
 *   从外到内
 * @author zw
 *
 */

public class Test02 {
    public static void main(String[] args){
        Student<String> stu = new Student<String>();
        stu.setName("张伟");
        System.out.println(stu.getName());


        PhStudent<Student<String>> ph = new PhStudent<Student<String>>();
        ph.setId(stu);
        stu = ph.getId();
        String name = stu.getName();
        System.out.println(name);

        //遍历

        Map<String,String> map = new HashMap<String,String>();
        map.put("a", "张伟");
        map.put("b", "老王");

        Set<Entry<String,String>> entrySet = map.entrySet();
        for(Entry<String,String> entry:entrySet){
            String Key = entry.getKey();
            String Value = entry.getValue();
            System.out.println(Key+"---"+Value);
        }


    }
}

666

注意:泛型没有多态,没有数组

package tk.zhangwei.Generic;

import java.util.ArrayList;
import java.util.List;

/***
 * 1.泛型 没有多态
 * 2.泛型没有数组
 * @author zw
 *
 */

public class Test01 {

    public static void main(String[] args) {
        //父类对象 直接引用子类对象
        Fruit f = new apple();

        //泛型 没有多态
        //List<Fruit> list = new Arraylist<apple>();

        //泛型没有数组
        //Fruit<String>[] arr = new Fruit<String>[10];

        //jdk1.7简化后
        List<Fruit> list2 = new ArrayList<>();

    }

}
package tk.zhangwei.Generic;

public class Fruit {

}
class apple extends Fruit{

}
<think>嗯,用户之前问过在C#中List<List<object>>和List<object[]>的区别,现在又问在Java中的情况。首先,我需要确认用户是否在比较类似的结构,也就是Java中的List<List<Object>>和List<Object[]>。 首先,回忆一下C#的情况,两者的主要区别在于内部集合的可变性和类结构。那么在Java中,是否也是类似的呢?Java的List和数组在行为上应该和C#类似,但需要注意Java的类系统和一些语法差异。 Java中的List是一个接口,通常由ArrayList等实现,而数组则是固定长度的。因此,List<List<Object>>中的每个元素都是List类,可以动态调整大小,而List<Object[]>中的每个元素是数组,长度固定。这应该和C#中的情况一致。 接下来要考虑用户可能的实际应用场景。比如,用户可能在处理表格数据,或者需要动态添加内部元素的情况。这时候选择List<List<Object>>会更灵活,而如果数据长度固定,比如矩阵的行列,可能更适合用数组,即List<Object[]>。 另外,Java中的类安全和处理需要注意。例如,数组在Java中是协变的,而是不变的,这可能影响两者的使用。例如,Object[]数组可以存放任何Object子类的元素,但List<Object>在添加元素时会有类检查,但可能会有一些协变的问题需要注意。 还需要考虑性能方面。数组在内存中是连续的,访问速度可能更快,而List由于需要动态扩容,可能在频繁增删时效率较低。但具体到内部元素是List还是数组,可能对整体性能的影响需要具体分析。 另外,用户可能在转换这两种结构时遇到问题,比如如何将List<Object[]>转换为List<List<Object>>,或者反过来。这时候需要遍历每个元素并进行转换,类似C#中的做法,但Java的语法不同,需要举例说明。 还需要检查是否有其他Java特定的注意事项,比如类擦除对的影响,或者在使用数组时可能出现的异常情况,比如ArrayStoreException等。不过这可能超出了用户当前问题的范围,但如果有必要可以简要提及。 最后,用户可能需要一个清晰的对比,包括类定义、内存结构、性能、使用场景等,类似于之前的C#回答结构。因此,回答的结构应该保持一致,便于用户对比理解。</think>在Java中,$\text{List<List<Object>>}$ 和 $\text{List<Object[]>}$ 的区别与C#类似,但受Java语言特性的影响,仍有一些需要注意的细节差异。以下是详细分析: --- ### 一、类定义差异 1. **$\text{List<List<Object>>}$** - 外层是$\text{List}$接口(如$\text{ArrayList}$),每个内层元素是另一个可动态调整的$\text{List}$ - **动态长度**:支持随时增删内层元素 - 示例: ```java List<List<Object>> nestedList = new ArrayList<>(); nestedList.add(new ArrayList<>(Arrays.asList(1, "a"))); nestedList.get(0).add(true); // 允许动态添加 ``` 2. **$\text{List<Object[]>}$** - 外层是$\text{List}$,每个内层元素是固定长度的$\text{Object[]}$数组 - **固定长度**:数组初始化后长度不可变 - 示例: ```java List<Object[]> listOfArrays = new ArrayList<>(); listOfArrays.add(new Object[]{1, "a"}); // listOfArrays.get(0)[2] = true; // 报错:索引越界(原数组长度固定为2) ``` --- ### 二、关键区别对比 | 特性 | $\text{List<List<Object>>}$ | $\text{List<Object[]>}$ | |---------------------|--------------------------------------------|------------------------------------------| | **内存管理** | 内层$\text{List}$存储引用,内存分散 | 内层数组连续存储,内存局部性更好 | | **扩容成本** | 内层$\text{List}$自动扩容(如$\text{ArrayList}$) | 需创建新数组并复制数据 | | **类安全** | 提供编译时类检查 | 数组允许协变,可能引发$\text{ArrayStoreException}$ | | **序列化支持** | 标准Java序列化直接支持 | 数组序列化需要额外处理 | --- ### 三、Java特有注意事项 1. **与数组的兼容性** Java禁止直接创建数组(类擦除导致): ```java // List<Object>[] arr = new ArrayList<Object>[10]; // 编译错误 List<Object[]> list = new ArrayList<>(); // 允许 ``` 2. **类协变风险** - 数组是协变的($\text{String[]}$可赋值给$\text{Object[]}$),但可能导致运行时异常: ```java Object[] arr = new String[]{"a", "b"}; arr[0] = 123; // 运行时抛出ArrayStoreException ``` - 集合是类不变的,安全性更高: ```java List<String> strList = new ArrayList<>(); // List<Object> objList = strList; // 编译错误 ``` 3. **性能差异** - 数组访问速度略快(直接索引): ```java Object val = listOfArrays.get(0)[1]; // 直接通过偏移量访问 ``` - 集合访问需要调用方法(如$\text{get()}$): ```java Object val = nestedList.get(0).get(1); // 涉及方法调用 ``` --- ### 四、相互转换方法 通过流操作或循环实现类转换: ```java // List<List<Object>> → List<Object[]> List<Object[]> convertedArrays = nestedList.stream() .map(list -> list.toArray(new Object[0])) .collect(Collectors.toList()); // List<Object[]> → List<List<Object>> List<List<Object>> convertedLists = listOfArrays.stream() .map(array -> new ArrayList<>(Arrays.asList(array))) .collect(Collectors.toList()); ``` --- ### 五、使用场景建议 - **优先选择 $\text{List<List<Object>>}$**: - 需要动态调整内层集合大小(如逐行读取不确定列数的CSV) - 涉及频繁插入/删除操作(如树形菜单数据) - **优先选择 $\text{List<Object[]>}$**: - 处理固定格式数据(如数据库查询结果的行记录) - 需要内存连续性优化(如科学计算中的矩阵存储) - 与遗留代码或需要数组的API交互(如JDBC批量操作) --- ### 六、总结 二者本质区别与C#类似,但需注意 **Java擦除** 和 **数组协变特性** 带来的影响。若需高性能和固定结构,选择数组形式;若需灵活操作,选择嵌套集合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值