Как вывести определенные поля класса в методе

У меня есть метод banUser:

public User banUser(User user) {
    for (var element : users.entrySet()) {
        if (element.getValue().getToken().equals(user.getToken())) {
            element.getValue().setBanReason(user.getBanReason());
           element.getValue().setDayOfBan(currentDateAndTime.toString());
            element.getValue().setBlocking(true);
            return user;
        }
    }
    return null;
}

И сам класс:

@Data
public class User {
    
    private int id;
    
    private String token;
    
    private String name;
    
    private String email;
    
    private String password;
    
    private String banReason;
    
    private String dayOfBan;
    
    private Boolean blocking = false;
}

Как мне вернуть у User только поля token и id в методе banUser()?


Ответы (1 шт):

Автор решения: Nowhere Man

Чтобы вернуть только несколько полей, достаточно создать некий класс-обертку или DTO-класс (для Java 17+ можно использовать кортеж record) и вернуть соответствующий экземпляр.

Также следует заметить, что можно было итерироваться по содержимому мапы Map<Key, User> users, которое возвращает метод Map::values() и вероятно следовало бы возвращать Optional вместо null:

record UserIdToken(int id, String token) {}

public Optional<UserIdToken> banUser(User user) {
    for (User v : users.values()) {
        if (v.getToken().equals(user.getToken())) {
            v.setBanReason(user.getBanReason());
            v.setDayOfBan(currentDateAndTime.toString());
            v.setBlocking(true);
            return Optional.of(new UserIdToken(v.getId(), v.getToken()));
        }
    }
    return Optional.empty();
}

Дополнение: Вариант с использованием Stream API

Здесь для изменения свойств объекта в мапе лучше реализовать отдельный метод User banUser(User user, String banReason).

record UserIdToken(int id, String token) {
    // добавить конструктор для кортежа
    public UserIdToken(User user) {
        this(user.getId(), user.getToken());
    }
}

public Optional<UserIdToken> banUser(User user) {
    return users.values().stream() // Stream<User>
        .filter(u -> u.getToken().equals(user.getToken()))
        .findFirst()            // Optional<User>
        .map(u -> banUser(u, user.getBanReason()))
        .map(UserIdToken::new); // Optional<UserIdToken>
}

// реализовать отдельный метод banUser для копирования нужных свойств
private User banUser(User user, String banReason) {
    user.setBanReason(banReason);
    user.setDayOfBan(currentDateAndTime.toString());
    user.setBlocking(true);

    return user;
}

Если вдруг мапа пользователей использует в качестве ключей те самые токены, код может ещё больше упроститься (с учётом вышеуказанных изменений):

// предполагаем, что ключами в Map<String, User> users являются токены
public Optional<UserIdToken> banUser(User user) {
    return Optional.ofNullable(users.get(user.Token())) // Optional<User>
        .map(u -> banUser(u, user.getBanReason()))      // Optional<User>
        .map(UserIdToken::new);                         // Optional<UserIdToken>
}
→ Ссылка