Последняя итерация расширенного цикла в java
Есть ли способ определить, выполняется ли цикл в последний раз. Мой код выглядит примерно так:
int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
for(int i : array)
{
builder.append("" + i);
if(!lastiteration)
builder.append(",");
}
Теперь я не хочу добавлять запятую в последнюю итерацию. Теперь есть способ определить, является ли это последней итерацией, или я придерживаюсь цикла for или использую внешний счетчик для отслеживания.
Ответы
Ответ 1
Другой вариант - добавить запятую перед добавлением i, а не на первую итерацию. (Пожалуйста, не используйте "" + i
, кстати, вы действительно не хотите конкатенации здесь, а StringBuilder имеет прекрасную пересылку append (int).)
int[] array = {1, 2, 3...};
StringBuilder builder = new StringBuilder();
for (int i : array) {
if (builder.length() != 0) {
builder.append(",");
}
builder.append(i);
}
Самое приятное в том, что он будет работать с любым Iterable
- вы не всегда можете индексировать вещи. ( "Добавить запятую, а затем удалить ее в конце" является хорошим предложением, когда вы действительно используете StringBuilder, но это не работает для таких вещей, как запись в потоки. Возможно, это лучший подход для этой точной проблемы. )
Ответ 2
Другой способ сделать это:
String delim = "";
for (int i : ints) {
sb.append(delim).append(i);
delim = ",";
}
Обновление: для Java 8 теперь Collectors
Ответ 3
Это может быть проще всегда добавлять. И затем, когда вы закончите свой цикл, просто удалите финальный символ. Тонны меньше условностей тоже.
Вы можете использовать StringBuilder
deleteCharAt(int index)
с индексом length() - 1
Ответ 4
Возможно, вы используете неправильный инструмент для задания.
Это более ручная работа, чем то, что вы делаете, но это более элегантно, если не немного "старая школа".
StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
while (iter.hasNext()) {
buffer.append(iter.next());
if (iter.hasNext()) {
buffer.append(delimiter);
}
}
Ответ 5
Это почти повторение fooobar.com/questions/17835/.... Вы хотите StringUtils и вызвать метод join.
StringUtils.join(strArr, ',');
Ответ 6
Другое решение (возможно, наиболее эффективное)
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]);
}
}
Ответ 7
Явные циклы всегда работают лучше, чем неявные.
builder.append( "" + array[0] );
for( int i = 1; i != array.length; i += 1 ) {
builder.append( ", " + array[i] );
}
Вы должны обернуть все это в if-statement на всякий случай, если вы имеете дело с массивом нулевой длины.
Ответ 8
держите его простым и используйте стандарт для цикла:
for(int i = 0 ; i < array.length ; i ++ ){
builder.append(array[i]);
if( i != array.length - 1 ){
builder.append(',');
}
}
или просто используйте apache commons-lang StringUtils.join()
Ответ 9
Если вы преобразуете его в классический индексный цикл, да.
Или вы можете просто удалить последнюю запятую после ее завершения. Например:
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);
Me, я просто использую StringUtils.join()
из commons- Ланг.
Ответ 10
Вам нужен Сепаратор класса.
Separator s = new Separator(", ");
for(int i : array)
{
builder.append(s).append(i);
}
Реализация класса Separator
выполняется прямо. Он переносит строку, которая возвращается при каждом вызове toString()
, за исключением первого вызова, который возвращает пустую строку.
Ответ 11
На основе java.util.AbstractCollection.toString() он выйдет раньше, чтобы избежать разделителя.
StringBuffer buffer = new StringBuffer();
Iterator iter = s.iterator();
for (;;) {
buffer.append(iter.next());
if (! iter.hasNext())
break;
buffer.append(delimiter);
}
Это эффективный и элегантный, но не такой само собой разумеющийся, как некоторые другие ответы.
Ответ 12
Вот решение:
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;
}
Ищите первую итерацию:)
Ответ 13
Еще один вариант.
StringBuilder builder = new StringBuilder();
for(int i : array)
builder.append(',').append(i);
String text = builder.toString();
if (text.startsWith(",")) text=text.substring(1);
Ответ 14
Многие из описанных здесь решений немного выше, 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]);
Там вы идете в 4 строках кода, включая объявление массива и StringBuilder.
Ответ 15
Здесь был проведен тест SSCCE (связанный с тем, что я должен был реализовать) с этими результатами:
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)");
}
}
Ответ 16
В качестве инструментария, упомянутого в Java 8, теперь Collectors. Вот как выглядит код:
String joined = array.stream().map(Object::toString).collect(Collectors.joining(", "));
Я думаю, что делает именно то, что вы ищете, и это шаблон, который вы могли бы использовать для многих других вещей.
Ответ 17
Другой подход заключается в том, чтобы длина массива (если доступна) хранилась в отдельной переменной (более эффективная, чем повторная проверка длины каждый раз). Затем вы можете сравнить свой индекс с этой длиной, чтобы определить, добавлять ли окончательную запятую.
EDIT: Еще одно соображение - это взвешивание стоимости исполнения для удаления конечного символа (что может привести к копированию строки) против того, чтобы на каждой итерации было проверено условие.
Ответ 18
Два альтернативных пути:
1: Apache Commons String Utils
2: сохранить логическое имя first
, установить значение true. На каждой итерации, если first
является ложным, добавьте запятую; после этого установите first
в значение false.
Ответ 19
Если вы только превращаете массив в массив с разделителями-запятыми, на многих языках для этого есть функция соединения. Он превращает массив в строку с разделителем между каждым элементом.
Ответ 20
В этом случае нет необходимости знать, является ли это последним повторением.
Есть много способов решить эту проблему. Один из способов:
String del = null;
for(int i : array)
{
if (del != null)
builder.append(del);
else
del = ",";
builder.append(i);
}
Ответ 21
С его фиксированным массивом было бы проще просто избежать расширения для... Если Object представляет собой коллекцию, то итератором будет проще.
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(",");
}
}