it-swarm.com.de

Letzte Iteration der erweiterten for-Schleife in Java

Gibt es eine Möglichkeit zu bestimmen, ob die Schleife das letzte Mal durchlaufen wird? Mein Code sieht ungefähr so ​​aus:

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();

for(int i : array)
{
    builder.append("" + i);
    if(!lastiteration)
        builder.append(",");
}

Jetzt möchte ich das Komma in der letzten Iteration nicht anhängen. Nun gibt es eine Möglichkeit festzustellen, ob es sich um die letzte Iteration handelt oder ob ich mit der for-Schleife festgehe oder einen externen Zähler verwende, um den Überblick zu behalten.

130
Mercurious

Eine andere Alternative besteht darin, das Komma vor dem Anhängen von i anzufügen, nicht jedoch in der first - Iteration. (Bitte verwenden Sie übrigens nicht "" + i - Sie möchten hier nicht wirklich verketten, und StringBuilder hat eine perfekte Überladung von Anhängen (int).)

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();

for (int i : array) {
    if (builder.length() != 0) {
        builder.append(",");
    }
    builder.append(i);
}

Das Schöne daran ist, dass es mit jeder Iterable funktioniert - man kann Dinge nicht immer indizieren. (Das "Komma hinzufügen und dann am Ende entfernen" ist ein guter Vorschlag, wenn Sie wirklich StringBuilder verwenden - es funktioniert jedoch nicht für das Schreiben in Streams. Es ist jedoch möglicherweise der beste Ansatz für dieses genaue Problem. )

216
Jon Skeet

Eine andere Möglichkeit, dies zu tun:

String delim = "";
for (int i : ints) {
    sb.append(delim).append(i);
    delim = ",";
}

Update: Für Java 8 haben Sie jetzt Collectors

141
toolkit

Es könnte einfacher sein, immer anzufügen. Und wenn Sie mit Ihrer Schleife fertig sind, entfernen Sie einfach das letzte Zeichen. Tonnenweise weniger Bedingungen auch auf diese Weise.

Sie können StringBuilders deleteCharAt(int index) verwenden, wobei index length() - 1 ist.

39
Dinah

Vielleicht verwenden Sie das falsche Werkzeug für den Job.

Dies ist mehr Handbuch als das, was Sie tun, aber es ist in gewisser Weise eleganter, wenn nicht ein bisschen "old school".

 StringBuffer buffer = new StringBuffer();
 Iterator iter = s.iterator();
 while (iter.hasNext()) {
      buffer.append(iter.next());
      if (iter.hasNext()) {
            buffer.append(delimiter);
      }
 }
29
Omar Kooheji

Dies ist fast eine Wiederholung von dieser StackOverflow-Frage . Sie möchten StringUtils und die Methode join aufrufen.

StringUtils.join(strArr, ',');
15
Phil H

Eine andere Lösung (vielleicht die effizienteste)

    int[] array = {1, 2, 3};
    StringBuilder builder = new StringBuilder();

    if (array.length != 0) {
        builder.append(array[0]);
        for (int i = 1; i < array.length; i++ )
        {
            builder.append(",");
            builder.append(array[i]);
        }
    }
14
bruno conde

Explizite Schleifen funktionieren immer besser als implizite.

builder.append( "" + array[0] );
for( int i = 1; i != array.length; i += 1 ) {
   builder.append( ", " + array[i] );
}

Sie sollten das Ganze in eine if-Anweisung einschließen, nur für den Fall, dass Sie ein Array der Länge null verwenden.

6
S.Lott

halten Sie es einfach und verwenden Sie einen Standard für Schleife:

for(int i = 0 ; i < array.length ; i ++ ){
    builder.append(array[i]);
    if( i != array.length - 1 ){
        builder.append(',');
    }
}

oder verwenden Sie einfach Apache commons-lang StringUtils.join ()

5
Gareth Davis

Wenn Sie es in eine klassische Indexschleife konvertieren, ja.

