Java:是否等效于Python的range(int,int)?


99

Java是否具有等效于Python range(int, int)方法的方法?


您是说返回列表的Python 2.x范围,还是返回迭代器的Python 3.x范围(相当于2.x xrange)?前者的实现相对简单,就像其他人在下面所做的那样,但是迭代器版本则比较棘手。
戴夫·柯比


对于范围内的任何的Comparable看看这个答案
c0der

对于步进范围看
斯瓦沃米尔Lenart

Answers:


27

Guava还提供类似于Python的东西range

Range.closed(1, 5).asSet(DiscreteDomains.integers());

您也可以使用Guava的AbstractIterator实现一个相当简单的迭代器来执行相同的操作:

return new AbstractIterator<Integer>() {
  int next = getStart();

  @Override protected Integer computeNext() {
    if (isBeyondEnd(next)) {
      return endOfData();
    }
    Integer result = next;
    next = next + getStep();
    return result;
  }
};

6
我希望在实现自己的通用范围之前已经看到了这一点。很好,但又提醒我们可以将笨拙的Java与功能更多的语言进行比较。
z7sg

14
Range#asSet似乎已经过时了。您现在需要执行以下操作:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Chthonic Project 2013年

我需要导入哪个库才能使用此库?
tgabb

从Java 8开始,IntStream和LongStream具有range和rangeClosed方法。
何塞·曼努埃尔·戈麦斯·阿尔瓦雷斯


16

从Guava 15.0开始,Range.asSet()已被弃用,并计划在版本16中删除。请改用以下命令:

ContiguousSet.create(Range.closed(1, 5), DiscreteDomain.integers());

15

我正在研究一个名为Jools的 Java utils小库,它包含一个Range提供所需功能的类(有一个可下载的JAR)。
构造函数可以是Range(int stop)Range(int start, int stop)Range(int start, int stop, int step)(类似于for循环),您可以对其进行迭代(使用惰性求值),也可以使用其toList()方法显式获取范围列表。

for (int i : new Range(10)) {...} // i = 0,1,2,3,4,5,6,7,8,9

for (int i : new Range(4,10)) {...} // i = 4,5,6,7,8,9

for (int i : new Range(0,10,2)) {...} // i = 0,2,4,6,8

Range range = new Range(0,10,2);
range.toList(); // [0,2,4,6,8]

14
public int[] range(int start, int stop)
{
   int[] result = new int[stop-start];

   for(int i=0;i<stop-start;i++)
      result[i] = start+i;

   return result;
}

原谅任何语法或样式错误;我通常使用C#编程。


鉴于Vivien Barousse击败了您,您为什么不删除自己的副本以避免重复。除非您真的打算将其充实。
aaronasterling

9
它们是相似的。我认为我的可读性更高。他对“长度”的使用具有误导性,而且我认为他不符合Python规范(他包含上限,network-theory.co.uk / docs / pytut / rangeFunction.html表示该上限不在Python中发生)。如果您认为自己是骗子,我相信您有足够的声誉亲自应对。
KeithS

10

您可以使用以下代码段来获取一组整数范围:

    Set<Integer> iset = IntStream.rangeClosed(1, 5).boxed().collect
            (Collectors.toSet());

7
public int[] range(int start, int length) {
    int[] range = new int[length - start + 1];
    for (int i = start; i <= length; i++) {
        range[i - start] = i;
    }
    return range;
}

(长回答只是说“不”)


另外,请参见python 3中的“ range”和Python 2中的首选“ xrange”返回一个“活动”对象,该对象不会为它包含的每个项目用尽内存。用Java实现的范围甚至更大。
jsbueno

3

Java 9- IntStream::iterate

从Java 9开始,您可以使用IntStream::iterate,甚至可以自定义步骤。例如,如果要int数组:

public static int[] getInRange(final int min, final int max, final int step) {
    return IntStream.iterate(min, i -> i < max, i -> i + step)
            .toArray();
}

List

public static List<Integer> getInRange(final int min, final int max, final int step) {
    return IntStream.iterate(min, i -> i < max, i -> i + step)
            .boxed()
            .collect(Collectors.toList());
}

然后使用它:

int[] range = getInRange(0, 10, 1);



1

如果您打算像在Python循环中那样使用它,则Java会使用for语句很好地循环,这使此结构不必要。


5
您通常也不会将其用于python中的循环。几乎总是有一种更干净的迭代方式。
Daenyth's

好吧,范围通常用于for循环中。但是for循环经常在没有范围的情况下使用。
FogleBird 2010年


0

我知道这是一篇老文章,但是如果您正在寻找一种返回对象流并且不希望或不能使用任何其他依赖项的解决方案,请执行以下操作:

Stream.iterate(start, n -> n + 1).limit(stop);

开始 -包容性停止 - 包容性

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.