Java: Tương đương với phạm vi của Python (int, int)?


99

Java có tương đương với range(int, int)phương thức của Python không?


Ý bạn là phạm vi Python 2.x trả về danh sách hay phạm vi Python 3.x trả về trình lặp (tương đương với 2.x xrange)? Phiên bản trước tương đối đơn giản để thực hiện như những người khác đã làm bên dưới, nhưng phiên bản trình lặp lại phức tạp hơn một chút.
Dave Kirby


Đối với phạm vi bất kỳ Comparable, hãy xem câu trả lời này
c0der

Đối với một phạm vi với stepping thấy này
Sławomir Lenart

Câu trả lời:


27

Ổi cũng cung cấp một cái gì đó tương tự như Python range:

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

Bạn cũng có thể triển khai một trình lặp khá đơn giản để làm điều tương tự bằng cách sử dụng AbstractIterator của 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
Tôi ước tôi đã thấy điều này trước khi tôi triển khai phạm vi chung của riêng mình. Thật tuyệt nhưng vẫn là một lời nhắc nhở khác về việc Java có thể so sánh với nhiều ngôn ngữ chức năng hơn như thế nào.
z7sg Ѫ

14
Range#asSetdường như đã trở nên không được chấp nhận. Bây giờ bạn cần phải làm điều này:ContiguousSet.create(Range.closed(low, high), DiscreteDomain.integers())
Chthonic Dự án

Tôi cần nhập thư viện nào để sử dụng cái này?
tgabb 24/09/17

Từ Java 8, IntStream và LongStream có phạm vi phương thức và phạm vi đóng gói.
Jose Manuel Gomez Alvarez,


16

Kể từ Guava 15.0, Range.asSet () đã không còn được dùng nữa và được lên lịch để xóa trong phiên bản 16. Thay vào đó, hãy sử dụng cách sau:

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

15

Tôi đang làm việc trên một thư viện Java utils nhỏ có tên Jools , và nó chứa một lớp Rangecung cấp chức năng bạn cần (có một JAR có thể tải xuống).
Constructors là một trong hai Range(int stop), Range(int start, int stop)hoặc Range(int start, int stop, int step)(tương tự như một vòng lặp for) và bạn có thể lặp qua nó, mà sử dụng đánh giá lười biếng, hoặc bạn có thể sử dụng nó toList()phương pháp để rõ ràng có được danh sách phạm vi.

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

Tha thứ cho bất kỳ lỗi cú pháp hoặc kiểu dáng nào; Tôi thường lập trình bằng C #.


cho rằng Vivien Barousse đã đánh bại bạn để trả lời, tại sao bạn không xóa của bạn để tránh bất kỳ sự trùng lặp nào. Tất nhiên, trừ khi bạn thực sự định làm thịt nó một cách độc đáo.
aaronasterling 24/09/10

9
Chúng giống nhau; Tôi nghĩ của tôi dễ đọc hơn một chút. Việc sử dụng "độ dài" của anh ấy là gây hiểu lầm và tôi không nghĩ rằng anh ấy đáp ứng thông số kỹ thuật của Python (anh ấy bao gồm giới hạn trên, điều mà network-theory.co.uk/docs/pytut/rangeFunction.html nói là không xảy ra trong Python ). Nếu bạn nghĩ ai đó là một trò lừa đảo, tôi tin rằng bạn có đủ uy tín để tự mình đối phó với nó.
KeithS

10

Bạn có thể sử dụng đoạn mã sau để có được một tập hợp các số nguyên:

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

(Câu trả lời dài chỉ để nói "Không")


Ngoài ra, hãy xem "phạm vi" trong python 3 và "xrange" được ưu tiên trong Python 2 trả về đối tượng "sống" không sử dụng hết bộ nhớ cho mỗi mục mà nó chứa. Điều đó thậm chí còn lớn hơn để triển khai trong Java.
jsbueno

3

Java 9 - IntStream::iterate

Kể từ Java 9, bạn có thể sử dụng IntStream::iteratevà thậm chí bạn có thể tùy chỉnh bước. Ví dụ: nếu bạn muốn intmảng:

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

hoặc 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());
}

Và sau đó sử dụng nó:

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

2

Lớp Range tiện lợi của Groovy có thể được sử dụng từ Java, mặc dù nó chắc chắn không đẹp bằng.



1

Nếu bạn muốn sử dụng nó như cách bạn làm trong vòng lặp Python, Java sẽ lặp lại một cách độc đáo với câu lệnh for, điều này khiến cấu trúc này không cần thiết cho mục đích đó.


5
Bạn cũng không thường sử dụng nó cho một vòng lặp trong python. Hầu như luôn có một cách tốt hơn để lặp lại.
Daenyth 24/09/10

Vâng, dải ô thường được sử dụng trong vòng lặp for. Nhưng vòng lặp for thường được sử dụng mà không có phạm vi.
FogleBird

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

1
Sẽ hữu ích nếu bạn giải thích cách mã này giải quyết vấn đề.
Robert Columbia

0

Tôi biết đây là một bài đăng cũ nhưng nếu bạn đang tìm kiếm giải pháp trả về luồng đối tượng và không muốn hoặc không thể sử dụng bất kỳ phụ thuộc bổ sung nào:

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

bắt đầu - dừng bao gồm - độc quyền

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.