Java: Python'un aralığına eşdeğer (int, int)?


99

Java'nın Python range(int, int)yöntemine bir eşdeğeri var mı ?


Bir liste döndüren bir Python 2.x aralığını mı yoksa bir yineleyici (2.x xrange'ye eşdeğer) döndüren bir Python 3.x aralığını mı kastediyorsunuz? Birincisinin uygulanması, aşağıda diğerlerinin yaptığı gibi nispeten basittir, ancak yineleyici sürümü biraz daha zordur.
Dave Kirby


Herhangi bir aralık Comparableiçin bu yanıta bakın
c0der

Adımlamayla bir aralık için bkz bu
Sławomir Lenart

Yanıtlar:


27

Guava ayrıca Python'unkine benzer bir şey sağlar range:

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

Guava'nın AbstractIterator'ını kullanarak aynı tür şeyleri yapmak için oldukça basit bir yineleyici de uygulayabilirsiniz:

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
Keşke bunu kendi jenerik aralığımı uygulamadan önce görmüş olsaydım. Güzel ama yine de Java'nın daha işlevsel dillerle ne kadar hantal olabileceğinin bir başka hatırlatıcısı.
z7sg Ѫ

14
Range#asSetkullanımdan kaldırılmış gibi görünüyor. Şimdi bunu yapmanız gerekiyor:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Chthonic Projesi

bunu kullanmak için hangi kitaplığı içe aktarmam gerekiyor?
tgabb

Java 8'den IntStream ve LongStream, range ve rangeClosed yöntemlerine sahiptir.
Jose Manuel Gomez Alvarez


16

Guava 15.0'dan beri, Range.asSet () kullanımdan kaldırıldı ve 16 sürümünde kaldırılması planlandı. Bunun yerine aşağıdakileri kullanın:

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

15

Jools adında küçük bir Java araçları kitaplığı üzerinde çalışıyorum ve içinde Rangeihtiyacınız olan işlevselliği sağlayan bir sınıf var (indirilebilir bir JAR var).
Yapıcılar ya vardır Range(int stop), Range(int start, int stop)ya da Range(int start, int stop, int step)(döngü için similiar) ve tembel değerlendirme kullanılan hangi içinden ya iterate can veya onun kullanabilirsiniz toList()açıkça aralık listesini almak için yöntem.

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;
}

Sözdizimi veya stil hatalarını affedin; Normalde C # ile programlıyorum.


Vivien Barousse'un sizi bir cevaba kadar dövdüğü göz önüne alındığında, neden herhangi bir dupden kaçınmak için kendi yanıtınızı silmiyorsunuz? Tabii ki güzel bir şekilde anlatmayı planlamıyorsanız.
aaronasterling

9
Benzerler; Sanırım benimki biraz daha okunaklı. "Uzunluk" kullanımı yanıltıcıdır ve Python spesifikasyonunu karşıladığını sanmıyorum ( network-theory.co.uk/docs/pytut/rangeFunction.html'nin Python'da olmadığını söylediği üst sınırı içerir. ). Birinin kukla olduğunu düşünüyorsan, bununla tek başına başa çıkacak kadar itibara sahip olduğuna inanıyorum.
KeithS

10

Bir dizi tam sayı elde etmek için aşağıdaki kod parçacığını kullanabilirsiniz:

    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;
}

(Sadece "Hayır" demek için uzun cevap)


Ayrıca, python 3'teki "aralık" ın ve Python 2'deki tercih edilen "xrange" ın, içerdiği her öğe için bellek kullanmayan "canlı" bir nesne döndürdüğüne bakın. Java'da uygulanması daha da büyük olurdu.
jsbueno

3

Java 9 - IntStream::iterate

Java 9'dan beri kullanabilir IntStream::iterateve hatta adımı özelleştirebilirsiniz. Örneğin intdizi istiyorsanız :

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

veya 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());
}

Ve sonra onu kullanın:

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



1

Bir Python döngüsünde olduğu gibi kullanmak istiyorsanız, Java, bu yapıyı bu amaç için gereksiz kılan for deyimiyle güzel bir şekilde döngüye girer.


5
Genellikle python'da bir döngü için de kullanmazsınız. Neredeyse her zaman yinelemenin daha temiz bir yolu vardır.
Daenyth

Aralık genellikle bir for döngüsünde kullanılır. Ancak döngüler için genellikle aralıksız kullanılır.
FogleBird

1
IntStream.range(0, 10).boxed().collect(Collectors.toUnmodifiableList());

1
Bu kodun sorunu nasıl çözdüğünü açıklamanız yardımcı olacaktır .
Robert Columbia

0

Bunun eski bir gönderi olduğunu biliyorum, ancak bir nesne akışı döndüren ve herhangi bir ek bağımlılık kullanmak istemeyen veya kullanamayan bir çözüm arıyorsanız:

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

başlangıç - kapsayıcı durdurma - özel

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.