ZetCode

Groovy 范围

最后修改于 2025 年 3 月 20 日

Groovy 中的范围使用 .. 操作符定义序列,支持数字、字符、日期等。它们是可迭代的,并提供操作方法。本教程通过实际示例探讨范围的创建和用法。

简单的数字范围

范围是使用开始值和结束值之间的两个点创建的,这是一种快速生成数字序列的方法。

SimpleRange.groovy
def range = 1..5
println range

1..5 创建一个包含 1 到 5 的范围。打印时,它显示为类似列表的序列 [1, 2, 3, 4, 5]。范围是 groovy.lang.IntRange 类型的对象,融合了简洁性和功能性。

$ groovy SimpleRange.groovy
[1, 2, 3, 4, 5]

循环中的范围

范围是可迭代的,使其非常适合循环处理序列,而无需手动列出每个元素。

RangeLoop.groovy
def range = 1..3

for (num in range) {
    println num
}

1..3for 循环中遍历 1、2、3,并打印每个数字。这展示了范围作为传统基于索引的循环的简洁替代方案,提高了可读性。

$ groovy RangeLoop.groovy
1
2
3

数字范围基础

数字范围具有 fromto 等属性,并且可以转换为列表,从而深入了解它们的结构。

NumericRangeBasics.groovy
def vals = 1..10
println vals.from
println vals.to
println vals.toList()

1..10 定义了一个包含的范围。from 返回 1(开始值),to 返回 10(结束值)。toList 将其转换为 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],显式列出所有值。这表明范围既是紧凑的对象,也是可扩展的序列。

$ groovy NumericRangeBasics.groovy
1
10
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

步进范围

step 方法生成一个具有指定增量的范围,允许您跳过序列中的值。

RangeStep.groovy
def vals2 = (1..7).step(2)
println vals2

(1..7).step(2) 从 1 开始,到 7 结束,步长为 2,生成 [1, 3, 5, 7]。它只包含每第二个值,在 7 或之前停止。此方法返回一个列表,提供了一种灵活的方式来定制范围的进展。

$ groovy RangeStep.groovy
[1, 3, 5, 7]

反向范围

通过颠倒开始和结束的顺序,范围可以向下计数,轻松创建降序序列。

ReverseRange.groovy
def vals3 = 10..1
println vals3

10..1 定义了一个从 10 到 1(包含)的范围,结果是 [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]。与升序范围不同,较大的数字在前,Groovy 会自动处理递减,简化了反向迭代。

$ groovy ReverseRange.groovy
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

排除范围

使用 ..<,范围可以排除上限,额外的 < 还可以排除下限,从而精确范围序列。

ExclusiveRange.groovy
def vals4 = 1..<10
println vals4.toList()

def vals5 = 1<..<10
println vals5.toList()

1..<10 包含 1 但排除 10,生成 [1, 2, 3, 4, 5, 6, 7, 8, 9]。1<..<10 排除两端,从 1 之后开始,在 10 之前停止,得到 [2, 3, 4, 5, 6, 7, 8, 9]。这些表示法提供了对范围边界的精确控制。

$ groovy ExclusiveRange.groovy
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 3, 4, 5, 6, 7, 8, 9]

字符范围

范围可以扩展到字符,创建字母序列,并提供检查和操作它们的方法,利用它们的序数值。

CharRange.groovy
def chars = 'a'..'z'
println chars 
println chars.size()
println chars.contains('c')
println chars.getFrom() 
println chars.getTo()

'a'..'z' 生成一个包含小写字母的范围 [a, b, c, ..., z]。size 返回 26,即字母的数量。contains('c') 检查包含(true)。getFromgetTo 返回 'a' 和 'z',即边界。这在内部使用字符码,使其对于字母序列来说非常直观。

$ groovy CharRange.groovy
[a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z]
26
true
a
z

日期和时间范围:月份

范围可以与 Month 等日期/时间类型一起使用,从而为基于日历的任务创建时间单位序列。

MonthRange.groovy
import java.time.Month

def months = Month.JANUARY..Month.DECEMBER

for (def m in months) {
    println m
}

Month.JANUARY..Month.DECEMBER 创建一个包含所有 12 个月的范围。for 循环进行迭代,从 JANUARY 打印到 DECEMBER。这利用了 Java 的 Month 枚举,展示了范围与数字和字符以外的有序类型的兼容性。

$ groovy MonthRange.groovy
JANUARY
FEBRUARY
MARCH
APRIL
MAY
JUNE
JULY
AUGUST
SEPTEMBER
OCTOBER
NOVEMBER
DECEMBER

日期和时间范围:天

范围可以跨越 LocalDate 对象,创建日期序列,用于基于日期的迭代,在调度或日志记录中很有用。

DayRange.groovy
import java.time.LocalDate

def days = LocalDate.now()..LocalDate.now().plusDays(17)

for (def d in days) {
    println d
}

LocalDate.now()..LocalDate.now().plusDays(17) 从今天到 17 天后(例如,2025 年 3 月 20 日至 2025 年 4 月 6 日)进行跨度。循环打印每一天,总共 18 天(包含)。输出因运行日期而异,但范围可以无缝地适应 LocalDate 的排序,简化了日期序列。

$ groovy DayRange.groovy  // Example for March 20, 2025
2025-03-20
2025-03-21
2025-03-22
[...continues...]
2025-04-05
2025-04-06

带负数的范围

范围可以包含负数,并保持与正数范围相同的包含或排除行为。

NegativeRange.groovy
def negRange = -3..2
println negRange.toList()

-3..2 创建一个包含 -3 到 2 的范围,结果是 [-3, -2, -1, 0, 1, 2]。这演示了范围对于任何整数边界的灵活性,升序或降序,扩大了它们的适用性。

$ groovy NegativeRange.groovy
[-3, -2, -1, 0, 1, 2]

来源

Groovy 文档

本教程通过实际示例探讨了 Groovy 范围。

作者

我的名字是 Jan Bodnar,我是一名充满热情的程序员,拥有丰富的编程经验。我自 2007 年以来一直在撰写编程文章。迄今为止,我已撰写了 1,400 多篇文章和 8 本电子书。我在教授编程方面拥有八年以上的经验。

列出 所有 Groovy 教程