java 交替

动态展示您的课程

当我还是Java新手时,我记得当时以为应该有一种方法可以删除或隐藏我不想公开的类中的方法。 就像用private方法或类似方法覆盖public方法一样(哪种情况是不可能的,也不应该是不可能的)。 显然,今天我们都知道,通过暴露
interface

杜克大学和斯派尔露出另一张样子……

通过使用名为Alternating Interface Exposure的方案,我们可以动态地查看类的方法并输入安全类型,以便同一类可以强制实施应该使用的模式。

让我举个例子。 假设我们有一个Map构建器,可以在构建实际Map之前先相继添加键和值来调用它。 Alternating Interface Exposure方案使我们能够确保调用key()方法和value()的次数完全相同,并且只有在存在该调用时, build()方法才可调用(例如在IDE中可见)。键和值一样多。

我正在参与的开源项目Speedment中使用了Alternating Interface Exposure方案。 在Speedment中,例如,在构建类型安全的Tuple时使用该方案,随后在向TupleBuilder添加元素之后将构建该类型安全的Tuple 。 这样,如果我们编写TupleBuilder.builder().add("Meaning of Life).add(42).build() ,我们可以获得类型化的Tuple2<String, Integer> = {“生命的含义”,42} TupleBuilder.builder().add("Meaning of Life).add(42).build()

使用动态地图生成器

我在以前的一些文章中(例如这里 )多次写过关于Builder模式的文章,如果您不熟悉这个概念,我建议您在阅读之前重新阅读有关此问题的文章。

当前的任务是产生一个Map构建器,它使用许多上下文相关的接口动态地公开许多实现方法。 此外,构建器应在首次使用它们时“学习”其键/值类型,然后对其余条目实施相同类型的键/值。

这是一个示例,说明一旦开发人员如何在代码中使用该构建器:

