← Назад к вопросам
Функция: массив объектов → массив имён
1.3 Junior🔥 131 комментариев
#Другое#Основы Java
Условие
Напишите функцию, которая принимает массив объектов Person и возвращает массив имён всех объектов.
class Person {
private String name;
private int age;
// конструктор, геттеры
}
Примеры
Вход:
Person[] persons = {
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 35)
};
Выход: ["Alice", "Bob", "Charlie"]
Требования
- Реализуйте с использованием цикла
- Реализуйте с использованием Stream API
- Обработайте null в массиве
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Извлечение имён из массива объектов
Суть задачи
Преобразовать массив объектов Person в массив строк (имён). Это базовая операция трансформации данных, которая в Java решается несколькими способами.
Определение класса Person
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
Способ 1: Традиционный цикл for
public String[] getNames(Person[] persons) {
if (persons == null) {
return new String[]{}; // пустой массив для null
}
String[] names = new String[persons.length];
for (int i = 0; i < persons.length; i++) {
if (persons[i] != null) {
names[i] = persons[i].getName();
}
// если persons[i] == null, то names[i] остаётся null
}
return names;
}
Недостатки:
- Требует ручного управления индексами
- Сохраняет null значения в результате
- Неэлегантно
Способ 2: Цикл for-each (итератор)
public String[] getNamesForEach(Person[] persons) {
if (persons == null) {
return new String[]{}; // пустой массив
}
List<String> namesList = new ArrayList<>();
for (Person person : persons) {
if (person != null) {
namesList.add(person.getName());
}
}
// Преобразуем List в массив
return namesList.toArray(new String[0]);
}
Преимущества:
- Чище, чем цикл с индексом
- Автоматически пропускает null значения
- Результат не содержит null элементов
Способ 3: Stream API (современный, O(n) рекомендуемый)
public String[] getNamesStream(Person[] persons) {
if (persons == null) {
return new String[]{}; // пустой массив
}
return Arrays.stream(persons)
.filter(Objects::nonNull) // фильтруем null
.map(Person::getName) // трансформируем в имена
.toArray(String[]::new); // собираем в массив
}
Преимущества:
- Декларативный стиль (что делать, а не как)
- Читаемый и компактный
- Легко добавлять дополнительные операции (сортировка, фильтрация и т.д.)
- Лучшая производительность на больших наборах данных
Пошаговый пример Stream API
Person[] persons = {
new Person("Alice", 25),
new Person("Bob", 30),
null,
new Person("Charlie", 35)
};
String[] names = getNamesStream(persons);
// Результат: ["Alice", "Bob", "Charlie"]
// Пошагово:
// 1. Arrays.stream(persons) → Stream<Person>
// 2. .filter(Objects::nonNull) → исключаем null → [Alice, Bob, Charlie]
// 3. .map(Person::getName) → трансформируем → ["Alice", "Bob", "Charlie"]
// 4. .toArray(String[]::new) → собираем в String[]
Вариант 4: Возврат List вместо массива
public List<String> getNamesAsList(Person[] persons) {
if (persons == null) {
return Collections.emptyList(); // пустой list
}
return Arrays.stream(persons)
.filter(Objects::nonNull)
.map(Person::getName)
.collect(Collectors.toList());
}
Когда использовать List вместо массива:
- Когда размер может изменяться
- Когда нужны операции как
add(),remove() - Когда результат пасуется в другие методы, работающие с Collection
Полный класс с примерами
import java.util.*;
import java.util.stream.*;
public class PersonNameExtractor {
/**
* Традиционный цикл for
*/
public static String[] getNamesTraditional(Person[] persons) {
if (persons == null) {
return new String[]{}; // обработка null
}
String[] names = new String[persons.length];
for (int i = 0; i < persons.length; i++) {
if (persons[i] != null) {
names[i] = persons[i].getName();
}
}
return names;
}
/**
* Цикл for-each с коллекцией
*/
public static String[] getNamesForEach(Person[] persons) {
if (persons == null) {
return new String[]{}; // обработка null
}
List<String> names = new ArrayList<>();
for (Person person : persons) {
if (person != null) {
names.add(person.getName());
}
}
return names.toArray(new String[0]);
}
/**
* Stream API (рекомендуемый способ)
*/
public static String[] getNamesStream(Person[] persons) {
if (persons == null) {
return new String[]{};
}
return Arrays.stream(persons)
.filter(Objects::nonNull)
.map(Person::getName)
.toArray(String[]::new);
}
/**
* Stream API с возвратом List
*/
public static List<String> getNamesAsList(Person[] persons) {
if (persons == null) {
return Collections.emptyList();
}
return Arrays.stream(persons)
.filter(Objects::nonNull)
.map(Person::getName)
.collect(Collectors.toList());
}
}
Обработка различных случаев
// Случай 1: обычный массив
Person[] persons = {
new Person("Alice", 25),
new Person("Bob", 30)
};
String[] names = getNamesStream(persons);
// Результат: ["Alice", "Bob"]
// Случай 2: массив с null элементами
Person[] personsWithNull = {
new Person("Alice", 25),
null,
new Person("Bob", 30),
null
};
String[] names2 = getNamesStream(personsWithNull);
// Результат: ["Alice", "Bob"] (null автоматически исключены)
// Случай 3: null массив
String[] names3 = getNamesStream(null);
// Результат: [] (пустой массив)
// Случай 4: пустой массив
String[] names4 = getNamesStream(new Person[]{});
// Результат: [] (пустой массив)
Расширенные операции со Stream
// Получить имена, отсортированные по алфавиту
public static String[] getNamesStreamSorted(Person[] persons) {
return Arrays.stream(persons)
.filter(Objects::nonNull)
.map(Person::getName)
.sorted()
.toArray(String[]::new);
}
// Получить имена в верхнем регистре
public static String[] getNamesStreamUpperCase(Person[] persons) {
return Arrays.stream(persons)
.filter(Objects::nonNull)
.map(person -> person.getName().toUpperCase())
.toArray(String[]::new);
}
// Получить только имена, начинающиеся с A
public static String[] getNamesStartingWith(Person[] persons, char letter) {
return Arrays.stream(persons)
.filter(Objects::nonNull)
.map(Person::getName)
.filter(name -> name.charAt(0) == letter)
.toArray(String[]::new);
}
Тесты
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
public class PersonNameExtractorTest {
@Test
public void testBasicArray() {
Person[] persons = {
new Person("Alice", 25),
new Person("Bob", 30),
new Person("Charlie", 35)
};
String[] expected = {"Alice", "Bob", "Charlie"};
assertArrayEquals(expected, PersonNameExtractor.getNamesStream(persons));
}
@Test
public void testArrayWithNull() {
Person[] persons = {
new Person("Alice", 25),
null,
new Person("Bob", 30)
};
String[] expected = {"Alice", "Bob"};
assertArrayEquals(expected, PersonNameExtractor.getNamesStream(persons));
}
@Test
public void testNullArray() {
String[] result = PersonNameExtractor.getNamesStream(null);
assertEquals(0, result.length);
}
@Test
public void testEmptyArray() {
Person[] persons = {};
String[] result = PersonNameExtractor.getNamesStream(persons);
assertEquals(0, result.length);
}
@Test
public void testSingleElement() {
Person[] persons = {new Person("Alice", 25)};
String[] expected = {"Alice"};
assertArrayEquals(expected, PersonNameExtractor.getNamesStream(persons));
}
}
Сравнение подходов
| Подход | Скорость | Читаемость | Гибкость | Рекомендация |
|---|---|---|---|---|
| For с индексом | O(n) быстро | Плохая | Низкая | ❌ Избегать |
| For-each | O(n) быстро | Хорошая | Средняя | ✓ Приемлемо |
| Stream API | O(n) быстро | Отличная | Высокая | ✅ Предпочтительно |
Вывод
Stream API — это современный, читаемый и гибкий способ трансформировать данные в Java. Для данной задачи он идеален:
Arrays.stream(persons)
.filter(Objects::nonNull)
.map(Person::getName)
.toArray(String[]::new);
Это единственная строка, которая:
- Обрабатывает null элементы
- Трансформирует объекты в строки
- Возвращает массив
- Читается как описание того, что делать (декларативный стиль)