在 Java 和 Groovy 中创建和初始化列表

先在 Java 中,然后在 Groovy 中创建和初始化一个整数列表。
29 位读者喜欢这篇文章。
3 cool machine learning projects using TensorFlow and the Raspberry Pi

Opensource.com

我非常喜欢 Groovy 编程语言。我喜欢它,因为归根结底,我喜欢 Java,即使 Java 有时感觉笨拙。而且因为我如此喜欢 Java,我并没有发现许多其他 JVM 语言特别有吸引力。例如,Kotlin、Scala 和 Clojure 与 Java 的感觉不太相似,它们追求自己对优秀编程语言的看法。Groovy 则不同;在我看来,当一位喜欢 Java 的程序员只需要一些更灵活、更紧凑,有时甚至更直接的东西时,Groovy 是完美的解药。

List 数据结构就是一个很好的例子,它用于保存数字、字符串或对象的有序列表,并允许程序员以高效的方式迭代这些项目。特别是对于编写和维护脚本的人来说,“效率”主要在于清晰简洁的表达,而不需要一堆仪式化的东西来掩盖代码的意图。

安装 Java 和 Groovy

Groovy 基于 Java,也需要安装 Java。您 Linux 发行版的软件仓库中可能同时包含最新且不错的 Java 和 Groovy 版本。否则,您可以按照这些说明安装 Groovy。对于 Linux 用户来说,SDKMan 是一个不错的替代方案,它可以用于获取多个版本的 Java、Groovy 和许多其他相关工具。在本文中,我使用 SDK 发布的以下版本:

  • Java:OpenJDK 11 的 11.0.12-open 版本
  • Groovy:3.0.8 版本

回到问题

自 Java 列表首次引入以来(我认为那是 Java 1.5,但请不要引用我的话),Java 中已经有多种实例化和初始化列表的方法。目前有两种有趣的方法涉及两个不同的库:java.util.Arraysjava.util.List

使用 java.util.Arrays

java.util.Arrays 定义了静态方法 asList(),该方法可用于创建一个由数组支持的列表,因此也是不可变的,尽管其元素是可变的。以下是它的实际应用:

var a1 = Arrays.asList(1,2,3,4,5,6,7,8,9,10); // immutable list of mutable elements

System.out.println("a1 = " + a1);
System.out.println("a1 is an instance of " + a1.getClass());

// output is
// a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// a1 is an instance of class java.util.Arrays$ArrayList

a1.set(0,0); // succeeds
System.out.println("a1 = " + a1); // output is
// a1 = [0, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a1.add(11); // fails producing
// Exception in thread "main" java.lang.UnsupportedOperationException
System.out.println("a1 = " + a1); // not reached

使用 java.util.List

java.util.List 定义了静态方法 of()。该方法可用于创建一个不可变列表,其元素可能是可变的,也可能不是可变的,这取决于元素列表中的项目是否是不可变的。以下是此版本的实际应用:

var a2 = List.of(1,2,3,4,5,6,7,8,9,10);

System.out.println("a2 = " + a2);
System.out.println("a2 is an instance of " + a2.getClass());

// output is
// a2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// a2 is an instance of class java.util.ImmutableCollections$ListN

a2.set(0,0); // fails producing
// Exception in thread "main" java.lang.UnsupportedOperationException
System.out.println("a2 = " + a2); // not reached

a2.add(11); // also fails for same reason if above two lines commented out
System.out.println("a2 = " + a2); // not reached

因此,如果我想要一个不能增长(或缩小)并且可能具有或不具有可变元素的列表,我可以使用 Arrays.asList()List.of()

如果我想要一个初始化的可变列表,我可能会求助于使用这些不可变类型的列表作为列表构造函数的参数,例如

var a1 = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));

System.out.println("a1 = " + a1);
System.out.println("a1 is an instance of " + a1.getClass());

// output is
// a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// a1 is an instance of class java.util.ArrayList

a1.set(0,0);
System.out.println("a1 = " + a1);

//output is
// a1 = [0, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a1.add(11);
System.out.println("a1 = " + a1);

// output is
// a1 = [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

请注意,Arrays.AsList() 用于初始化新的 ArrayList<Integer>(),它创建了参数的可变副本。

现在可能只是我个人感觉,但这似乎需要了解关于 java.util.Arraysjava.util.List 细节的大量理论——仅仅为了创建和初始化一个整数的可变列表,尽管实际使用的语句并不过于“仪式化”。再次列出如下,仅供参考:

var a1 = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5,6,7,8,9,10));

Groovy 方法

以下是上述内容的 Groovy 版本:

def a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

println "a1 = $a1"
println "a1 is an instance of ${a1.getClass()}"

// output is
// a1 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// a1 is an instance of class java.util.ArrayList

a1[0] = 0
println "a1 = $a1"

// output is
// a1 = [0, 2, 3, 4, 5, 6, 7, 8, 9, 10]

a1 << 11
println "a1 = $a1"

// output is
// a1 = [0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

乍一看,Groovy 使用 def 关键字而不是 var。我也知道,我可以通过在方括号之间放置一个事物列表(在本例中为整数)来创建列表表示。此外,这样创建的列表实例正是我想要的:ArrayList 的可变实例。

现在可能又只是我个人感觉,但上面这个方法似乎要简单得多——无需记住 .of().asList() 返回的半不可变结果并进行补偿。同样令人高兴的是,我可以使用带索引值的方括号来引用列表的特定元素,而不是方法调用 set(),并且 << 运算符会追加到列表的末尾,这样我就不必使用方法调用 add()。此外,您是否注意到缺少分号?是的,在 Groovy 中,它们是可选的。最后,请注意字符串插值的使用,双引号字符串内的 $variable${expression} 提供了该功能。

在 Groovy 世界中,“底层”还有更多内容。该定义是动态类型(Groovy 中的默认类型)与 Java 的静态类型的一个例子。在 Groovy 定义行中,a1 的类型是在运行时从右侧评估的表达式的类型推断出来的。现在我们都知道,动态编程语言赋予我们强大的力量,而强大的力量也带来了许多搞砸的好机会。但是对于不喜欢动态类型的程序员来说,Groovy 提供了静态类型的选项。

Groovy 资源

我在开头提到的 Apache Groovy 网站有很多很棒的文档。另一个优秀的 Groovy 资源是 Mr. Haki。学习 Groovy 的一个真正的好理由是继续学习 Grails,这是一个非常高效的全栈 Web 框架,它构建在 Hibernate、Spring Boot 和 Micronaut 等优秀组件之上。

本文献给我在 2022 年 1 月 3 日去世的挚友 Anil Mukhi。感谢 Anil,让我有机会学习这么多关于 Groovy、Grails 和赛马数据的知识。

接下来阅读什么
标签
Chris Hermansen portrait Temuco Chile
自从 1978 年毕业于不列颠哥伦比亚大学以来,我几乎总是离不开某种计算机。自 2005 年以来,我一直是全职 Linux 用户,从 1986 年到 2005 年是全职 Solaris 和 SunOS 用户,在此之前是 UNIX System V 用户。

评论已关闭。

© . All rights reserved.