У меня есть массив String
с именем и идентификатором, мне нужно преобразовать этот массив String
в List
объектов.
Это мой код:
private List<ObjectAttribute> getDtls(String newVal) {
ObjectAttribute object = new ObjectAttribute();
List<ObjectAttribute> objLst = new ArrayList<ObjectAttribute>();
String[] newImageVal = [step0005.jpg, 172B6846-0073-4E5B-B10A-DDD928994EA6, step0003.jpg, FBC8D143-2CD7-47E6-B323-31A0928A9338]
for (int i = 0; i <= newImageVal.length - 1; i++) {
object.setImageName(newImageVal[i]);
object.setImageId(newImageVal[++i]);
objLst.add(object);
}
return objLst;
}
но есть проблема, что он всегда возвращает только последнее значение в objList
. Может ли кто-нибудь исправить этот код.
переехать
ObjectAttribute object = new ObjectAttribute();
внутри цикла for:
for (int i = 0; i <= newImageVal.length - 1; i++) {
ObjectAttribute object = new ObjectAttribute();
object.setImageName(newImageVal[i]);
object.setImageId(newImageVal[++i]);
objLst.add(object);
}
@HonzaZidek, это ошибка из OP, которая была просто скопирована. Так что вам не нужно говорить StefanBeike, а вместо этого OP;)
@Lino: я думаю, что мы несем определенную ответственность за наши ответы. Мы должны исправить не только их функциональные ошибки, но и их ошибки в дизайне. Ответы SO очень часто используются новичками в качестве источника знаний.
@HonzaZidek вы можете опубликовать свой собственный ответ, который указывает на это. SO поощряет разные ответы, которые по-разному отвечают на одно и то же. И если вы даже улучшите код из OP, возможно, вы получите много положительных отзывов.
@Honza Zidek да, конечно ..., но мой ответ относится к исходной проблеме. не к некоторым проблемам с руководством по стилю кода или лучшим практикам.
Также условие i <= newImageVal.length - 1
слишком оптимистично, если newImageVal
не содержит четного числа элементов, будет выброшено ArrayIndexOutOfBoundException
.
private List<ObjectAttribute> getDtls(String newVal) {
List<ObjectAttribute> objLst = new ArrayList<ObjectAttribute>();
String[] newImageVal = [step0005.jpg, 172B6846-0073-4E5B-B10A-DDD928994EA6, step0003.jpg, FBC8D143-2CD7-47E6-B323-31A0928A9338]
// String delimiter = ", ";
// newImageVal = newVal.split(delimiter);
for (int i = 0; i <= newImageVal.length - 1; i++) {
ObjectAttribute object = new ObjectAttribute();
object.setImageName(newImageVal[i]);
object.setImageId(newImageVal[++i]);
objLst.add(object);
}
return objLst;
}
Это очень плохая практика — снова увеличивать переменную цикла for внутри тела цикла for. Это не должно быть принятым решением, поскольку другие пользователи SO используют их в качестве модельных решений.
Также условие i <= newImageVal.length - 1
слишком оптимистично, если newImageVal
не содержит четного числа элементов, будет выброшено ArrayIndexOutOfBoundException
.
или вы можете сделать что-то подобное, используя способ streams
:
AtomicInteger ai = new AtomicInteger();
List<ObjectAttribute> objLst = Arrays.stream(newImageVal)
.map(img-> {
ObjectAttribute object = new ObjectAttribute();
object.setImageName(img);
object.setImageId(ai.getAndIncrement());
return obj;
}).collect(Collectors.toList())
Основная причина вашей проблемы, как писал @StefanBeike, заключается в том, что вы создаете экземпляр объекта только один раз перед циклом for, а затем просто продолжаете переписывать его атрибуты. Перемещение экземпляра (= вызов new
) внутри цикла for исправляет функциональность.
Однако, помимо этого, очень плохой практикой является увеличение переменной цикла for внутри тела цикла for. Таким образом, вы затемняете свое намерение и получаете код, который менее читабелен, сложнее в сопровождении и легче ломается последующими изменениями.
И главным условием должно быть i < newImageVal.length-1
безопасное обращение с размером массива. (Чтобы быть на 100% уверенным, что вы не получите ArrayIndexOutOfBoundsException
.)
Есть несколько лучших способов.
Увеличьте на 2 в «заголовке» цикла for:
for (int i = 0; i < newImageVal.length-1; i += 2) {
ObjectAttribute object = new ObjectAttribute();
object.setImageName(newImageVal[i]);
object.setImageId(newImageVal[i+1]);
objLst.add(object);
}
Используйте цикл while вместо цикла for:
int i = 0;
while (i < newImageVal.length-1) {
ObjectAttribute object = new ObjectAttribute();
object.setImageName(newImageVal[i++]);
object.setImageId(newImageVal[i++]);
objLst.add(object);
}
Может быть, это ошибка со стороны OP, кажется совершенно особенным увеличивать i
в двух разных местах. Но все таки. Хороший ответ +1 :)
Практика очень плохой заключается в увеличении переменной цикла for опять таки внутри тела цикла for. Вы с вашим опытом не должны учить новичков таким вещам :)