2013-01-04 9 views
12

Powiel możliwe:
Detecting the first iteration through a for-each loop in JavaNajlepsze praktyki: traktowanie pierwszy element inny niż inni podczas zapętlenie nad kolekcją

Hi podczas zapętlenie nad kolekcją chcę znaleźć najmądrzejszy sposób generują inne zachowanie tylko na pierwszym elemencie kolekcji. Mam do czynienia z tym problemem bardzo często i poczuć się jak moje rozwiązanie nie jest najlepsze:

boolean first = true; 
for(String foo: foos) { 
    if(first) { 
    // do first behavior 
    first = false; 
    continue; 
    } 
    // do normal behaviour 
} 

zastanawiam się czy są jakieś inne inteligentniejszego podejścia niż to?

+3

Jeśli używasz zwykłej pętli for, możesz polegać na indeksie. Dla każdego, nie ma innego sposobu niż posiadanie flagi. – kosa

+1

możesz po prostu usunąć "kontynuuj", prawda? –

+1

kontynuacja jest usuwalna tylko wtedy, gdy normalne zachowanie nie ma wpływu na pierwsze zachowanie i na odwrót. – sics

Odpowiedz

12

Można to zrobić (ale to nie będzie działać z tablicami):

Iterator<String> it = ... 
if (it.hasNext()) { 
    String s = it.next(); 
    //first behaviour 
    while (it.hasNext()) { 
     //other behaviour 
    } 
} 

Uwaga: To jest inspirowana przez guava Joiner's class.

Z ciekawości, ja również sprawdziłem podejście stosowane przez Apache's StringUtils#join - to nie jest konieczne, nie stosuje się do przypadku użycia, jak trzeba być w stanie uzyskać dostęp do elementu i-tego (czyli nie działa w żadnej iterables):

for (int i = startIndex; i < endIndex; i++) { 
    if (i > startIndex) { 
     buf.append(separator); 
    } 
    buf.append(array[i]); 
} 
0

Nie lubię też flag. To zależy od sytuacji, na przykład jeżeli buduję SELECT listę kolumn używam ten trick

StringBuilder sb = new StringBuilder(); 
for(String c : columns) { 
    if (sb.length != 0) { 
     sb.append(','); 
    } 
    sb.append(c); 
} 

jak widać nie ma flagi

+1

Istnieje przypadek graniczny, jeśli twój plik CSV wygląda jak ,, a, b, c "(tj. Pierwsze 2 puste elementy) => przegapisz pierwszy przecinek. – assylias

+0

Oczywiście to zależy, mój przykład był dla kolumn DB –

2

będzie to zrobić. (Zakładając, że używasz listę array)

Foo foo = foos.get(0); 

// do first behavior 

    for(int i=1;i<foos.size();i++) { 
    // do normal behaviour 
    } 
+4

-1 get() nie jest obsługiwane dla wszystkich kolekcji, np. Set nie ma metody get(). Ta odpowiedź w rzeczywistości nie odpowiada na pytanie – Bohemian

+0

Konieczność zapewnienia 'length! = 0' – weston

+0

Ma to na celu zilustrowanie procesu pierwszego elementu osobno, a następnie przetworzenie innych elementów przez pętlę. – Suranga

2

Myślę, że tak jak ogólne rozwiązania, trudno jest wygrać. Jest zwięzły, jest jasne, działa z tablicami Java, a także z kontenerami, które nie obsługują pobierania elementu po indeksie i poprawnie obsługuje puste kolekcje.

Może być również trywialnie uogólniony do obsługi pierwszych elementówinaczej niż pozostałe (wystarczy obrócić flagę logiczną w licznik całkowitoliczbowy).

+0

+1 Jedynym rozwiązaniem do obsługi tablic oraz kolekcji/Iterables jest użycie pętli for-each. – assylias