public static void main(String[] args) {// Use the type safe builderMap<Integer, String> map = Maps.builder().key(1)                 // The key type is decided here for all following keys.value("One")           // The value type is decided here for all following values.key(2)                 // Must be the same or extend the first key type.value("Two")           // Must be the same type or extend the first value type.key(10).value("Zehn'") // And so on....build();               // Creates the map!// Create an empty mapMap<String, Integer> map2 = Maps.builder().build();}}

在上面的代码中,一旦我们开始通过调用key(1)使用Integer,构建器将仅接受作为Integer实例的其他键。 值也是如此。 一旦我们调用value("one") ,就只能使用作为String实例的对象。 例如,如果尝试写入value(42)而不是value("two") ,我们将立即在IDE中看到错误。 同样,当我们使用代码完成功能时,大多数IDE:都将能够自动选择合适的候选对象。

让我详细说明一下:

初次使用

使用方法Maps.builder()创建构建器,返回的初始视图允许我们调用:

  1. build()生成一个空的Map (如上面的第二个“空地图”示例)
  2. key(K key) ,该密钥将密钥添加到构建器并确定所有后续密钥的类型(= K)(例如上述key(1)

调用了初始key(K key) ,该构建器的另一个视图将显示为仅公开:

  1. value(V value) ,它向构建器添加一个值并为所有后续值确定类型(= V)(例如value("one")

注意,由于键和值的数量不同, build()方法不会在此状态下公开。 编写Map.builder().key(1) .build() ; 完全是非法的,因为没有与key 1关联的值。

后续用法

现在已经确定了键和值类型,构建器将根据要调用的key()value()在显示的两个交替接口之间进行切换。 如果调用key() ,则公开value() ;如果调用value() ,则公开key()build()

建造者

一旦确定类型,这是构建器使用的两个交替接口:

public interface KeyBuilder<K, V> {ValueBuilder<K, V> key(K k);Map<K, V> build();}
public interface ValueBuilder<K, V> {KeyBuilder<K, V> value(V v);}

请注意,一个接口如何返回另一个接口,从而导致暴露的交替接口无限流动。 这是使用交替接口的实际构建器:

public class Maps<K, V> implements KeyBuilder<K, V>, ValueBuilder<K, V> {private final List<Entry<K, V>> entries;private K lastKey;public Maps() {this.entries = new ArrayList<>();}@Overridepublic ValueBuilder<K, V> key(K k) {lastKey = k;return (ValueBuilder<K, V>) this;}@Overridepublic KeyBuilder<K, V> value(V v) {entries.add(new AbstractMap.SimpleEntry<>(lastKey, v));return (KeyBuilder<K, V>) this;}@Overridepublic Map<K, V> build() {return entries.stream().collect(toMap(Entry::getKey, Entry::getValue));}public static InitialKeyBuilder builder() {return new InitialKeyBuilder();}}

我们看到实现类实现了两个交替接口,但仅根据调用key()value()才返回其中一个。 我通过创建两个初始帮助类来“欺骗”一点,这两个初始帮助类负责尚未确定键和值类型的初始阶段。 为了完整起见,下面还显示了两个“欺诈”类:

public class InitialKeyBuilder {public <K> InitialValueBuilder<K> key(K k) {return new InitialValueBuilder<>(k);}public <K, V> Map<K, V> build() {return new HashMap<>();}}
public class InitialValueBuilder<K> {private final K k;public InitialValueBuilder(K k) {this.k = k;}public <V> KeyBuilder<K, V> value(V v) {return new Maps<K, V>().key(k).value(v);}}

后面的类以与主构建器类似的方式工作,即InitialKeyBuilder返回InitialValueBuilder ,而InitialValueBuilder创建一个类型化的构建器,该生成器可以通过交替返回KeyBuilderValueBuilder来无限期使用。

结论

当您需要类的类型安全和上下文感知模型时,“ 交替接口暴露”方案很有用。 您可以使用此方案为您的课程制定和实施许多规则。 这些类的使用将更加直观,因为上下文相关的模型及其类型一直传播到IDE。 该模式还提供了更强大的代码,因为在设计阶段的早期就发现了潜在的错误。 我们将在编码时看到潜在的错误,而不是失败的测试或应用程序错误。

翻译自: https://www.javacodegeeks.com/2016/03/java-8-type-safe-map-builder-using-alternating-interface-exposure.html

java 交替

java 交替_Java 8:使用交替接口公开的类型安全地图生成器相关推荐

  1. Java 8:使用交替接口公开的类型安全地图生成器

    动态展示您的课程 当我是Java新手时,我记得当时想过应该有一种方法可以删除或隐藏我不想公开的类中的方法. 就像用private方法或类似方法覆盖public方法一样(哪种情况是不可能的,也不应该是不 ...

  2. java 多线程 交替_java 多线程–线程交替

    要求: 借助同步机制,sleep()方法,join()方法,实现动画显示: 甲线程:1.3.5.7.9 乙线程:2.4.6.8.10 丙线程:a.b.c.d.e main()线程输出:线程开始,线程结 ...

  3. 【纯JAVA语言做RPG游戏】1.做个瓷砖地图生成器

    开个坑,想做个JAVA游戏. 虽然现在有着各种游戏引擎,使得做游戏的效率提高了很多,但是用着别人的代码来做感觉对自己也没啥提升,而且在游戏的模式上也不得不去迎合别人的思维,所以露珠准备应用前面学到的所 ...

  4. java多线程交替打印_使用Java实现三个线程交替打印0-74

    使用Java实现三个线程交替打印0-74 题目分析 三个线程交替打印,即3个线程是按顺序执行的.一个线程执行完之后,唤醒下一个线程,然后阻塞,等待被该线程的上一个线程唤醒.执行的顺序是一个环装的队列 ...

  5. predicate java 作用_Java函数式编程接口详解之Predicate

    一.初识 Predicate是Java提供的重要的函数编程接口之一,作用主要是用于逻辑判断. 首先看看源码: @FunctionalInterface public interface Predica ...

  6. java程序设计_Java程序设计--接口interface(笔记)

    有时必须从几个类中派生出一个子类,继承它们所有的属性和方法.但是,Java不支持多重继承.有了接口,就可以得到多重继承的效果. 有时必须从几个类中抽取出一些共同的行为特征,而它们之间又没有继承关系,仅 ...

  7. java 转账_JAVA实操项目:转账接口设计

    原标题:JAVA实操项目:转账接口设计 在一个项目中,一般都会支付相关的业务,而涉及到支付必定会有转账的操作,转账这一步想起来算是比较关键的部分,这个接口的设计能力,也大致体现出一个人的水平. 昨天碰 ...

  8. java用来创建数据库连接的接口是_Java操作数据库--JDBC

    简介 刚开始介绍了mysql基本语句,但是你会觉得好像不会知道怎么用,它的用途在什么地方,所以为了提高兴趣今天我们来介绍一下JDBC,以后会和MySQL一起更新. JDBC,到底jdbc是什么东西呢? ...

  9. java厨房_Java多线程基础

    目录: 进程和线程 为什么使用多线程? 多线程的创建方式 Runnable与Thread两种方式比较 start()与run()方法 线程的生命周期/状态转换 常用方法使用与解读 线程的优先级 守护线 ...

最新文章

  1. php微信开发例子,微信开发实战之知乎日报
  2. mysql 魔术设置_PHP之十六个魔术方法详细介绍
  3. 基于matlab的车牌定位算法设计与实现,matlab车牌定位系统设计(源码+文档)
  4. 编译动态库时报错relocation R_X86_64_32 against `.bss' can not be used when making a shared object; recompile
  5. 美检方或起诉刘强东;百度对呛微信规则;澳洲调查 Facebook | 极客头条
  6. 23种设计模式(9):访问者模式(转)
  7. Lenovo联想键盘关闭fn功能恢复F1-F12按键
  8. ubntu系统克隆到其他计算机的方法
  9. delphi 热部署_DelphiWebMVC微信公众号开发
  10. 完美解决 OneNote 笔记无法同步的问题
  11. 未授权访问漏洞测试方法及修复方案
  12. TestCenter测试管理工具功能详解十(O)
  13. 信诺科学计算机说明书,计算机科学技术专业简介(Introduction to computer science and technology).doc...
  14. 孩子教育,不要只看重分数!
  15. 深入了解Elasticsearch存储
  16. 儿童的31个“敏感期”特点及建议(转载)
  17. 【Python图形绘制】使用turtle库实现美国队长盾牌
  18. 视频教程-微信小程序电商实战-PHP
  19. Deep Supervision:深度监督(2014)+DHM
  20. Linux中的常用shell命令(一)

热门文章

  1. codeforces:812(div2):总结
  2. #20071-[NOIP2020模拟赛B组Day6]礼物购买【二分】
  3. 51nod-猴猴的比赛【莫队,线段树】
  4. 【二分】雪(luogu 7405)
  5. YL杯超级篮球赛(jzoj 1325)
  6. Spring 自动装配 ‘byType’
  7. Spring Bean 定义继承
  8. Java 程序员必须掌握的 5 个注解
  9. 如何合理的规划一次 JVM 性能调优
  10. java爬虫的2种爬取方式(HTTP||Socket)简单Demo(一)