← Назад к вопросам

Функция: массив объектов → массив имён

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-eachO(n) быстроХорошаяСредняя✓ Приемлемо
Stream APIO(n) быстроОтличнаяВысокаяПредпочтительно

Вывод

Stream API — это современный, читаемый и гибкий способ трансформировать данные в Java. Для данной задачи он идеален:

Arrays.stream(persons)
    .filter(Objects::nonNull)
    .map(Person::getName)
    .toArray(String[]::new);

Это единственная строка, которая:

  • Обрабатывает null элементы
  • Трансформирует объекты в строки
  • Возвращает массив
  • Читается как описание того, что делать (декларативный стиль)
Функция: массив объектов → массив имён | PrepBro