java.util.function

왜 이렇게 양이 많을까?
T만을 사용한다면 boxed 타입인 Integer, String과 같은 것들을 계속 사용해줘야 한다. 그러나 이것은 int 등에 비해 메모리를 훨씬 더 많이 사용하기에 primitive 타입을 다루는 interface를 만들었다.
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
}
// 사용예제1
public class Main implements Function<Integer, Integer> {
@Override
public Integer apply(Integer x) {
return x+10;
}
}
public static void main(String[] args) {
Function<Integer, Integer> myAdder = new Main();
int result = myAdder.apply(5);
System.out.println(result);
}
Function<Integer, Integer> myAdder = (Integer x) -> {
return x + 10;
};
int result = myAdder.apply(5);
System.out.println(result);
Function<Integer, Integer> myAdder = x -> x + 10;
int result = myAdder.apply(5);
System.out.println(result);
@FunctionalInterface
public interface BiFunction<T, U, R> {
R apply(T t, U u);
}
BiFunction<Integer, Integer, Integer> add = (Integer x, Integer y) -> {
return x + y;
};
int result1 = add.apply(3, 5);
System.out.println(result1);
@FunctionalInterface
public interface TriFunction<T,U,V,R> {
R apply(T t, U u, V v);
}
// 직접 만들어서 사용
TriFunction<Integer, Integer, Integer, Integer> addThree = (x, y, z) -> x + y + z;
@FunctionalInterface
public interface Supplier<T> {
T get();
}
Supplier<String> mySup = () -> "hello world";
System.out.println(mySup.get());
Supplier<Double> myRandom = () -> Math.random();
System.out.println(myRandom.get());
// 메서드를 만들어서 인수로 받아 사용
public static void printRandom(Supplier<Double> random, int count) {
for (int i = 0; i < count; i++) {
System.out.println(random.get());
}
}
// 새로 만든 메서드 사용
printRandom(myRandom,5);
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
Consumer<String> myConsumer = (String str) -> System.out.println(str);
myConsumer.accept("hello");
// 매서드를 만들어 사용
public static <T> void process(List<T> inputs, Consumer<T> processor) {
for (T input : inputs) {
processor.accept(input);
}
}
// consuemr 인터페이스 만들어 사용
Consumer<Integer> myDifferentIntegerProcessor = x ->
System.out.println("Processing integer in different way " + x);
process(integerInputs, myDifferentIntegerProcessor);
// 람다식으로 바로 사용
List<Double> doubleInputs = Arrays.asList(1.1, 2.2, 3.3);
process(doubleInputs, x -> System.out.println("Processing double " + x));
@FunctionalInterface
public interface BiConsumer<T, U> {
void accept(T t, U u);
}
public static <T> void process(List<T> inputs, BiConsumer<Integer, T> processor) {
for (int i = 0; i< inputs.size(); i++) {
processor.accept(i, inputs.get(i));
}
}
BiConsumer<Integer, Double> myDoubleProcessor =
(index, input) ->
System.out.println("Processing " + input + " at index " + index);
List<Double> inputs = Arrays.asList(1.1, 2.2, 3.3);
process(inputs, myDoubleProcessor);
@FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
Predicate<Integer> isPositive = x -> x > 0;
System.out.println(isPositive.test(-10));
//
public static <T> List<T> filter(List<T> inputs, Predicate<T> condition) {
List<T> output = new ArrayList<>();
for (T input : inputs) {
if (condition.test(input)) {
output.add(input);
}
}
return output;
}
// 인터페이스 내부에 디폴트 메서드 이용
List<Integer> inputs = Arrays.asList(10, -5, 4, -2, 0, 3);
System.out.println("Positive number: " + filter(inputs, isPositive));
System.out.println("Non-positive number: " + filter(inputs, isPositive.negate()));
System.out.println("Non-negative number: "
+ filter(inputs, isPositive.or(x -> x == 0)));
System.out.println("Positive even numbers: "
+ filter(inputs, isPositive.and(x -> x % 2 == 0)));
}
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
List<User> users = new ArrayList<>();
users.add(new User(3, "Alice"));
users.add(new User(1, "Charlie"));
users.add(new User(5, "Bob"));
System.out.println(users);
Comparator<User> idComparator = (u1, u2) -> u1.getId() - u2.getId();
Collections.sort(users, (u1, u2) -> u1.getId() - u2.getId());
System.out.println(users);
Collections.sort(users, (u1, u2) -> u1.getName().compareTo(u2.getName()));
System.out.println(users);