Java异构容器

目录

同构容器

异构容器

代码示例


前在阅读【Effective Java(第三版)】的泛型时,书中提到过异构容器与同构容器,这里单独简单记录一下。

同构容器

Java中基础提供的,Set<E>、Map<K, V>、List<E>几种常用的集合,以及ThreadLocal<T>、AtomicReference<V>这种单元数类型容器,它们的类型都是在创建时就已经确定好了的,存放的空间是被参数化的容器,这样就限制了每个容器只有固定数目的类型参数,所以叫同构容器。特点是容器参数化。

异构容器

书中提到,数据库数据每行有多列,如果希望用类型安全的方式来访问所有列。(这里不要理解成日常数据库业务开发方向,当成数据库操作底层提供的jar包、或者动态结构,理解起来可能会更贴切)这时与同构容器相比,拥有更灵活的设定,就是Key参数化,然后将参数化的Key值交给容器进行存入或者取出。用泛型来保障值得类型与Key相匹配。

※这里的键值与Map的键值有些不一样,Map的键值,值的类型是固定的,就算定义Object,取出之后还是需要各自进行类型转换,而异构容器的值取出之后直接就是存入的类型,不需要再次转换。

代码示例

/**
 * @author xuwejsnj
 * @description: 异构容器,简单版,缺点:每种类型只能存放一个
 * @date 2021/7/5
 */
public class ClassContainerByType {
    private static Map<Class<?>, Object> container = new HashMap<>();
    public static <T> void addClass(Class<T> clz, T value) {
        container.put(clz, value);
    }
    public static <T> T getClass(Class<T> clz) {
        return clz.cast(container.get(clz));
    }
    public static void main(String[] args) {
        ClassContainerByType.addClass(Student.class, new Student("1", "xuwS"));
        ClassContainerByType.addClass(Teacher.class, new Teacher("2", "xuwT"));
        ClassContainerByType.addClass(Teacher.class, new Teacher("3", "xuwT3"));
        System.out.println(ClassContainerByType.getClass(Student.class));
        System.out.println(ClassContainerByType.getClass(Teacher.class));
    }
}

@Data
@ToString
@AllArgsConstructor
public class Student {
    private String sid;
    private String name;
}

@Data
@ToString
@AllArgsConstructor
public class Teacher {
    private String tid;
    private String name;
}

--------打印结果
Student(sid=1, name=xuwS)
Teacher(tid=3, name=xuwT3)
/**
 * @author xuwejsnj
 * @description: 异构容器,利用钩子,让同类型元素可以同时存放多个
 * @date 2021/7/5
 */
public class ClassContainerByKey {
    private static Map<Key<?>, Object> container = new HashMap<>();
    public static <T> void addClass(Key<T> key, Object value) {
        container.put(key, value);
    }
    public static <T> T getClass(Key<T> key) {
        return key.getClz().cast(container.get(key));
    }
    public static void main(String[] args) {
        ClassContainerByKey.addClass(new Key<>("s1", Student.class), new Student("1", "xuwS"));
        ClassContainerByKey.addClass(new Key<>("t1", Teacher.class), new Teacher("2", "xuwT"));
        ClassContainerByKey.addClass(new Key<>("t2", Teacher.class), new Teacher("3", "xuwT3"));
        System.out.println(ClassContainerByKey.getClass(new Key<>("s1", Student.class)));
        System.out.println(ClassContainerByKey.getClass(new Key<>("t1", Teacher.class)));
        System.out.println(ClassContainerByKey.getClass(new Key<>("t2", Teacher.class)));
    }
}

@Data
@ToString
@AllArgsConstructor
@EqualsAndHashCode
public class Key<T> {
    private String name;
    private Class<T> clz;
    public Class<T> getClz() {
        return clz;
    }
}


-----------打印结果
Student(sid=1, name=xuwS)
Teacher(tid=2, name=xuwT)
Teacher(tid=3, name=xuwT3)

关于异构容器使用场景猜想

一般的业务开发中很少有场景需要运用到异构容器。Java都是强类型指定,一般运用中不太会遇到需要动态多类型存放的业务场景。

可能在做一些中间件组件时、或者云平台存放不同公司各自制定数据类型时会涉及吧。但是现在一般都会利用Redis,制定好Key的规则,不同类型的数据直接大Json存放,取出之后也是各自的业务逻辑,自己转换类型吧。本文仅做扩展了解就行。

本文技术菜鸟个人学习使用,如有不正欢迎指出修正。xuweijsnj

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值