Java'da bir Array öğesinin yalnızca bir kısmını almak ister misiniz?


275

Java tamsayılar bir dizi var, ben sadece bir kısmını kullanmak istiyorum. Python bu dizi [index:] gibi bir şey yapabilirsiniz biliyorum ve dizinden dizi döndürür. Java'da böyle bir şey mümkün mü?

Yanıtlar:


444

Java'da bir dizinin uzunluğu değişmez. Bu nedenle, istenen parçayı yeni bir dizi olarak kopyalamanız gerekir. Java.util.Arrays sınıfından yöntemi
kullanın :copyOfRange

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

startIndex , kopyalanacak aralığın (dahil) başlangıç ​​dizinidir.
endIndex , kopyalanacak aralığın münhasır endeksidir. (Bu dizin dizinin dışında olabilir)

Örneğin:

   //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)

boyut sınırı var gibi görünüyor mu? sadece bu çalışır: Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,255)255 yerine Integer.MAX_VALUE kullanamıyorum, gerçek uzunluğu elde etmek istemiyorum durumunda
Aquarius Power

@AquariusPower boyut sınırı dizi boyutudur ve 255'ten büyük olabilir endIndex. İlk bağımsız değişken olarak geçirilen dizinin boyutundan daha büyük bir değer sağlayamazsınız . Yani, tam bir kopya istiyorsanız, bu diziye Arrays.copyOfRange(var, 0, var.length)Arrays.copyOf(var, var.length)
başvuran

Stacktrace alt dizisi için yerel bir var oluşturmak zorunda kalacak, ama bu işe yaradığını buldum! Arrays.copyOfRange(Thread.currentThread().getStackTrace(),1,Short.MAX_VALUE)
Kova Gücü

Dikkatli olun ArrayIndexOutOfBoundsException.
elias

1
başka bir sorun daha var. Uzunluk dizesini bölmek gerekirse 250K alt dizilerine 500K demek. Bu yöntem 65000'de maksimum olan interegr'i kabul eder.
Vishnu Dahatonde

31

Dizinizi liste olarak sarabilir ve alt listesini isteyebilirsiniz.

MyClass[] array = ...;
List<MyClass> subArray = Arrays.asList(array).subList(index, array.length);

22

Evet, Arrays.copyOfRange kullanabilirsiniz

Aynı şeyi yapar (bir kopya olduğunu unutmayın: ilk diziyi değiştirmezsiniz).


2
Bununla birlikte, açık bir kopya yapmak istemiyorsanız , @ K-ballo'un cevabında belirtildiği gibi a Listve subLista'yı kullanmanız gerekir .
Louis Wasserman

Doğru. Java, daha modern dillerin sunduğu dizi dilimleme olanaklarına sahip değildir.
Denys Séguret

Bu şekilde koyarsam emin değilim, ama ... evet, Java dizi dilimleme sunmuyor. : (Vb Sen iki yönde de olabilir hafıza sızıntıları azalmış olasılık, dizi azaltılmış havai ekstra alanları kaçınarak Yani bu yaklaşımın bazı avantajları vardır, dedi.)
Louis Wasserman

Evet, yine haklısın (ve bir alev savaşı başlatmaya çalışmadım;)). Dilimleme GC'yi çok karmaşık hale getirir. Java, Dizelerde nesne tabanlı örtülü dilimlemeyi denediğinde , bunun tehlikeli olduğu daha açık hale geldi .
Denys Séguret

11

Deneyebilirsin:

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

Sistem için javadoc'a bakınız .


3
Ben sadece bu tam olarak nasıl Arrays.copyOf () ve Arrays.copyOfRange () aslında nasıl uygulanır seviyorum (sans sınırları kontrol) ve henüz biraz daha yüksek havai yarar yöntemi sarmalayıcılar System.arraycopy kalma rağmen oylar rafa iken oy alır 1995'e dön.
Dave

1
Bazıları için yeterince "modern" görünmüyor sanırım.
Dave

Eski okula gitmeyi seviyorum, sadece gerekli makineleri parlak çan ve ıslık çalmıyorum. C gibi memcpy gibi
StvnBrkdll

Ancak arrays.copyOfRange () kullanımı, okunabilirliği artırır ve hata olasılığını önemli ölçüde azaltır.
Florian F

7

Java 1.6 veya üstünü kullanıyorsanız Arrays.copyOfRange, dizinin bir bölümünü kopyalamak için kullanabilirsiniz . Javadoc'tan:

Belirtilen dizinin belirtilen aralığını yeni bir diziye kopyalar. Aralığın (başlangıç) endeksi sıfır ile original.lengthkapsayıcı arasında olmalıdır . Adresindeki değer original[from], kopyanın ilk öğesine ( from == original.lengthveya değilse from == to) yerleştirilir. Orijinal dizideki sonraki öğelerin değerleri, kopyadaki sonraki öğelere yerleştirilir. Daha tobüyük veya eşit olması gereken ( ) aralığının son dizini, daha büyük fromolabilir; original.lengthbu durumda false, dizini, dizini eşit veya daha büyük olan tüm öğelere yerleştirilir original.length - from. Döndürülen dizinin uzunluğu olacaktır to - from.

İşte basit bir örnek :

/**
 * @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]);
    }

}



-2

subList(int fromIndex, int toIndex)Tamsayı dizinizde yöntemi kullanabilirsiniz , şöyle bir şey:

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 + " ");
    }
}

Çıktı olacaktır: 2 3.

Bu subList(int fromIndex, int toIndex)yöntem eksi 1 alır (değişken2 - 1) 2 değişken üzerinde gerçekleştirir, ben tam olarak neden bilmiyorum, ama bu ne olur, belki dizi boyutunu aşma şansını azaltmak için.

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.