Dostajesz tylko część tablicy w Javie?

275

Mam tablicę liczb całkowitych w Javie, chciałbym użyć tylko jej części. Wiem, że w Pythonie możesz zrobić coś takiego jak ta tablica [indeks:] i zwraca tablicę z indeksu. Czy coś takiego jest możliwe w Javie.

Borut Flis
źródło

Odpowiedzi:

444

Długość tablicy w Javie jest niezmienna. Musisz więc skopiować żądaną część jako nową tablicę.
Użyj copyOfRangemetody z klasy java.util.Arrays :

int[] newArray = Arrays.copyOfRange(oldArray, startIndex, endIndex);

startIndex jest początkowym indeksem zakresu do skopiowania, włącznie.
endIndex to końcowy indeks zakresu do skopiowania, wyłączny. (Ten indeks może leżeć poza tablicą)

Na przykład:

   //index   0   1   2   3   4
int[] arr = {10, 20, 30, 40, 50};
Arrays.copyOfRange(arr, 0, 2);          // returns {10, 20}
Arrays.copyOfRange(arr, 1, 4);          // returns {20, 30, 40}
Arrays.copyOfRange(arr, 2, arr.length); // returns {30, 40, 50} (length = 5)
elias
źródło
wydaje się, że istnieje limit rozmiaru? tylko to działa: Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)ponieważ zamiast 255 nie mogę użyć Integer.MAX_VALUE, na wypadek, gdybym nie chciał uzyskać rzeczywistej długości
Aquarius Power
@AquariusPower limit rozmiaru to rozmiar tablicy, który może być większy niż 255. Po prostu nie można podać endIndexrozmiaru większego niż rozmiar tablicy przekazany jako pierwszy argument. Jeśli więc chcesz mieć pełną kopię, utwórz zmienną odnoszącą się do tej tablicy i użyj Arrays.copyOfRange(var, 0, var.length)lubArrays.copyOf(var, var.length)
elias
Musiałbym utworzyć lokalny var dla pod-tablicy stacktrace, ale stwierdziłem, że to działa !!! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Aquarius Power
Uważaj na to ArrayIndexOutOfBoundsException.
elias,
1
jest inny problem. Co się stanie, jeśli będę musiał podzielić tablicę ciągów o długości, powiedz 500K na podgrupy 250K. Ta metoda akceptuje interegr, który osiąga maksimum przy 65000.
Wisznu Dahatonde
31

Możesz owinąć tablicę jako listę i poprosić o jej podlistę.

MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);
K-ballo
źródło
22

Tak, możesz użyć Arrays.copyOfRange

Robi to samo (pamiętaj, że istnieje kopia: nie zmieniasz początkowej tablicy).

Denys Séguret
źródło
2
To powiedziawszy, jeśli nie chcesz robić wyraźnej kopii, musisz użyć a Listi a, subListjak opisano w odpowiedzi @ K-ballo.
Louis Wasserman,
Zgadza się. Java nie ma funkcji krojenia tablic, które oferują bardziej nowoczesne języki.
Denys Séguret,
Nie jestem pewien, czy powiedziałbym to w ten sposób, ale ... tak, Java nie oferuje podziału tablic. (To powiedziawszy, istnieją pewne zalety tego podejścia: zmniejszone możliwości wycieków pamięci, zmniejszone obciążenie tablicy przez unikanie dodatkowych pól itp. Możesz przejść w obie strony.)
Louis Wasserman,
Tak, masz rację ponownie (a ja nie próbowałem rozpocząć wojny z płomieniami;)). Krojenie czyni GC bardzo złożonym. A kiedy Java próbowała niejawnego krojenia opartego na obiektach w ciągach , stało się bardziej oczywiste, że jest to niebezpieczne .
Denys Séguret,
11

Możesz spróbować:

System.arraycopy(sourceArray, 0, targetArray, 0, targetArray.length);// copies whole array

// copies elements 1 and 2 from sourceArray to targetArray
System.arraycopy(sourceArray, 1, targetArray, 0, 2); 

Zobacz javadoc dla Systemu .

StvnBrkdll
źródło
3
Po prostu uwielbiam, jak dokładnie tak są zaimplementowane Arrays.copyOf () i Arrays.copyOfRange () (sans granice czeków), a mimo to nie otrzymuje głosów, podczas gdy owijki nieco wyższej metody użyteczności publicznej podnoszą głosy pomimo System.arraycopy powrót do 1995 r.
Dave
1
Myślę, że dla niektórych po prostu nie wygląda na „nowoczesny”.
Dave
Lubię chodzić do starej szkoły, bez błyszczących dzwonków i gwizdków tylko potrzebną maszynerię. Jak memcpy w C
StvnBrkdll
Ale użycie arrays.copyOfRange () zwiększa czytelność i znacznie zmniejsza prawdopodobieństwo błędów.
Florian F
7

Jeśli używasz Java 1.6 lub nowszej, możesz użyć Arrays.copyOfRangedo skopiowania części tablicy. Z javadoc:

Kopiuje określony zakres określonej tablicy do nowej tablicy. Początkowy indeks zakresu (od) musi wynosić od zera do original.lengthwłącznie. Wartość at original[from]jest umieszczana w początkowym elemencie kopii (chyba że from == original.lengthlub from == to). Wartości z kolejnych elementów w oryginalnej tablicy są umieszczane w kolejnych elementach w kopii. Ostateczny indeks zakresu ( to), który musi być większy lub równy from, może być większy niż original.length, w którym falseto przypadku jest umieszczany we wszystkich elementach kopii, których indeks jest większy lub równy original.length - from. Długość zwracanej tablicy będzie wynosić to - from.

Oto prosty przykład :

/**
 * @Program that Copies the specified range of the specified array into a new 
 * array.
 * CopyofRange8Array.java 
 * Author:-RoseIndia Team
 * Date:-15-May-2008
 */
import java.util.*;
public class CopyofRange8Array {
    public static void main(String[] args) {
       //creating a short array
       Object T[]={"Rose","India","Net","Limited","Rohini"};
        // //Copies the specified  short array upto specified range,
        Object T1[] = Arrays.copyOfRange(T, 1,5);
        for (int i = 0; i < T1.length; i++) 
            //Displaying the Copied short array upto specified range
            System.out.println(T1[i]);
    }

}
Justin Ethier
źródło
3

Sprawdź copyOfRange ; i przykład:

int[] arr2 = Arrays.copyOfRange(arr,0,3);
dcp
źródło
-2

Możesz użyć subList(int fromIndex, int toIndex)metody na liczbach całkowitych arr, mniej więcej tak:

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> arr = new ArrayList<>();
        arr.add(1);
        arr.add(2);
        arr.add(3);
        arr.add(4);
        List<Integer> partialArr = arr.subList(1, 3);

        // print the subArr
        for (Integer i: partialArr)
            System.out.println(i + " ");
    }
}

Wyjście będzie: 2 3.

Zauważ, że subList(int fromIndex, int toIndex)metoda wykonuje minus 1 na drugiej zmiennej, którą otrzymuje (var2 - 1), nie wiem dokładnie dlaczego, ale tak właśnie się dzieje, być może w celu zmniejszenia szansy na przekroczenie rozmiaru tablicy.

A. Ab
źródło