Oder Sie löschen einfach das letzte Komma, nachdem es fertig ist. So wie:

int[] array = {1, 2, 3...};
StringBuilder

builder = new StringBuilder();

for(int i : array)
{
    builder.append(i + ",");
}

if(builder.charAt((builder.length() - 1) == ','))
    builder.deleteCharAt(builder.length() - 1);

Ich benutze nur StringUtils.join() aus commons-lang .

4
sblundy

Basierend auf Java.util.AbstractCollection.toString () wird es frühzeitig beendet, um den Begrenzer zu vermeiden.

StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
for (;;) {
  buffer.append(iter.next());
  if (! iter.hasNext())
    break;
  buffer.append(delimiter);
}

Es ist effizient und elegant, aber nicht so selbstverständlich wie andere Antworten.

3
13ren

Sie benötigen Class Separator .

Separator s = new Separator(", ");
for(int i : array)
{
     builder.append(s).append(i);
}

Die Implementierung der Klasse Separator ist unkompliziert. Es wird ein String umbrochen, der bei jedem Aufruf von toString() zurückgegeben wird, mit Ausnahme des ersten Aufrufs, der einen leeren String zurückgibt.

3
akuhn

Hier ist eine Lösung:

int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
bool firstiteration=true;

for(int i : array)
{
    if(!firstiteration)
        builder.append(",");

    builder.append("" + i);
    firstiteration=false;
}

Suchen Sie nach der ersten Iteration:)

2
FallenAvatar

Noch eine Option.

StringBuilder builder = new StringBuilder();
for(int i : array)
    builder.append(',').append(i);
String text = builder.toString();
if (text.startsWith(",")) text=text.substring(1);
1
Peter Lawrey

Viele der hier beschriebenen Lösungen sind ein wenig übertrieben, vor allem diejenigen, die auf externe Bibliotheken angewiesen sind. Es gibt eine schöne saubere, klare Sprache für das Erreichen einer durch Kommas getrennten Liste, die ich immer verwendet habe. Es beruht auf dem bedingten (?) Operator:

Bearbeiten : Originallösung korrekt, aber laut Kommentaren nicht optimal. Ein zweites Mal versuchen:

    int[] array = {1, 2, 3};
    StringBuilder builder = new StringBuilder();
    for (int i = 0 ;  i < array.length; i++)
           builder.append(i == 0 ? "" : ",").append(array[i]); 

Nun, in 4 Zeilen Code, einschließlich der Deklaration des Arrays und des StringBuilder.

1
Julien Chastang

Wie in dem Toolkit erwähnt, haben wir in Java 8 jetzt Collectors . So würde der Code aussehen:

String joined = array.stream().map(Object::toString).collect(Collectors.joining(", "));

Ich denke, das macht genau das, wonach Sie suchen, und es ist ein Muster, das Sie für viele andere Dinge verwenden könnten.

1
b1tw153

Hier ist ein SSCCE-Benchmark, den ich (bezogen auf das, was ich implementieren musste) mit diesen Ergebnissen durchführte: 

elapsed time with checks at every iteration: 12055(ms)
elapsed time with deletion at the end: 11977(ms)

In meinem Beispiel ist das Überspringen der Prüfung bei jeder Iteration insbesondere bei normalen Datenmengen nicht merklich schneller, aber ist.

import Java.util.ArrayList;
import Java.util.List;


public class TestCommas {

  public static String GetUrlsIn(int aProjectID, List<String> aUrls, boolean aPreferChecks)
  {

    if (aPreferChecks) {

      StringBuffer sql = new StringBuffer("select * from mytable_" + aProjectID + " WHERE hash IN ");

      StringBuffer inHashes = new StringBuffer("(");
      StringBuffer inURLs = new StringBuffer("(");

      if (aUrls.size() > 0)
      {

      for (String url : aUrls)
      {

        if (inHashes.length() > 0) {
        inHashes.append(",");
        inURLs.append(",");
        }

        inHashes.append(url.hashCode());

        inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"");//.append(",");

      }

      }

      inHashes.append(")");
      inURLs.append(")");

      return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
    }

