在 Java 和 Groovy 中创建和初始化列表的不同
创始人
2024-03-02 10:24:01
0

首先在 Java 中创建初始化一个整数列表,然后在 Groovy 中做同样的事。

我非常喜欢 Groovy 编程语言。我喜欢它是因为我喜欢 Java,尽管 Java 有时候感觉很笨拙。正因为我是那么喜欢 Java,其他运行在 JVM 上语言都不能吸引我。比方说 Kotlin、Scala 还有 Clojure 语言,它们感觉上就和 Java 不一样,因为它们对于什么是好的编程语言的理解不同。Groovy 和它们都不一样,在我看来,Groovy 是一个完美的选项,特别是对于一部分程序员来说,他们喜欢 Java,但是又需要一个更灵活、更紧凑,并且有时候更直接的语言。

列表 List 这种数据结构是一个很好的例子,它可以容纳一个无序的列表,列表中的元素可以是数字、字符串或者对象,程序员可以用某种方式高效地遍历这些元素,特别是对于编写和维护脚本的人来说,“高效”的关键就是要有简洁清晰的表达,而不需要一大堆“仪式”,把代码的意图都变模糊了。

安装 Java 和 Groovy

Groovy 是基于 Java 的,因此需要同时安装一个 Java 才行。你的 Linux 发行版的仓库中可能有最近的比较好的 Java 版本。或者,你也可以在根据 这些指导 来安装 Groovy。对于 Linux 用户来说,SDKMan 是一个不错的代替选项,你可以使用它来获取多个 Java 和 Groovy 版本,以及许多其他的相关工具。在这篇文章中,我使用的 SDK 发行版是:

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

言归正传

Java 中有很多方法可以实例化并初始化列表,从它最初被引入的时候就有了(我记得是在 Java 1.5 的时候,但请不要引用我的话)。在这些方法里,有两个有趣的方法,它们涉及到了 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(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() 的,也就是说,它为这个传进来的列表创建了一个可变的拷贝。

现在,或许只有我这么想,但是这种方式确实看起来需要理解很多关于 java.util.Arraysjava.util.List 类的细节才行,而我只是想要创建并初始化一个数字列表而已(尽管真正使用到的语句并没有太多“仪式”)。下面是真正用到的那行代码,仅供参考:

var a1 = new ArrayList(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() 返回的是“ 半不变 semi-mutable ”的结果,也不用为它们做一些补偿。另外一个好处是,我现在可以使用括号和下标来引用列表中的某个特定元素,而不用这个叫 set() 方法。另外,这个跟在列表后面的 << 操作符也很方便,我再也不用调用 add() 方法来添加元素啦。还有,你注意到代码中没有分号了吗?没错,在 Groovy 里,句末的分号并不是必须的。最后,我们来看看字符串插值,只要在字符串里用 $变量 或者 ${表达式} 就可以实现了哦!

在 Groovy 世界中还藏着许多“有待发掘”的东西。上面的列表定义其实是一个动态类型(Groovy 中默认)和 Java 中的静态类型的对比。在上面的 Groovy 代码定义的那一行,变量 a1 的类型是在运行的时候,根据等号右边的表达式的计算结果推断出来的。现在我们都知道,动态语言可以给我们带来强大的功能,有了强大的功能,我们有了很多机会去尝试不同的东西。对于那些不喜欢动态类型的程序员来说,Groovy 也支持静态类型。

Groovy 相关资源

Apache Groovy 网站上有非常多的文档。另一个很棒的 Groovy 资源是 Mr. Haki。学习 Groovy 还有一个很棒的原因,那就是可以接着学习 Grails,后者是一个优秀的、高效率的全栈 Web 框架,基于许多优秀组件构建而成,比如有 Hibernate、Spring Boot 和 Micronaut 等。


via: https://opensource.com/article/22/1/creating-lists-groovy-java

作者:Chris Hermansen 选题:lujun9972 译者:lkxed 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

相关内容

怎么用AI做短视频赚钱?小...
嘿,你是不是也刷到过那些爆火的短视频,心想:“这玩意儿咋这么赚钱?...
2025-06-06 22:12:18
JAVA集合知识整理
Java集合知识整理 HashMap相关 HashMap的底层数据...
2025-06-01 22:12:08
安卓逆向高阶之frida ...
文章目录1. 初次hook Java 层函数2. hook 修改函...
2025-06-01 20:46:39
【Java基础面试宝典】h...
目录 hashCode和equals之间的关系 final关键字的...
2025-06-01 18:07:56
Java开发一年不到,来面...
前言 我的好朋友兼大学同学老伍家庭经济情况不错,毕业...
2025-06-01 15:50:23
java LinkedHa...
目录 一、前言 二、LinkedHashSet简介 三、Linke...
2025-06-01 14:58:51

热门资讯

Helix:高级 Linux ... 说到 基于终端的文本编辑器,通常 Vim、Emacs 和 Nano 受到了关注。这并不意味着没有其他...
使用 KRAWL 扫描 Kub... 用 KRAWL 脚本来识别 Kubernetes Pod 和容器中的错误。当你使用 Kubernet...
JStock:Linux 上不... 如果你在股票市场做投资,那么你可能非常清楚投资组合管理计划有多重要。管理投资组合的目标是依据你能承受...
通过 SaltStack 管理... 我在搜索Puppet的替代品时,偶然间碰到了Salt。我喜欢puppet,但是我又爱上Salt了:)...
Epic 游戏商店现在可在 S... 现在可以在 Steam Deck 上运行 Epic 游戏商店了,几乎无懈可击! 但是,它是非官方的。...
《Apex 英雄》正式可在 S... 《Apex 英雄》现已通过 Steam Deck 验证,这使其成为支持 Linux 的顶级多人游戏之...
如何在 Github 上创建一... 学习如何复刻一个仓库,进行更改,并要求维护人员审查并合并它。你知道如何使用 git 了,你有一个 G...
2024 开年,LLUG 和你... Hi,Linuxer,2024 新年伊始,不知道你是否已经准备好迎接新的一年~ 2024 年,Lin...
什么是 KDE Connect... 什么是 KDE Connect?它的主要特性是什么?它应该如何安装?本文提供了基本的使用指南。科技日...
Opera 浏览器内置的 VP... 昨天我们报道过 Opera 浏览器内置了 VPN 服务,用户打开它可以防止他们的在线活动被窥视。不过...