当前位置: 首页 > 知识库问答 >
问题:

静态编程语言/Java:将多个项目添加到一次只允许一个. add()的Builder类

梁丘招
2023-03-14

问题:我在Kotlin中使用AWS DynamoDb增强的Java客户端V2(客户端的细节可能并不重要),在这里我想创建一个包含一堆请求的< code > BatchWriteItemEnhancedRequest 。根据文件,标准用法是:

val batchWriteItemEnhancedRequest = BatchWriteItemEnhancedRequest.builder()
    .addWriteBatch(
        WriteBatch.builder(MyClass::class.java)
            .mappedTableResource(myMappedTable)
            .addPutItem(putRequest1)
            .addPutItem(putRequest2)
            .addPutItem(putRequest3)
            .build()
    )
    .build()

< code>WriteBatch的生成器似乎不允许添加请求列表:doc

正如我所看到的,做到这一点的唯一方法是制作一个for循环:

var writeBatchBuilder = WriteBatch.builder(MyClass::class.java)
    .mappedTableResource(myMappedTable)

for (request in putItemRequests){
    writeBatchBuilder = writeBatchBuilder.addPutItem(request)
}

val writeBatch = writeBatchBuilder.build()

这对我来说似乎很可怕。必须有一种更惯用的方式来做到这一点,对吧?

共有2个答案

潘文乐
2023-03-14

在这种情况下,扩展函数函数可能会派上用场。让我们假设,WriteBatch.builder(MyClass::class.java具有类型WriteBatch.Builder可能带有一些泛型,这在示例中很难说。

val writeBatch = WriteBatch.builder(MyClass::class.java)
    .mappedTableResource(myMappedTable)
    .addItems(putItemRequests)
    .build()
// I did use Any for items type, change it according to your need
fun WriteBatch.Builder.addItems(items: List<Any>) {
    items.forEach { item -> addPutItem(item) }
}
洪永长
2023-03-14

给定< code>WriteBatch的实例。Builder,没有必要明确需要链接DSL,所以您的< code>writeBatchBuilder可以是一个< code>val。每个构建器函数都会改变< code>WriteBatch的内部状态。Builder实例,返回值只是为了方便起见——源代码。

因此,您可以简化您的for循环并使WriteBatchBuilder成为val

val writeBatchBuilder = WriteBatch.builder(MyClass::class.java)
    .mappedTableResource(myMappedTable)

for (request in putItemRequests){
    writeBatchBuilder.addPutItem(request)
}

val writeBatch = writeBatchBuilder.build()

更进一步,作用域函数是将JavaDSL转换为更静态编程语言的好方法。

< code>apply {}将转换创建的< code>WriteBatch。生成器到接收器中,这意味着您不需要为生成器准备一个变量,只需使用< code>this即可。

val writeBatch = WriteBatch.builder(MyClass::class.java).apply {
  mappedTableResource(myMappedTable)

  putItemRequests.forEach { request -> 
    addPutItem(request)
  }
}.build()

(我还将 for 循环更改为 forEach {} - 这更像是科特林-ey。

下一个改进是将应用{}逻辑封装在辅助函数WriteBatchBuilder()中,因此样板被隐藏起来,这使得重新使用该函数更容易。

使用inline具体化T意味着无需每次都定义::class.java-相反,类可以定义为类型参数,并且如果静态编程语言可以推断类型,则可以省略类。

请注意,builderarg的接收器是WriteBatch.Builder,就像应用{}范围函数如何将接收器更改为构建器一样。

inline fun <reified T> buildWriteBatch(
  builder: WriteBatch.Builder<T>.() -> Unit
) : WriteBatch<T> {
  return WriteBatch.builder(T::class.java).apply(builder).build()
}

示例用法:

val writeBatch = buildWriteBatch<MyClass> {
  mappedTableResource(myMappedTable)

  putItemRequests.forEach { request -> 
    addPutItem(request)
  }
}


// no need for explicit typing on buildWriteBatch - Kotlin can infer the type
val writeBatch2: WriteBatch<MyClass> = buildWriteBatch {}
 类似资料:
  • 问题内容: 我想使我的网站一次只允许一个会话。例如,假设用户已经登录到我在firefox上的网站,如果该用户再次登录到另一台浏览器(例如同一台计算机或另一台计算机上的Opera),则Firefox上的会话将被破坏。但是,如果仍为一届会议,则有关Firefox的会议仍将保留。我可以知道该怎么做吗?我正在使用php和apache。谢谢。 问候。本杰明 问题答案: 我建议您做这样的事情: 假设用户“ A

  • 问题内容: 我需要初始化一个常量HashMap,并希望在一行语句中完成它。避免这样的事情: 类似于目标C: 看了这么多,我还没有找到任何显示如何做到这一点的例子。 问题答案: 您可以使用 Double Brace初始化 ,如下所示: 作为警告,请参阅Java的效率效率“ Double BraceInitialization”,了解它可能带来的性能影响。

  • 正如标题所说,我正在尝试将Java和Kotlin混合在一个项目中。这里有一个很好的例子。混合java kotlin hello world。除了kotlin在src/main/Java/somepackage/SomeClass中找不到我的任何Java类之外,所有的东西都正常工作。Java语言 这是什么原因? 我的身材。gradle看起来像这样 而不是开始尝试在更大的项目上实现这一点。我试图通过创

  • 问题内容: 我需要防止用户多次启动我的Java应用程序(WebStart Swing应用程序)。因此,如果应用程序已经在运行,则应该无法再次启动它或显示警告/再次关闭它。 有一些方便的方法可以做到这一点吗?我考虑过要阻止端口或将某物写入文件。但是希望您可以访问某些系统属性或JVM? 顺便说一句 目标平台是带有Java 1.5的Windows XP 问题答案: 我认为您的建议是在启动应用程序时打开端

  • 我创建了一个版本.,就像这样: 现在我想像这样导入和使用该文件: 我该怎么做? 注意:我已经看到这篇文章,但它不完全是我搜索…

  • #include <stdio.h> #include <pthread.h> int a = 0; int b = 0; void *thread1_func(void *p_arg) { while (1) { a++; sleep(1); } } void *thread2_fu