    else {

      StringBuffer sql = new StringBuffer("select * from mytable" + aProjectID + " WHERE hash IN ");

      StringBuffer inHashes = new StringBuffer("(");
      StringBuffer inURLs = new StringBuffer("(");

      if (aUrls.size() > 0)
      {

      for (String url : aUrls)
      {
        inHashes.append(url.hashCode()).append(","); 

        inURLs.append("\"").append(url.replace("\"", "\\\"")).append("\"").append(",");
      }

      }

      inHashes.deleteCharAt(inHashes.length()-1);
      inURLs.deleteCharAt(inURLs.length()-1);

      inHashes.append(")");
      inURLs.append(")");

      return sql.append(inHashes).append(" AND url IN ").append(inURLs).toString();
    }

  }

  public static void main(String[] args) { 
        List<String> urls = new ArrayList<String>();

    for (int i = 0; i < 10000; i++) {
      urls.add("http://www.google.com/" + System.currentTimeMillis());
      urls.add("http://www.yahoo.com/" + System.currentTimeMillis());
      urls.add("http://www.bing.com/" + System.currentTimeMillis());
    }


    long startTime = System.currentTimeMillis();
    for (int i = 0; i < 300; i++) {
      GetUrlsIn(5, urls, true);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("elapsed time with checks at every iteration: " + (endTime-startTime) + "(ms)");

    startTime = System.currentTimeMillis();
    for (int i = 0; i < 300; i++) {
      GetUrlsIn(5, urls, false);
    }
    endTime = System.currentTimeMillis();
    System.out.println("elapsed time with deletion at the end: " + (endTime-startTime) + "(ms)");
  }
}
1
Buffalo

Ein anderer Ansatz besteht darin, die Länge des Arrays (falls verfügbar) in einer separaten Variablen zu speichern (effizienter als jedes Mal eine erneute Überprüfung). Sie können dann Ihren Index mit dieser Länge vergleichen, um zu bestimmen, ob das letzte Komma hinzugefügt werden soll oder nicht.

BEARBEITEN: Eine andere Überlegung besteht darin, die Leistungskosten für das Entfernen eines Endzeichens (was eine Zeichenkettenkopie verursachen kann) abzuwägen, damit bei jeder Iteration eine Bedingung geprüft wird.

0
Brian

Zwei alternative Wege hier:

1: Apache Commons String Utils

2: Behalten Sie einen booleschen Namen namens first bei, der auf true gesetzt ist. Wenn first in jeder Iteration falsch ist, hängen Sie Ihr Komma an. Danach setzen Sie first auf false.

0
Paul Brinkley

In diesem Fall ist es wirklich nicht nötig zu wissen, ob es die letzte Wiederholung ist. Es gibt viele Möglichkeiten, wie wir das lösen können. Ein Weg wäre:

String del = null;
for(int i : array)
{
    if (del != null)
       builder.append(del);
    else
       del = ",";
    builder.append(i);
}
0
fastcodejava

Da es sich um ein festes Array handelt, ist es einfacher, das erweiterte für zu vermeiden. Wenn das Objekt eine Sammlung ist, wäre ein Iterator einfacher.

int nums[] = getNumbersArray();
StringBuilder builder = new StringBuilder();

// non enhanced version
for(int i = 0; i < nums.length; i++){
   builder.append(nums[i]);
   if(i < nums.length - 1){
       builder.append(",");
   }   
}

//using iterator
Iterator<int> numIter = Arrays.asList(nums).iterator();

while(numIter.hasNext()){
   int num = numIter.next();
   builder.append(num);
   if(numIter.hasNext()){
      builder.append(",");
   }
}
0
AnthonyJClink

Wenn Sie ein Array nur in ein durch Kommas getrenntes Array umwandeln, haben viele Sprachen genau dafür eine Join-Funktion. Es verwandelt ein Array in einen String mit einem Trennzeichen zwischen jedem Element.

0
Dinah