(매개변수) -> {실행코드}
@FunctionalInterface
)가 제공 (함수지향)// 익명 객체
Comparator<Student> comparator = new Comparator<>() {
public int compare(Student o1, Student o2) { Integer.compare(o1.score, o2.score) }
}
// 람다
Comparator<Student> comparator = (o1, o2) -> { Integer.compare(o1.score, o2.score) }
compare()
재정의Comparator.java
is @FunctionalInerface
int compare(T o1, T o2);
of Comparator.java
is only one abstract methodpublic class CustomFunctionInterfaceExample {
public static void main(String[] args) {
// 인터페이스는 인스턴스 만들 수 없지만 추상 메서드 구현하면 가능
CustomFunctionInterface1 f0 = new CustomFunctionInterface1() {
@Override
public void lambda() {
System.out.println("hello world");
}
};
// => 람다로 한줄 가능
// 구현부 한줄 이면 중괄호 생략 가능. 여러줄 이면 생략 불가
CustomFunctionInterface1 f1 = () -> System.out.println("hello world");
f1.lambda();
// 파라미터, 반환값 없으면 뭐든지 다 구현 가능함을 의미
CustomFunctionInterface1 f12 = () -> System.out.println("hello lambda");
f12.lambda();
// 인스턴스 아닌 클래스로 호출
CustomFunctionInterface1.staticMethod();
// default, static은 인터페이스에서 여러개 정의 가능
f1.defaultMethod();
f12.defaultMethod();
}
@FunctionalInterface // 추상 메서드 2개되면 컴파일 에러 잡아줌 (@Retention(RetentionPolicy.RUNTIME)
public interface CustomFunctionInterface1 {
// abstract method
void lambda(); // 매개변수, 반환값 없음
// void lambda2();
// default method
// 인스턴스(외부)에 제공
default void defaultMethod() {
System.out.println("defaultMethod");
}
// static method
static void staticMethod() {
System.out.println("staticMethod");
}
// public
// 인터페이스는 기본 접근 제어자가 public (외부 객체에 메서드 제공하는 역할 이므로)
}
void lambda();
void lambda(T arg);
void lambda(T... args);
int lambda(int i1, int i2);
int lambda(int i1, int i2);
public class CustomFunctionInterfaceExample {
public static void main(String[] args) {
// 0. 인터페이스는 인스턴스 만들 수 없지만 추상 메서드 구현 하면 가능 (익명 객체)
CustomFunctionInterface1 f0 = new CustomFunctionInterface1() {
@Override
public void lambda() {
System.out.println("hello world");
}
};
// => 람다로 한줄 가능
// 구현부 한줄 이면 중괄호 생략 가능. 여러줄 이면 생략 불가
CustomFunctionInterface1 f1 = () -> System.out.println("hello world");
f1.lambda();
// 1. void, ()
CustomFunctionInterface1 f12 = () -> System.out.println("hello lambda");
f12.lambda();
// 인스턴스 아닌 클래스로 호출
CustomFunctionInterface1.staticMethod();
// default, static은 인터페이스에서 여러개 정의 가능
f1.defaultMethod();
f12.defaultMethod();
// 2. void, T
CustomFunctionInterface2.staticMethod(); // 인스턴스 생성 전 호출 가능
CustomFunctionInterface2<Object> f2 = a -> System.out.println(a);
// <Object> 이므로 모든 데이터 타입 인자로 가능 (default 이므로 생략 가능)
f2.lambda(10);
f2.lambda("hello world");
f2.lambda(new Something("hello world", 10));
f2.defaultMethod();
System.out.println();
// 3. void, T...(가변 인자)
CustomFunctionInterface3.staticMethod();
CustomFunctionInterface3 f3 = arguments -> {
for (int i = 0; i < arguments.length; i++) {
System.out.print(arguments[i] + ",");
}
System.out.println();
// return arguments;
};
f3.lambda();
f3.lambda(10);
f3.lambda(10, 20);
f3.lambda(10, 20, 30);
f3.lambda(10, 20, 30, 40, 50);
f3.defaultMethod();
System.out.println();
// 4. int, 인자 2개
CustomFunctionInterface4.staticMethod();
CustomFunctionInterface4 f4 = (a, b) -> a + b;
System.out.println(f4.lambda(1, 2));
System.out.println(f4.lambda(3, 4));
System.out.println(f4.lambda(100, 200));
System.out.println(f4.lambda(300, 400));
f4.defaultMethod();
// 5. T, T...
// Object default => 덧셈 아닌 결합
CustomFunctionInterface5.staticMethod();
CustomFunctionInterface5 f5 = arguments -> {
String str = "";
for (Object arg: arguments) {
str += arg;
}
return str;
};
System.out.println(f5.lambda());
System.out.println(f5.lambda(1));
System.out.println(f5.lambda(1, 2));
System.out.println(f5.lambda(1, 2, 3, 4));
System.out.println(f5.lambda("a"));
System.out.println(f5.lambda("a", "b"));
System.out.println(f5.lambda("a", "b", "c"));
System.out.println(f5.lambda("a", "b", "c", "d"));
f5.defaultMethod();
}
}
@FunctionalInterface
)public class ConsumerExample {
public static void main(String[] args) {
// 1. 인스턴스 생성(new 생략) + 추상 메서드 람다 구현 / 2. 추상 메서드 호출
Consumer<String> consumer = t -> System.out.println(t + "8");
consumer.accept("java");
BiConsumer<String, String> biConsumer = (t, u) -> System.out.println(t + u);
biConsumer.accept("java", "8");
DoubleConsumer doubleConsumer = d -> System.out.println("Java" + d);
doubleConsumer.accept(8.0);
ObjIntConsumer<String> objIntConsumer = (t, i) -> System.out.println(t + i);
objIntConsumer.accept("Java", 8);
}
}
public class SupplierExample {
public static void main(String[] args) {
// 1. 인스턴스 생성(new 생략) + 추상 메서드 람다 구현 / 2. 추상 메서드 호출
Supplier<String> supplier = () -> "java8";
System.out.println(supplier.get());
IntSupplier intSupplier = () -> (int) (Math.random() * 45) + 1;
System.out.println(intSupplier.getAsInt());
}
}
public class FunctionExample {
private static List<Student> students = Arrays.asList(
new Student("kim", 20, 80),
new Student("lee", 25, 50),
new Student("park", 29, 100)
);
// 1. 인터페이스의 인스턴스 생성 : Function<Student, String> function
// public interface Function<T, R> {
public static String mapToString(Student student, Function<Student, String> function) {
// 2. 구현한 추상 메서드를 인스턴스로 호출
return function.apply(student);
}
public static int mapToInt(Student student, ToIntFunction<Student> function) {
return function.applyAsInt(student);
}
public static double average(ToIntFunction<Student> function) {
int sum = 0;
for (Student student: students) {
sum += function.applyAsInt(student);
}
return (double)sum / students.size();
}
// 3. 추상 메서드 람다로 구현 : mapToString(student, t -> t.getName()
// R apply(T t);
public static void main(String[] args) {
for (Student student: students) {
System.out.println(mapToString(student, t -> t.getName()));
}
System.out.println();
for (Student student: students) {
System.out.println(mapToInt(student, t -> t.getAge()));
}
System.out.println();
for (Student student: students) {
System.out.println(mapToInt(student, t -> t.getScore()));
}
System.out.println();
System.out.printf( "age average = %f\n", average( t -> t.getAge() ));
System.out.printf( "score average = %f\n", average( t -> t.getScore() ));
}
}
public class OperatorExample {
private static int[] ints = { 92, 95, 97, 100, 85, -100, -200, 300 };
// 1. 인터페이스의 인스턴스 생성
public static int maxOrMin(IntBinaryOperator operator) {
int res = ints[0];
for (int i: ints) {
// 2. 추상 메서드 호출
res = operator.applyAsInt(res, i); // 갱신
}
return res;
}
public static void main(String[] args) {
// 3. 인터페이스의 추상 메서드 구현
// int max = maxOrMin((a, b) -> Math.max(a, b));
int max = maxOrMin(Math :: max);
System.out.println("max = " + max);
// int min = maxOrMin((a, b) -> Math.min(a, b));
int min = maxOrMin(Math :: min);
System.out.println("min = " + min);
}
}
boolean test(T t);
public class PredicateExample {
private static List<Student> students = Arrays.asList(
new Student("kim", 20, 80),
new Student("dong", 19, 60),
new Student("kil", 17, 70),
new Student("yoon", 16, 100),
new Student("lee", 25, 50),
new Student("park", 29, 100),
new Student("choi", 39, 70),
new Student("kang", 31, 80),
new Student("lim", 32, 60)
);
// 1. 인터페이스의 인스턴스 생성
public static double averageIf(Predicate<Student> predicate) {
int count = 0;
int sum = 0;
for ( Student student: students ) {
// 2. 추상 메서드 호출 + 인자 전달
if ( predicate.test(student) ) { // 특정 조건의 student만 모아서
sum += student.getScore(); // 평균 구하기
count++;
}
}
return (double) sum / count;
}
public static void main(String[] args) {
// 3. 추상 메서드 구현
double average30 = averageIf( t -> t.getAge() >= 30 );
// student에서 30살 이상인 애들만 인자로 전달되어 평균 구해짐 (30살 이상 학생의 평균)
System.out.println("average30 = " + average30);
double average20 = averageIf( t -> t.getAge() < 20 );
System.out.println("average20 = " + average20);
}
}
클래스 :: 정적 메소드
인스턴스 변수 :: 메소드
클래스 :: new
https://jaehoney.tistory.com/112
https://steady-coding.tistory.com/568
volatile
synchronized
Automic variable
private volatile int value;
: volatile은 메인 메모리(스레드 아닌)에서 값을 읽음private static AtomicLong number = new AtomicLong(0); // 원래 값이
public static synchronized void increase() {
number.set(number.get() + 1); // 수정 되었으므로
System.out.println(number); // 수정된 값을 가져옴
}