#java #for-loop #arraylist #collections #jvm
#java #for-цикл #arraylist #Коллекции #jvm
Вопрос:
Упрощенный пример
Представьте, что я определяю person как:
public class Person (String name, int age)
и тогда у меня есть список людей…
public class ListOfPeople {
private ArrayList<Person> people;
}
затем я хочу иметь возможность создавать несколько человек за один раз, делать что-то вроде…
ListOfPeople myFriends = new ListOfPeople("Chris",33,"Adam",26,"John",50)
Я знаю, что мог бы инициализировать каждый из них по отдельности, а затем добавить их, мне просто было любопытно посмотреть, могу ли я каким-то образом просто создать их «на лету», как описано выше
Комментарии:
1. Каков источник для набора имен и возрастов?
2. Что-то не так с выполнением
new ListOfPeople(new Person("Chris", 33), new Person("Adam", 26), new Person("John", 50))
? Тогда вы не добавляете их после их создания, и это все еще работает на лету. Если это не сработает, вы всегда можете создать для себя пользовательскийArrayList
класс, который наследует basicArrayList
и имеет пользовательский конструктор, который принимает строки и инициализирует все, чтобы вы могли передавать данные, как в вашем примере.3. Вы также могли бы черпать вдохновение из java 9
java.util.Map.of(K, V, K, V, ...)
4. Просто для записи: список людей, который вы решаете, создавая простой
List<People>
объект. Если ваш класс содержит только этот внутренний список… тогда это не добавляет никакой ценности вашему дизайну. У Java уже есть коллекции. Ваш новый класс только усложняет задачу, например, вам придется реализовать equals() , hashCode() и toString(), чтобы сделать что-то полезное. Итак, имхо, первое, что нужно сделать: спросите себя, действительно ли вам нужен или нужен этот специальный класс ListOfSomething . Или наоборот: как вы думаете, вы хотите создать такой новый класс для каждого и любого5. @GhostCat в реальной жизни сценарий более сложный и требует большего, чем просто простой список, я просто убирал его для краткости и простоты понимания
Ответ №1:
Вы могли бы сделать что-то вроде этого:
List<Person> personListConstructor(String... data) {
List<Person> personList = new ArrayList<>();
for (int i = 0; i < data.length / 2; i ) {
personList.add(new Person(data[2 * i], Integer.parseInt(data[2 * i 1])));
}
return personList;
}
Конечно, ему не хватает проверки — должно быть четное количество аргументов, каждая секунда должна быть целым числом. Другим решением было бы использовать массив Object
s:
List<Person> personListConstructor(Object... data) {
List<Person> personList = new ArrayList<>();
for (int i = 0; i < data.length / 2; i ) {
personList.add(new Person((String) data[2 * i], (Integer) data[2 * i 1]));
}
return personList;
}
Те же уведомления здесь.
Комментарии:
1. Может быть, не самый элегантный, но он, безусловно, подходит для моего требования!
Ответ №2:
Вы можете создать конструктор, который принимает массив Person
объектов:
public class ListOfPeople {
private ArrayList<Person> people;
public ListOfPeople(Person... persons) {
for (Person person : persons) {
people.add(person);
}
}
}
И используйте его следующим образом:
ListOfPeople myFriends = new ListOfPeople(new Person("Chris", 33), new Person("Adam",26), new Person("John",50));
Ответ №3:
Было интересно, как это сделать, используя lambda, и вот простое решение, если кому-то интересно.
public class Person {
String name;
int age;
public Person(List<String> attributes) {
attributes.stream().findFirst().ifPresent(this::setName);
attributes.stream().skip(1).findFirst().map(Integer::parseInt).ifPresent(this::setAge);
}
// getters, setters
}
public class ListOfPersons {
List<Person> people;
public ListOfPersons(String ...persons) {
final int chunkSize = 2;
final AtomicInteger counter = new AtomicInteger();
this.people = Stream.of(persons)
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / chunkSize))
.values()
.stream()
.map(Person::new)
.collect(Collectors.toList());
System.out.println(Arrays.toString(this.people.toArray()));
}
}
Итак, new new ListOfPersons("A", "1", "B", "2", "C")
возвращает
[Person{name='A', age=1}, Person{name='B', age=2}, Person{name='C', age=0}]
Комментарии:
1. Мне потребуется некоторое время, чтобы прочитать и понять, как это работает, но это выглядит очень впечатляюще! Я не знаком с потоками и понятия не имею, что такое AtomicInteger, но я проведу некоторое исследование 🙂