Dlaczego Java zezwala na tablice o rozmiarze 0?


82

Tablice w Javie mają stałą długość. Dlaczego więc Java zezwala na tablice o rozmiarze 0?

String[] strings = new String[0];

Odpowiedzi:


122

Oznacza to, że jest pusty. Oznacza to, że możesz zapętlić go tak, jakby miał elementy i nie ma żadnego wyniku:

for(int k = 0; k < strings.length; k++){
   // something
}

Dzięki temu unika się konieczności sprawdzania. Gdyby tablica, o której mowa null, miałaby miejsce, wystąpiłby wyjątek, ale w tym przypadku po prostu nic nie robi, co może być właściwe.


9
Jest również przydatny do wywoływania funkcji test(Object... objects)jawnie, gdy istnieje funkcjatest()
Frithjof

51

Dlaczego Java zezwala na tablice o rozmiarze 1? Czy nie jest całkiem bezużyteczne zawijanie pojedynczej wartości w tablicy? Czy nie wystarczyłoby, gdyby Java dopuszczała tylko tablice o rozmiarze 2 lub większym?

Tak, nullzamiast niej możemy przekazać pustą tablicę i pojedynczy obiekt lub prymityw zamiast macierzy o rozmiarze jeden.

Ale jest kilka dobrych argumentów przeciwko takiemu ograniczeniu. Moje osobiste najważniejsze argumenty:

Ograniczenie jest zbyt skomplikowane i nie jest konieczne

Aby ograniczyć tablice do rozmiarów [1..INTEGER.MAX_INT], musielibyśmy dodać wiele dodatkowych sprawdzeń boudarowych, (zgadzam się z komentarzem Konradsa ) logikę konwersji i przeciążenia metod w naszym kodzie. Wyłączenie 0 (a może 1) z dozwolonych rozmiarów macierzy nie oszczędza kosztów, wymaga dodatkowego wysiłku i ma negatywny wpływ na wydajność.

Wektor modeli macierzy

Tablica jest dobrym modelem danych dla wektora (matematyka, nieVector klasy!). Oczywiście wektor w matematyce może być zerowymiarowy. Który koncepcyjnie różni się od bycia nieistniejącym.


Uwaga dodatkowa - wyróżniającym się opakowaniem dla tablicy (znaków) jest Stringklasa. Niezmienna Stringmaterializuje koncepcję pustej tablicy: jest to pusty String ( "").


2
Nie wierzę w twój argument dotyczący ograniczenia. Java (w przeciwieństwie np. C) już wymaga sprawdzenia liczb ujemnych. To sprawdzenie można by w prosty sposób dostosować, aby pomieściło 0 (wystarczy zmienić >= 0na > 0). Ale oczywiście masz rację co do reszty, więc dodanie tego ograniczenia nie miałoby sensu.
Konrad Rudolph

Moim zdaniem argument iteracji pętli wydaje się lepszy: "for (int k = 0; k <strings.length; k ++) {// coś}"
dannyxyz22

2
Nie, moim zdaniem nie, ponieważ w świecie bez tablic o rozmiarze zerowym puste łańcuchy (oparte na tablicach char) po prostu nie istniałyby, więc nie byłoby potrzeby rozważania pustych tablic w pętlach. Ten argument iteracji jest bardzo praktycznym efektem ubocznym. W tym świecie tablica miałaby co najmniej jeden wpis. (Lub dwa, ponieważ: po co mi tablica tylko dla jednego elementu?)
Andreas Dolk,

Sprawdzenie indeksu ujemnego i zbyt wysokiego jest tym samym sprawdzeniem: indeksy ujemne są zawsze bez znaku-nie mniej-niż długość tablicy
harold


16

Rozważ to (bardziej szczegółowe wyjaśnienie odpowiedzi Noona):

public String[] getStrings() {
 if( foo ) {
  return null;
 } else {
  return new String[] {"bar, "baz"};
 }
}

String[] strings = getStrings();
if (strings != null) {
 for (String s : strings) {
  blah(s);
 }
}

Teraz porównaj to z tym:

public String[] getStrings() {
 if( foo ) {
  return new String[0];
 } else {
  return new String[] {"bar, "baz"};
 }
}

// the if block is not necessary anymore
String[] strings = getStrings();
for (String s : strings) {
 blah(s);
}

To (zwracanie pustych tablic zamiast wartości null) jest w rzeczywistości najlepszą praktyką w świecie projektowania Java API.

Poza tym w Javie możesz zamieniać listy (np. ArrayList) na tablice i sensowne jest tylko przekonwertowanie pustej listy na pustą tablicę.



4

Inny przypadek, w którym tablica o zerowej długości może być przydatna: Aby zwrócić tablicę zawierającą wszystkie elementy na liście:

<T> T[ ] toArray(T[ ] a)

Tablica o zerowej długości może służyć do przekazywania typu tablicy do tej metody. Na przykład:

ClassA[ ] result = list.toArray(new ClassA[0]);

Tablica o zerowej długości jest nadal instancją Object, która zawiera zero elementów.


2

Jednym z przypadków, o których mogę pomyśleć, w których pusta tablica jest niezwykle przydatna, jest użycie jej zamiast wartości null w sytuacji, gdy wartość null nie jest dozwolona. Jednym z możliwych przykładów jest BlockingQueue tablic. Gdy chcesz zasygnalizować koniec wprowadzania do strony odczytu, co byś zrobił? Wysłanie wartości null wydaje się oczywistym wyborem, ale problem polega na tym, że BlockingQueue nie akceptuje wartości null. Możesz umieścić swoją tablicę wewnątrz klasy z boolean last;polem typu " ", ale to trochę przesada. Wysłanie pustej tablicy (o rozmiarze zerowym) wydaje się najbardziej rozsądnym wyborem.


0

Innym przypadkiem, gdy tablica o zerowej długości jest przydatna, jest kopiowanie tablicy dwuwymiarowej. Umiem pisać:

public int[][] copyArray(int[][] array){
     int[][] newArray = new int[array.length][0];
     for(int i=0;i<array.length;i++){
         newArray[i] = array[i];
     }
     return newArray;

Ponieważ każde odwołanie do tablicy w tablicy jest nadpisywane, inicjowanie ich jako odniesień do tablic o zerowej długości jest najbardziej wydajne.


0

Długość 0 byte[]lub char[]może reprezentować pusty String, który różni się od null. Pierwsze bajtów lub znaków, jak tablice z łańcuchów (stosując getBytes(), getChars()w Stringklasie itp) i vice versa formowania Stringsz byte[], char[]jest dość powszechne. Na przykład w celu niestandardowego kodowania dekodowanie ciągów.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.