Java. Разбор FunctionalInterface Function и Predicate

Разбор FunctionalInterface Function:


@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}

У функционального интерфейса Function
 есть несколько методов, которые почему-то
редко используют:
andThen
compose
Тут, конечно, проще использовать UnaryOperator
который extends Function<T, T>

Function<String, String> func1 = s -> s + "1";
Function<String, String> func2 = s -> s + "2";
Function<String, String> func3 = s -> s + "3";
Function<String, String> func4 = s -> s + "4";
func1.andThen(func2).andThen(func3).andThen(func4).apply("AND_");
//тут будет выведено AND_1234
func1.compose(func2).compose(func3).compose(func4).apply("COMPOSE_");
//тут вывод в обратном порядке COMPOSE_4321
Но можно еще и миксовать 
func1.andThen(func2).compose(func3).andThen(func4).apply("MIX_");
//MIX_3124 - те сначала будет выведены compose, а потом andThen

Разбор FunctionalInterface Predicate:
Методы :
and
negate
or
Есть класс User:
public final class User {
private String userName;
private int userAge;

public User(String userName,int userAge) {
this.userName = userName;
this.userAge = userAge;
}

public String getUserName() {
return userName;
}

public void setUserName(String userName) {
this.userName = userName;
}

public int getUserAge() {
return userAge;
}

public void setUserAge(int userAge) {
this.userAge = userAge;
}

@Override
public String toString() {
return "User{" +
"userName='" + userName + '\'' +
", userAge=" + userAge +
'}';
}


@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return userAge == user.userAge &&
Objects.equals(userName, user.userName);
}

@Override
public int hashCode() {

return Objects.hash(userName, userAge);
}
}

И есть класс UserUtil для более удобной работы с коллекцией
пользователей:
public class UserUtil {

public static List<User> getUsers() {
List<User> users = new ArrayList<>();
users.add(new User("Ivan",34));
users.add(new User("Alex",35));
users.add(new User("Max",21));
users.add(new User("Tom",45));
users.add(new User("Richard",52));
users.add(new User("Donald",19));
return users;
}
}



Методы в Predicate:
and
negate
or
Добавим методы UserUtil:
public static Predicate<User> olderThan(int older) {
return u -> u.getUserAge() > older;
}

public static Predicate<User> youngerThan(int younger) {
return u -> u.getUserAge() < younger;
}

public static Predicate<User> sameAge(int sameAge) {
return u -> u.getUserAge() == sameAge;
}

public static Predicate<User> sameName(String name) {
return u -> u.getUserName().equalsIgnoreCase(name);
}

public static Predicate<User> containsName(String name) {
return u -> u.getUserName().contains(name);
}

Найти пользователей, старше 50 лет
List<User> allUsers = UserUtil.getUsers();
List<User> usersOlder50 = allUsers.stream().filter(u -> u.getUserAge() > 50).collect(Collectors.toList());
System.out.println(usersOlder50);
//Старше 30
List<User> olderThan30 = allUsers.stream()
.filter(olderThan(30)).collect(Collectors.toList());
//меньше или равно 30
List<User> olderThan30 = allUsers.stream()
.filter(olderThan(30).negate())
.collect(Collectors.toList());
//больше 30 и младше 50
List<User> olderThan30 = allUsers.stream()
.filter(olderThan(30).and(youngerThan(50)))
.collect(Collectors.toList());
//старше 30 или имя "Max":
List<User> olderThan30orMax = allUsers.stream()
.filter(olderThan(30).or(containsName("Max")))
.collect(Collectors.toList());

Можно сдалать просто метод который просто принимает
предикат:
private static Stream<User> users() {
return getUsers().stream();
}


public static List<User> listUsers(Predicate<User> predicate) {
return users().filter(predicate).collect(Collectors.toList());
}

Вызов:
List<User> usersOlder30 = UserUtil.listUsers(olderThan(30));
Полный код класса UserUtil:
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class UserUtil {

public static List<User> getUsers() {
List<User> users = new ArrayList<>();
users.add(new User("Ivan",34));
users.add(new User("Alex",35));
users.add(new User("Max",21));
users.add(new User("Tom",45));
users.add(new User("Richard",52));
users.add(new User("Donald",19));
return users;
}


private static Stream<User> users() {
return getUsers().stream();
}


public static List<User> listUsers(Predicate<User> predicate) {
return users().filter(predicate).collect(Collectors.toList());
}


public static Predicate<User> olderThan(int older) {
return u -> u.getUserAge() > older;
}

public static Predicate<User> youngerThan(int younger) {
return u -> u.getUserAge() < younger;
}

public static Predicate<User> sameAge(int sameAge) {
return u -> u.getUserAge() == sameAge;
}

public static Predicate<User> sameName(String name) {
return u -> u.getUserName().equalsIgnoreCase(name);
}

public static Predicate<User> containsName(String name) {
return u -> u.getUserName().contains(name);
}
}





Комментарии

Популярные сообщения из этого блога

Java. Лучшая практика работы с Enum

Java. Разбор класса Collections

Java. Удаление данных из коллекции