Java: เทียบเท่ากับช่วงของ Python (int, int)?


99

Java มีคุณสมบัติเทียบเท่ากับrange(int, int)เมธอดของ Python หรือไม่?


คุณหมายถึงช่วง Python 2.x ที่ส่งคืนรายการหรือช่วง Python 3.x ที่ส่งคืนตัววนซ้ำ (เทียบเท่ากับ 2.x xrange)? ก่อนหน้านี้ใช้งานได้ค่อนข้างง่ายเหมือนที่คนอื่น ๆ ทำไว้ด้านล่าง แต่เวอร์ชันตัววนซ้ำนั้นค่อนข้างยุ่งยากกว่าเล็กน้อย
Dave Kirby


สำหรับช่วงใด ๆComparableโปรดดูคำตอบนี้
c0der

สำหรับช่วงที่มีการก้าวเห็นนี้
Sławomir Lenart

คำตอบ:


27

Guavaยังให้สิ่งที่คล้ายกับ Python range:

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

คุณยังสามารถใช้ iterator ที่ค่อนข้างง่ายเพื่อทำสิ่งเดียวกันโดยใช้ AbstractIterator ของ Guava:

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

ฉันต้องนำเข้าไลบรารีใดเพื่อใช้สิ่งนี้
tgabb

จาก Java 8, IntStream และ LongStream มีช่วงเมธอดและ rangeClosed
Jose Manuel Gomez Alvarez

231

คำถามเก่าคำตอบใหม่ (สำหรับ Java 8)

    IntStream.range(0, 10).forEach(
        n -> {
            System.out.println(n);
        }
    );

หรือด้วยการอ้างอิงวิธีการ:

IntStream.range(0, 10).forEach(System.out::println);

1
แพ็คเกจอะไร ฉันจะนำเข้าได้อย่างไร
Justin Thomas

6
@ จัสตินนั่นคือคุณสมบัติภาษา java 8
Tzafrir


16

ฉันกำลังทำงานกับไลบรารียูทิลิตี้ Java ชื่อJoolsและมีคลาสRangeที่ให้ฟังก์ชันที่คุณต้องการ (มี JAR ที่ดาวน์โหลดได้)
ก่อสร้างมีทั้งRange(int stop), Range(int start, int stop)หรือRange(int start, int stop, int step)(คล้ายกับการวน) และคุณสามารถย้ำผ่านมันซึ่งใช้ในการประเมินผลขี้เกียจหรือคุณสามารถใช้มัน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]

16

ตั้งแต่ Guava 15.0, Range.asSet ()ได้เลิกใช้งานและมีกำหนดจะลบออกในเวอร์ชัน 16 ใช้สิ่งต่อไปนี้แทน:

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

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

11

คุณสามารถใช้ข้อมูลโค้ดต่อไปนี้เพื่อรับชุดจำนวนเต็มช่วง:

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

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

(ตอบยาวแค่ว่า "ไม่")


นอกจากนี้โปรดดูว่า "range" ใน python 3 และ "xrange" ที่ต้องการใน Python 2 ส่งคืนอ็อบเจ็กต์ "live" ที่ไม่ใช้หน่วยความจำสำหรับแต่ละรายการที่มีอยู่ นั่นจะยิ่งใหญ่กว่าในการนำไปใช้ใน Java
jsbueno

3

จาวา 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);


2

ไลบรารี "Functional Java" อนุญาตให้เขียนโปรแกรมในลักษณะที่ จำกัด ได้โดยมีวิธี range () ที่สร้างอินสแตนซ์ fj.data.Array

ดู:

ในทำนองเดียวกันห้องสมุด "Totally Lazy" มีวิธีการช่วงขี้เกียจ: http://code.google.com/p/totallylazy/


1

หากคุณต้องการใช้มันเหมือนที่คุณทำในลูป Python Java จะวนซ้ำกับคำสั่ง for ซึ่งทำให้โครงสร้างนี้ไม่จำเป็นสำหรับจุดประสงค์นั้น


5
โดยปกติคุณจะไม่ใช้มันสำหรับการวนซ้ำใน python เช่นกัน มีวิธีที่สะอาดกว่าในการทำซ้ำเกือบทุกครั้ง
Daenyth

โดยปกติแล้ว range จะใช้ในการวนซ้ำ แต่สำหรับลูปมักใช้แบบไม่มีช่วง
FogleBird


0

ฉันรู้ว่านี่เป็นโพสต์เก่า แต่หากคุณกำลังมองหาวิธีแก้ปัญหาที่ส่งคืนสตรีมวัตถุและไม่ต้องการหรือไม่สามารถใช้การอ้างอิงเพิ่มเติมใด ๆ :

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

เริ่ม - หยุดรวม - พิเศษ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.