programing

Java에서 루프를 위한 확장의 마지막 반복

shortcode 2022. 9. 18. 17:47
반응형

Java에서 루프를 위한 확장의 마지막 반복

루프가 마지막으로 반복되는지 확인할 수 있는 방법이 있습니까?코드는 다음과 같습니다.

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

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

여기서 중요한 것은 마지막 반복에 쉼표를 추가하고 싶지 않습니다.이것이 마지막 반복인지, for 루프를 계속 사용하는지, 아니면 외부 카운터를 사용하여 추적하는지 여부를 판별할 수 있는 방법이 있습니다.

또 다른 방법은 i를 추가하기 전에 콤마를 추가하는 것입니다.단, 첫 번째 반복에서는 사용하지 마십시오."" + i덧붙여서, 여기서의 접속은 별로 하고 싶지 않습니다.String Builder에는 완전히 양호한 추가(int) 오버로드가 있습니다.)

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

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

이것의 좋은 점은 어떤 것과도 함께 작동한다는 것입니다.Iterable- 항상 색인화할 수 있는 것은 아닙니다.('쉼표 추가 후 마지막에 삭제'는 String Builder를 실제로 사용할 때 권장하는 방법이지만 스트림에 쓰는 방법에는 적합하지 않습니다.이 문제에 대한 최선의 접근법이 될 수 있습니다.)

또 다른 방법은 다음과 같습니다.

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

업데이트: Java 8의 경우 Collector를 사용할 수 있게 되었습니다.

항상 추가하는 것이 더 쉬울 수 있습니다.그리고 루프가 끝나면 마지막 글자를 삭제해 주세요.그렇게 하면 조건도 훨씬 적어지죠

사용할 수 있습니다.StringBuilderdeleteCharAt(int index)지수를 가지고length() - 1

Job에 잘못된 도구를 사용하고 있는 것 같습니다.

이것은 당신이 하고 있는 것보다 더 수동적이지만, 좀 더 '구식'은 아니더라도 훨씬 우아하다.

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

이것은 이 StackOverflow 질문을 거의 반복한 것입니다.필요한 것은 String Utils이며 가입 메서드를 호출합니다.

StringUtils.join(strArr, ',');

다른 솔루션(아마도 가장 효율적일 것)

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

단순성을 유지하고 루프 표준을 사용합니다.

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

또는 apache commons-lang StringUtils.join()을 사용합니다.

명시적 루프는 암묵적인 루프보다 항상 더 잘 작동합니다.

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

길이가 0인 어레이를 취급할 경우에 대비하여 모든 것을 if-statement로 포장해야 합니다.

툴킷에서 설명한 바와 같이 Java 8에서는 Collector가 도입되었습니다.코드는 다음과 같습니다.

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

이 패턴은 당신이 찾고 있는 것과 정확히 일치하며, 다른 많은 것에 사용할 수 있는 패턴이라고 생각합니다.

클래식 인덱스 루프로 변환하면 네.

또는 마지막 쉼표를 삭제해도 됩니다.다음과 같은 경우:

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

전 그냥 common-lang에서 사용해요.

클래스 구분자가 필요합니다.

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

Separator직진입니다.콜마다 반환되는 문자열을 랩합니다.toString()빈 문자열을 반환하는 첫 번째 콜을 제외합니다.

java.util을 기반으로 합니다.Abstract Collection.toString()은 딜리미터를 피하기 위해 일찍 종료됩니다.

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

효율적이고 우아하지만 다른 답변만큼 자명하지는 않습니다.

해결책은 다음과 같습니다.

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

첫 번째 반복을 찾습니다. : )

또 다른 선택지입니다.

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

여기서 설명하는 솔루션의 대부분은 IMHO, 특히 외부 라이브러리에 의존하는 솔루션보다 약간 과장되어 있습니다.쉼표로 구분된 목록을 작성하기 위한 깨끗하고 명확한 관용구가 있습니다.조건 연산자(?)에 의존합니다.

편집: 원래 솔루션은 올바르지만 코멘트에 따르면 최적은 아닙니다.두 번째 시도:

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

어레이 선언과 String Builder를 포함한 4줄의 코드로 구성됩니다.

다음으로 (실장해야 할 것과 관련된) SSCE 벤치마크를 실시하여 다음 결과를 나타냅니다.

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

적어도 이 예에서는 반복할 때마다 검사를 건너뛰는 것이 특히 정상적인 데이터 볼륨의 경우 눈에 띄게 빠르지는 않지만 더 빠릅니다.

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

또 다른 방법은 배열의 길이(사용 가능한 경우)를 별도의 변수에 저장하는 것입니다(매번 길이를 다시 확인하는 것보다 더 효율적입니다).그런 다음 인덱스를 해당 길이와 비교하여 마지막 쉼표를 추가할지 여부를 결정할 수 있습니다.

편집: 마지막 문자 삭제(문자열 복사의 원인이 될 수 있음)와 각 반복에서 조건부 체크가 필요한 경우의 퍼포먼스 비용을 저울질하는 것도 고려해야 할 사항입니다.

배열을 쉼표로 구분된 배열로만 변환하는 경우, 많은 언어에서 정확히 이 배열을 위한 결합 기능이 있습니다.배열을 각 요소 사이에 딜리미터가 있는 문자열로 변환합니다.

이 경우, 이것이 마지막 반복인지 아닌지는 알 필요가 없습니다.이 문제를 해결할 수 있는 방법은 여러 가지가 있습니다.한 가지 방법은 다음과 같습니다.

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

여기에는 두 가지 대체 경로가 있습니다.

1: Apache Commons 문자열 유틸리티

2: 부울 를 유지하세요.firsttrue.true로 「」의 는,first 콤마를 false로 합니다.이치first거짓으로.

고정 배열이기 때문에 확장 기능을 사용하지 않아도 됩니다.오브젝트가 컬렉션인 경우 반복이 더 쉬워집니다.

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

String Joiner를 사용할 수 있습니다.

int[] array = { 1, 2, 3 };
StringJoiner stringJoiner = new StringJoiner(",");

for (int i : array) {
    stringJoiner.add(String.valueOf(i));
}

System.out.println(stringJoiner);

언급URL : https://stackoverflow.com/questions/285523/last-iteration-of-enhanced-for-loop-in-java

반응형