์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- Spring Security
- spring data jpa
- CLI๋ช ๋ น์ด
- CSS
- Publishing
- ์ธํ ๋ฆฌ์ ์ด
- java
- ํ๊ณ
- FilterChain
- ๋ฐฑ์ค์๊ณ ๋ฆฌ์ฆ
- ์๊ณ ๋ฆฌ์ฆ
- ์คํ๋ง
- ๋ฐ์ผ๋ฆฌ์ฝ๋ฉ
- ์ปฌ๋ ์ ํ๋ ์์ํฌ
- ์ฒซ๊ธ์๋๋ฌธ์
- ๊ทธ๋ฆฌ๋
- ๊ณ์ฐ๊ธฐ๋ง๋ค๊ธฐ
- ๋ฐฑ์๋
- ์๋ฐ
- fibonacci
- ์ ๋ค๋ฆญ์ค
- ๊ฑฐ๋ญ์ ๊ณฑ
- Spring Data JDBC
- HTML
- ๋ถํธ์บ ํ
- ๊นํ๋ธ
- testing
- ๋ฌธ์์ด๋ค์ง๊ธฐ
- ํ์ดํ๋ก๊ทธ๋๋ฐ
- ์๋ฃ๊ตฌ์กฐ
- Today
- Total
๋์ ๋ชจ์
018 | Java - Enum, Annotation, Lambda, Stream ๋ณธ๋ฌธ
๐ Enum
๐ค History of Enum
- ์๋ก ๊ด๋ จ๋ ์์(๋ณํ์ง ์๋ ๊ฐ, final)๋ค์ ์งํฉ
- ํ์ ๋์ด ๋ณํ์ง ์๋ ๋ฐ์ดํฐ๋ฅผ ๋ค๋ฃจ๋ ๋ฐ ์ฌ์ฉ
// ๊ณ์
public static final int SPRING = 1;
public static final int SUMMER = 2;
public static final int AUTUMN = 3;
public static final int WINTER = 4;
// ํ๋ ์์ํฌ
public static final int DJANGO = 1;
public static final int SPRING = 2;
// => ์ปดํ์ผ์๋ฌ. ๊ณ์ ์ SPRING๊ณผ ์ค๋ณต ๋ฐ์!
interface Seasons {
int SPRING = 1, SUMMER = 2, AUTUMN = 3, WINTER = 4;
}
interface Frameworks {
int DJANGO = 1, SPRING = 2, NEST = 3, EXPRESS = 4;
}
โ ์ค๋ณต ์์๋ช ๋ฌธ์ ๋ ํผํ ์ ์์ง๋ง ํ์ ์์ ์ฑ ๋ฌธ์ ๊ฐ ์๊น
if(Seasons.SPRING == Frameworks.SPRING) { }
โ ์๋ฏธ์ ์ผ๋ก ๋ค๋ฅธ ๊ฐ๋ ์ด์ง๋ง, ์ ๋์ ๋น๊ตํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ์ง ์์.
์ด๊ฑธ ํด๊ฒฐํด์ฃผ๋ ค๋ฉด ์๋ก ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๋ง๋ค์ด์ค์ผ๋จ
class Seasons {
public static final Seasons SPRING = new Seasons();
public static final Seasons SUMMER = new Seasons();
public static final Seasons FALL = new Seasons();
public static final Seasons WINTER = new Seasons();
}
class Frameworks {
public static final Frameworks DJANGO = new Frameworks();
public static final Frameworks SPRING = new Frameworks();
public static final Frameworks NEST = new Frameworks();
public static final Frameworks EXPRESS = new Frameworks();
}
โ ์์๋ช ์ค๋ณต, ํ์ ์์ ์ฑ ๋ฌธ์ ํด๊ฒฐ ๊ฐ๋ฅ. But, ์ฝ๋ ๊ธธ์ด์ง. ์ฌ์ฉ์ ์ ์ํ์ ์ด๋ผ switch๋ฌธ์ ์ฌ์ฉ ๋ถ๊ฐ
์ด๋์ ๋์จ๊ฒ enum
enum Seasons { SPRING, SUMMER, FALL, WINTER }
enum Frameworks { DJANGO, SPRING, NEST, EXPRESS }
๐ค Use Enum
์ด๊ฑฐํ์ ์ฌ์ฉ
enum ์ด๊ฑฐํ์ด๋ฆ {์์๋ช
1, ์์๋ช
2, ์์๋ช
3, ...}
์์
eums Seasons {
SPRING, //์ ์๊ฐ 0 ํ ๋น
SUMMER, //์ ์๊ฐ 1 ํ ๋น
AUTUMN, //์ ์๊ฐ 2 ํ ๋น
WINTER //์ ์๊ฐ 3 ํ ๋น
}
- ์ด๊ฑฐํ์ ์ ์ธ๋ ์์์ ์ ๊ทผํ๋ ๋ฐฉ๋ฒ: ์ด๊ฑฐํ์ด๋ฆ.์์๋ช
enum Seasons { SPRING, SUMMER, AUTUMN, WINTER }
public class EnumExample {
public static void main(String[] args) {
System.out.println(Seasons.SPRING); // SPRING
}
}
- ์ฐธ์กฐ๋ณ์ favouriteSeason์ Seasons.SPRING ๋ด๊ธฐ
enum Seasons { SPRING, SUMMER, AUTUMN, WINTER }
public class EnumExample {
public static void main(String[] args) {
Seasons favoriteSeason = Seasons.SPRING;
System.out.println(favoriteSeason); // SPRING
}
}
โ Ref.
https://docs.oracle.com/javase/7/docs/api/java/lang/Enum.html
Enum (Java Platform SE 7 )
Returns the enum constant of the specified enum type with the specified name. The name must match exactly an identifier used to declare an enum constant in this type. (Extraneous whitespace characters are not permitted.) Note that for a particular enum typ
docs.oracle.com
๐ Annotation
๐ค About Annotation
- โ์ ๋ณด๋ฅผ ์ ๋ฌํด์ค ๋์โ์ ๋ชฉ์ ์ ๋
- ํ๋ก๊ทธ๋๋ฐ ์ธ์ด์ ์ํฅ์ ๋ฏธ์น์ง ์์ผ๋ฉฐ ๊ฐ๋ฐ์/ํ๋ก๊ทธ๋จ์๊ฒ ์ ๋ณด ์ ๊ณต
์ ๋ํ ์ด์ ์ ์ญํ
- ์ปดํ์ผ๋ฌ์๊ฒ ์ ๋ณด ์ ๊ณต โ ๋ฌธ๋ฒ ์๋ฌ ์ฒดํฌ
- ํ๋ก๊ทธ๋จ ๋น๋ ์ ์ ๋ณด ์ ๊ณต โ ์ฝ๋ ์๋ ์์ฑ
- ๋ฐํ์์๊ฒ ์ ๋ณด ์ ๊ณต โ ํน์ ๊ธฐ๋ฅ ์คํ
์ ๋ํ ์ด์ ์ ์ข ๋ฅ
- ํ์ค ์ ๋ํ ์ด์ : ์๋ฐ์์ ๊ธฐ๋ณธ ์ ๊ณต
- ๋ฉํ ์ ๋ํ ์ด์ : ์ ๋ํ ์ด์ ์ ๋ถ์ด๋ ์ ๋ํ ์ด์
- ์ฌ์ฉ์ ์ ์ ์ ๋ํ ์ด์
๐ค ํ์ค ์ ๋ํ
์ด์
(*)
@Override
- ๋ฉ์๋ ์์๋ง ๋ถ์ผ ์ ์์
- ์ ์ธํ ๋ฉ์๋๊ฐ ์์ ํด๋์ค์ ๋ฉ์๋๋ฅผ ์ค๋ฒ๋ผ์ด๋ฉํ๋ ๋ฉ์๋๋ผ๋ ๊ฒ์ ์ปดํ์ผ๋ฌ์๊ฒ ์๋ ค์ค
class Super {
void run() {}
}
class Sub extends Super {
@Override
void rnu() {} // ์ปดํ์ผ ์๋ฌ - ์คํ
}
@Deprecated
- ์์ผ๋ก ์ฌ์ฉํ์ง ์์ ๊ฒ์ ๊ถ์ฅํ๋ ํ๋๋ ๋ฉ์๋์ ๋ถ์
class OldClass {
@Deprecataed
int oldField;
@Deprecated
int getOldField() { return oldField; }
}
โ์ ๋ฉ์๋๋ฅผ ์์ ๋ ๊ฒ ๋์ @deprecated๋ฅผ ์ฌ์ฉํ ๊น?
โ์๋ฐ๋ ํ์ ํธํ์ฑ์ ์ค์์ ์ฌ๊น. ํ์ ๋ฒ์ ๊ณผ ํธํ์ฑ ๋๋ฌธ์ @deprecated๋ฅผ ์ฌ์ฉํ๋ฏ๋ก ์์ผ๋ก๋ ์ฌ์ฉํ์ง ๋ง๋ผ๊ณ ์๋ ค์ฃผ๋ ๊ฒ!
@SuppressWarnings
- ์ปดํ์ผ ๊ฒฝ๊ณ ๋ฉ์์ง๋ฅผ ์ ์ธ์ํฌ ๋ ์ฌ์ฉ
- @SuppressWarnings("all") // ๋ชจ๋ ๊ฒฝ๊ณ ์ ์ธ
- ๋ ์ด์์ ๊ฒฝ๊ณ ๋ฅผ ํ๋ฒ์ ์ ์ธ
- @SuppressWarnings({"deprecation", "unused", "null"})
@FunctionalInterface
- ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ ์ธํ ๋, ์ปดํ์ผ๋ฌ๊ฐ ํจ์ํ ์ธํฐํ์ด์ค์ ์ ์ธ์ด ๋ฐ๋ฅด๊ฒ ์ ์ธ๋์๋ ์ง ํ์ธ
- ํจ์ํ ์ธํฐํ์ด์ค: ๋จ ํ๋์ ์ถ์ ๋ฉ์๋๋ง ๊ฐ์ ธ์ผ ํจ
@FunctionalInterface public interface Runnable { public abstract void run (); // ํ๋์ ์ถ์ ๋ฉ์๋ }
- ๋ชฉ์ : ๋๋ค์ ์ฌ์ฉ (1:1 ๋งค์นญ)
๐ค ๋ฉํ ์ ๋ํ
์ด์
- ์ ๋ํ ์ด์ ์ ์ํ ์ ๋ํ ์ด์
- ์ ๋ํ ์ด์ ์ ์ ์ฉ๋์ ๋๋ ์ ์ง ๊ธฐ๊ฐ์ ์ ํ๋ ๋ฑ ์ ๋ํ ์ด์ ์ ์ ์ํ๋ ๋ฐ ์ฌ์ฉ
@Target
- ์ ๋ํ ์ด์ ์ ์ ์ ์ ์ฉ ๋์์ ์ง์ ํ๋๋ฐ ์ฌ์ฉ
- java.lang.annotation.ElementType
- ์์
import static java.lang.annotation.ElementType.*;
//import๋ฌธ์ ์ด์ฉํ์ฌ ElementType.TYPE ๋์ TYPE๊ณผ ๊ฐ์ด ์์ฑ ๊ฐ๋ฅ
@Target({FIELD, TYPE, TYPE_USE}) // ์ ์ฉ๋์: FIELD, TYPE
public @interface CustomAnnotation { } // ์ ์: CustomAnnotation
@CustomAnnotation // ์ ์ฉ๋์์ด TYPE์ธ ๊ฒฝ์ฐ
class Main {
@CustomAnnotation // ์ ์ฉ๋์์ด FIELD์ธ ๊ฒฝ์ฐ
int i;
}
@Documented
- ์ ๋ํ ์ด์ ์ ๋ํ ์ ๋ณด๊ฐ javadoc์ผ๋ก ์์ฑํ ๋ฌธ์์ ํฌํจ๋๋๋ก ํ๋ ์ ๋ํ ์ด์ ์ค์
- ์๋ฐ์์ ์ ๊ณตํ๋ ํ์ค ์ ๋ํ
์ด์
๊ณผ ๋ฉํ ์ ๋ํ
์ด์
๋ชจ๋ @Documented๊ฐ ์ ์ฉ
(@Override @SuppressWarnings๋ฅผ ์ ์ธ)
@Documented
@Target(ElementType.Type)
public @interface CustomAnnotation { }
@Inherited
- ํ์ ํด๋์ค๊ฐ ์ ๋ํ ์ด์ ์ ์์ โ ์์ ํด๋์ค์ ๋ถ์ ์ ๋ํ ์ด์ ๋ค์ด ๋์ผํ๊ฒ ์ ์ฉ
@Inherited // @SuperAnnotation์ด ํ์ ํด๋์ค๊น์ง ์ ์ฉ
@interface SuperAnnotation{ }
@SuperAnnotation
class Super { }
class Sub extends Super{ } // Sub์ ์ ๋ํ
์ด์
์ด ๋ถ์ ๊ฒ์ผ๋ก ์ธ์
@Retention
- ์ ๋ํ ์ด์ ์ ์ง์ ์๊ฐ ๊ฒฐ์
- ์ ๋ํ
์ด์
์ ์ง์ ์ฑ
(์ ์ง๋๋ ๊ธฐ๊ฐ ์ง์ ์์ฑ)
- SOURCE: ์์ค ํ์ผ์ ์กด์ฌ. ํด๋์ค ํ์ผ์๋ ์กด์ฌํ์ง ์์
- CLASS: ํด๋์ค ํ์ผ์ ์กด์ฌ. ์คํ ์ ์ฌ์ฉ๋ถ๊ฐ, ๊ธฐ๋ณธ๊ฐ
- RUNTIME: ํด๋์ค ํ์ผ์ ์กด์ฌ. ์คํ ์ ์ฌ์ฉ ๊ฐ๋ฅ
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
//์ค๋ฒ๋ผ์ด๋ฉ์ด ์ ๋๋ก ๋์๋์ง ์ปดํ์ผ๋ฌ๊ฐ ํ์ธํ๋ ์ฉ๋
//ํด๋์ค ํ์ผ์ ๋จ๊ธธ ํ์ ์์ด ์ปดํ์ผ์์๋ง ํ์ธํ๊ณ ์ฌ๋ผ์ง
public @interface Override(){ }
โ ์ ์์ ์์ @Override๋ ์ปดํ์ผ๋ฌ ์ฌ์ฉ ํ ๋ โ ์คํ ์ ์ฌ์ฉ x
@Repeatable
- ์ ๋ํ ์ด์ ๋ฐ๋ณต ์ฌ์ฉ ๊ฐ๋ฅ
- ์ฌ์ฉ์ ํ์ ์ ๋ํ ์ด์ ์ ์
@Repeatable(Works.class) // ToDo ์ ๋ํ
์ด์
์ ์ฌ๋ฌ ๋ฒ ๋ฐ๋ณตํด์ ์ธ ์ ์๊ฒ ํ๋ค.
@interface Work{
String value();
}
- ๋ฐ๋ณต ์ฌ์ฉ
@Work("์ฝ๋ ์
๋ฐ์ดํธ")
@Work("๋ฉ์๋ ์ค๋ฒ๋ผ์ด๋ฉ")
class Main{ }
- ์ฌ๋ฌ๋ฒ ์ ์ฉ ๊ฐ๋ฅ โ ํ๋๋ก ๋ฌถ์ด์ฃผ๋ ๋ณ๋ ์ ๋ํ ์ด์ ์์ฑ ํ์
@interface Works { // ์ฌ๋ฌ๊ฐ์ ToDo์ ๋ํ
์ด์
์ ๋ด์ ์ปจํ
์ด๋ ์ ๋ํ
์ด์
ToDos
Work[] value();
}
@Repeatable(Works.class) // ์ปจํ
์ด๋ ์ ๋ํ
์ด์
์ง์
@interface Work {
String value();
}
๐ค ์ฌ์ฉ์ ์ ์ ์ ๋ํ
์ด์
- ์ฌ์ฉ์ ์ง์ ์ ์ํด์ ์ฌ์ฉ
@interface ์ ๋ํ
์ด์
๋ช
{ // ์ธํฐํ์ด์ค ์์ @๊ธฐํธ๋ฅผ ๋ถ์ฌ ์ ์
ํ์
์์๋ช
(); // ์ ๋ํ
์ด์
์์ ์ ์ธ
}
- java.lang.annotation ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ๊ธฐ ๋๋ฌธ์ ๋ค๋ฅธ ํด๋์ค๋ ์ธํฐํ์ด์ค๋ฅผ ์์ ๋ฐ์ ์ ์์
โ Ref.
https://docs.oracle.com/javase/tutorial/java/annotations/index.html
Lesson: Annotations (The Javaโข Tutorials > Learning the Java Language)
The Java Tutorials have been written for JDK 8. Examples and practices described in this page don't take advantage of improvements introduced in later releases and might use technology no longer available. See Java Language Changes for a summary of updated
docs.oracle.com
๐ Lambda
๐ค ๋๋ค์
- ๋ฉ์๋๋ฅผ ํ๋์ ์์ผ๋ก ํํํ ๊ฒ โ ์ฝ๋ ๊ฐ๊ฒฐ, ๋ช ํ
- ํจ์ํ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ ์ง์
//๊ธฐ์กด ๋ฉ์๋ ํํ ๋ฐฉ์
void sayhello() {
System.out.println("HELLO!")
}
//์์ ์ฝ๋๋ฅผ ๋๋ค์์ผ๋ก ํํํ ์
() -> System.out.println("HELLO!")
- ํน์ง
- ๋ฐํํ์ ๊ณผ ์ด๋ฆ ์๋ต ๊ฐ๋ฅ โ ์ต๋ช ํจ์(anonymous function)
- ๋ฉ์๋ ๋ฐ๋์ ์คํ๋ฌธ์ด ํ๋๋ง ์กด์ฌํ ๊ฒฝ์ฐ ์ค๊ดํธ ์๋ต ๊ฐ๋ฅ
- ๋งค๊ฐ๋ณ์ ํ์ ์ ์ถ ๊ฐ๋ฅํ ๊ฒฝ์ฐ ๋งค๊ฐ๋ณ์ ํ์ ์๋ต ๊ฐ๋ฅ
- ์ต๋ช ๊ฐ์ฒด โ ์ ์ธ๊ณผ ๋์์ ์์ฑ
๐ค ํจ์ํ ์ธํฐํ์ด์ค
- ์๋ฐ์์ ํจ์๋ ๋ฐ๋์ ํด๋์ค ์์์ ์ ์ โ ๋ฉ์๋ ๋ ๋ฆฝ์ x
- ๋๋ค์ โ ๊ฐ์ฒด โ ์ด๋ฆ์ด ์๊ธฐ ๋๋ฌธ์ ์ต๋ช
ํด๋์ค
- ์ต๋ช
ํด๋์ค: ๊ฐ์ฒด์ ์ ์ธ๊ณผ ์์ฑ์ ๋์์ ํจ
โ ๋จ ํ๋์ ๊ฐ์ฒด๋ง ์์ฑํ๊ณ ๋จ ํ๋ฒ๋ง ์ฌ์ฉ๋๋ ์ผํ์ฉ ํด๋์ค
- ์ต๋ช
ํด๋์ค: ๊ฐ์ฒด์ ์ ์ธ๊ณผ ์์ฑ์ ๋์์ ํจ
public class LamdaEx {
public static void main(String[] args) {
/* Object obj = new Object() {
int sum(int num1, int num2) {
return num1 + num1;
}
};
*/
FunctionEx exFunction = (num1, num2) -> num1 + num2
System.out.println(exFunction.sum(10,15))
}
@FunctionalInterface // ์ธํฐํ์ด์ค๊ฐ ๋ฐ๋ฅด๊ฒ ์ ์๋์๋์ง ์ปดํ์ผ๋ฌ๊ฐ ํ์ธํ ์ ์๊ฒ ..
interface FunctionEx {
public abstract int sum(int num1, int num2);
}
- ๊ธฐ์กด ์ธํฐํ์ด์ค ๋ฌธ๋ฒ์ ํ์ฉํ์ฌ ๋๋ค์์ ๋ค๋ฃจ๋ ๊ฒ
- ๊ฐ๋ฅํ ์ด์ ? ๋๋ค์๋ ๊ฒฐ๊ตญ ํ๋์ ๊ฐ์ฒด์ด๊ธฐ ๋๋ฌธ โ ์ธํฐํ์ด์ค์ ์ ์๋ ์ถ์๋ฉ์๋ ๊ตฌํ ๊ฐ๋ฅ
- ๋๋ค์ : ์ธํฐํ์ด์ค ๋ฉ์๋ = 1 : 1
@FunctionalInterface
public interface FunctionalInterface {
public int accept(int x, int y);
}
import static java.lang.Integer.sum;
public class FunctionalInterfaceEx {
public static void main(String[] args) throws Exception {
FunctionalInterface ex;
ex = (x, y) -> {
int result = x + y;
return result;
};
ex = (x, y) -> { return x + y; };
ex = (x, y) -> x + y;
ex = (x, y) -> sum(x, y);
}
public static int sum(int x, int y){
return x + y;
}
}
/* ์ถ๋ ฅ: ๋ค 7*/
๐ค ๋ฉ์๋ ๋ ํผ๋ฐ์ค
- ๋๋ค์์์ ๋ถํ์ํ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๊ฑฐํ ๋ ์ฃผ๋ก ์ฌ์ฉ
โ ๋๋ค์์ผ๋ก ๊ฐ๋จํด์ง ์ต๋ช ๊ฐ์ฒด๋ฅผ ๋! ๊ฐ๋จํ๊ฒ! ์ฌ์ฉ
(left, right) -> Math.max(left, right);
// ์์ ๋ฉ์๋๋ฅผ ์ฐธ์กฐ ๋ฉ์๋๋ก ๋ณ๊ฒฝ
// ํด๋์ค์ด๋ฆ :: ๋ฉ์๋์ด๋ฆ
Math :: max
์ ์ ๋ฉ์๋์ ์ธ์คํด์ค ๋ฉ์๋ ์ฐธ์กฐ
- ์ ์ ๋ฉ์๋ ์ฐธ์กฐ
ํด๋์ค :: ์ ์ ๋ฉ์๋๋ช
- ์ธ์คํด์ค ๋ฉ์๋ ์ฐธ์กฐ
์ฐธ์กฐ๋ณ์ :: ์ธ์คํด์ค๋ฉ์๋๋ช
์์
// Calculator.java
public class Calculator {
public static int staticMethod(int x, int y) {
return x + y;
}
public int instanceMethod(int x, int y) {
return x * y;
}
}
import java.util.function.IntBinaryOperator;
public class MethodReferences {
public static void main(String[] args) {
IntBinaryOperator operator;
/* ์ ์ ๋ฉ์๋
* ํด๋์ค์ด๋ฆ :: ๋ฉ์๋์ด๋ฆ
*/
operator = Calculator::staticMethod;
System.out.println("์ ์ ๋ฉ์๋: " + operator.applyAsInt(3, 5));
/* ์ธ์คํด์ค๋ฉ์๋
* ์ธ์คํด์ค์ด๋ฆ :: ๋ฉ์๋์ด๋ฆ
*/
Calculator calculator = new Calculator();
operator = calculator::instanceMethod;
System.out.println("์ธ์คํด์ค๋ฉ์๋: " + operator.applyAsInt(3, 5));
}
}
์์ฑ์ ์ฐธ์กฐ
- ์์ฑ์ ์ฐธ์กฐ == ๊ฐ์ฒด์์ฑ
- ๊ฐ์ฒด ์์ฑ & ๋ฆฌํด ๋๋ค์ โ ์์ฑ์ ์ฐธ์กฐ๋ก ๋์น ๊ฐ๋ฅ
(a, b) -> { return new ํด๋์ค(a, b); };
- ์์ฑ์ ์ฐธ์กฐ๋ก ํํ
ํด๋์ค :: new
โ Ref.
- ํจ์ํ ์ธํฐํ์ด์ค ์คํ ํ์ธ
https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html
java.util.function (Java Platform SE 8 )
Interface Summary Interface Description BiConsumer Represents an operation that accepts two input arguments and returns no result. BiFunction Represents a function that accepts two arguments and produces a result. BinaryOperator Represents an operation u
docs.oracle.com
https://codechacha.com/ko/java8-functional-interface/
Java8 - ํจ์ํ ์ธํฐํ์ด์ค(Functional Interface) ์ดํดํ๊ธฐ
ํจ์ํ ์ธํฐํ์ด์ค๋ 1๊ฐ์ ์ถ์ ๋ฉ์๋๋ฅผ ๊ฐ๊ณ ์๋ ์ธํฐํ์ด์ค๋ฅผ ๋งํฉ๋๋ค. Single Abstract Method(SAM)๋ผ๊ณ ๋ถ๋ฆฌ๊ธฐ๋ ํฉ๋๋ค. ํจ์ํ ์ธํฐํ์ด์ค๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ ์๋ฐ์ ๋๋ค์์ ํจ์ํ ์ธํฐํ
codechacha.com
๐ Stream
๐ค Stream ํน์ง
- ์คํธ๋ฆผ: ๋ฐ์ดํฐ๋ฅผ ์ฐ์์ ์ผ๋ก ์ ๋ฌํ๋ ํต๋ก
- ๋ฐฐ์ด, ์ปฌ๋ ์ ์ ์ ์ฅ์์๋ฅผ ํ๋์ฉ ์ฐธ์กฐํด์ ๋๋ค์์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋๋ก ํด์ฃผ๋ ๋ฐ๋ณต์
- ๋ค์ํ ๋ฐ์ดํฐ ์์ค(List, Set, Map, ๋ฐฐ์ด ๋ฑ)๋ก๋ถํฐ ์คํธ๋ฆผ์ ๋ง๋ค๊ณ , ํ์คํ๋ ๋ฐฉ๋ฒ์ผ๋ก ๋ค๋ฃฐ ์ ์์
์ ์ธํ์ผ๋ก ๋ฐ์ดํฐ ์์ค ์ฒ๋ฆฌ
- โ๋ฌด์"์ ์ํํ๋์ง๊ฐ ์ค์
- ๋ด๋ถ ๋์ ์๋ฆฌ๋ฅผ ๋ชฐ๋ผ๋ ์ฝ๋๊ฐ ๋ฌด์จ ์ผ์ ํ๋์ง ์ดํด ๊ฐ๋ฅ
์์
- List์ ์๋ ์ซ์๋ค ์ค 4๋ณด๋ค ํฐ ์ง์ ํฉ๊ณ ๊ตฌํ๊ธฐ
import java.util.List;
public class ImperativeProgrammingEx{
public static void main(String[] args){
List<Integer> numbers = List.of(1, 3, 6, 7, 8, 11);
// ๋ช
๋ นํ ํ๋ก๊ทธ๋๋ฐ
int sum = 0;
for(int number : numbers) {
if(number > 4 && (number % 2 == 0)) {
sum += number;
}
}
// ์ ์ธํ ํ๋ก๊ทธ๋๋ฐ - ์คํธ๋ฆผ
int sum = numbers.stream()
.filter(number -> number > 4 && (number % 2 == 0))
.mapToInt(number -> number)
.sum();
}
}
๋๋ค์์ผ๋ก ์์ ์ฒ๋ฆฌ ์ฝ๋ ์ ๊ณต
- ์คํธ๋ฆผ์ด ์ ๊ณตํ๋ ๋๋ถ๋ถ์ ์์ ์ฒ๋ฆฌ ๋ฉ์๋ โ ํจ์ํ ์ธํฐํ์ด์ค ๋งค๊ฐํ์ ์ ๊ฐ์ง
- โ ๋๋ค์ ๋๋ ๋ฉ์๋ ์ฐธ์กฐ๋ฅผ ์ด์ฉํด์ ์์ ์ฒ๋ฆฌ ๋ด์ฉ์ ๋งค๊ฐ๊ฐ์ผ๋ก ์ ๋ฌํ ์ ์์
stream.forEach(s -> {
String name = s.getName();
int score = s.getScore();
System.out.println(name + ": " + score);
});
๋ด๋ถ ๋ฐ๋ณต์์ ์ฌ์ฉ์ผ๋ก ๋ณ๋ ฌ ์ฒ๋ฆฌ์ ์ฉ์ด
- ์ธ๋ถ๋ฐ๋ณต์(external iterator)
- ๊ฐ๋ฐ์๊ฐ ์ฝ๋๋ก ์ง์ ์ปฌ๋ ์ ์ ์์๋ฅผ ๋ฐ๋ณตํด์ ๊ฐ์ ธ์ค๋ ์ฝ๋ ํจํด
- index๋ฅผ ์ฌ์ฉํ๋ for๋ฌธ, iterator๋ฅผ ์ด์ฉํ๋ while๋ฌธ
- ๋ด๋ถ๋ฐ๋ณต์(internal iterator)
- ์ปฌ๋ ์ ๋ด๋ถ: ์์ ๋ฐ๋ณต / ๊ฐ๋ฐ์: ์์ ๋น ์ฒ๋ฆฌํด์ผ ํ ์ฝ๋๋ง ์ ๊ณตํ๋ ์ฝ๋ ํจํด
- ์ด์
- ์์ ๋ฐ๋ณต์ ์ปฌ๋ ์ ์๊ฒ, ๊ฐ๋ฐ์๋ ์์ ์ฒ๋ฆฌ ์ฝ๋์ ์ง์ค
- ์์ ๋ฐ๋ณต ์์ ๋ณ๊ฒฝ, ๋ฉํฐ์ฝ์ด CPU ์ต๋ํ ํ์ฉ
โ ์์๋ค์ ๋ถ๋ฐฐ์์ผ ๋ณ๋ ฌ ์์ ์ ๋์์ฃผ๋ฏ๋ก ํจ์จ์ ์ธ ์์ ๋ฐ๋ณต ๊ฐ๋ฅ- ๋ณ๋ ฌ ์คํธ๋ฆผ ์ฌ์ฉ: ์คํธ๋ฆผ parallel() ๋ฉ์๋ ์ฌ์ฉ

์ค๊ฐ ์ฐ์ฐ๊ณผ ์ต์ข ์ฐ์ฐ
- ์คํธ๋ฆผ์ ์ปฌ๋ ์
์ ์์์ ๋ํด ์ค๊ฐ ์ฐ์ฐ๊ณผ ์ต์ข
์ฐ์ฐ์ ์ํํ ์ ์์
- ์ค๊ฐ ์ฐ์ฐ: ๋งคํ, ํํฐ๋ง, ์ ๋ ฌ ๋ฑ์ ์ํ
- ์ต์ข ์ฐ์ฐ: ๋ฐ๋ณต, ์นด์ดํ , ํ๊ท , ์ดํฉ ๋ฑ์ ์ง๊ณ ์ํ
- ์๋ฅผ ๋ค์ด ํ์ ๊ฐ์ฒด๋ฅผ ์์๋ก ๊ฐ์ง๋ ์ปฌ๋ ์
์ด ์๋ค๊ณ ๊ฐ์ ํ ๋,
- ์ค๊ฐ ์ฐ์ฐ: ํ์์ ์ ์๋ฅผ ์ถ๋ ฅ
- ์ต์ข ์ฐ์ฐ: ์ ์์ ํ๊ท ๊ฐ์ ์ฐ์ถ
๐ค ํ์ดํ๋ผ์ธ
- ๋ฆฌ๋์
(Reduction): ๋๋์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ๊ณตํด ์ถ์ํ๋ ๊ฒ
- ๊ฒฐ๊ณผ๋ฌผ: ๋ฐ์ดํฐ์ ํฉ๊ณ, ํ๊ท ๊ฐ, ์นด์ดํ , ์ต๋๊ฐ, ์ต์๊ฐ ๋ฑ
ํ์ดํ๋ผ์ธ
- ๊ตฌ์กฐ: ์ฌ๋ฌ๊ฐ์ ์คํธ๋ฆผ์ด ์ฐ๊ฒฐ
- ๋ชจ๋ ์ค๊ฐ ์ฐ์ฐ ์คํธ๋ฆผ(์ต์ข ์ฐ์ฐ ์ ์ธ)

๐ค ์คํธ๋ฆผ ์์ฑ, ์ค๊ฐ ์ฐ์ฐ, ์ต์ข
์ฐ์ฐ
์คํธ๋ฆผ ์์ฑ
- stream(): Collection ์ธํฐํ์ด์ค์ ์ ์
โ Collection ์ธํฐํ์ด์ค ๊ตฌํ ๊ฐ์ฒด(List, Set ๋ฑ)๋ค์ ๋ชจ๋ ์ด ๋ฉ์๋๋ก ์คํธ๋ฆผ ์์ฑ ๊ฐ๋ฅ - stream() ์ฌ์ฉ โ ํด๋น Collection์ ๊ฐ์ฒด ์์ค๋ก ํ๋ Stream ๋ฐํ
- ์คํธ๋ฆผ ์ฌ์ฉ ์ ์ฃผ์์
- Read-only
- Disposable
์ค๊ฐ ์ฐ์ฐ
- ์ค๊ฐ ์ฐ์ฐ์ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ์คํธ๋ฆผ์ผ๋ก ๋ฐํํ๊ธฐ ๋๋ฌธ์ ์ฐ์ํด์ ์ฌ๋ฌ ๋ฒ ์ํ ๊ฐ๋ฅ
ํํฐ๋ง - filter(), distinct()
- filter(): ์คํธ๋ฆผ ์กฐ๊ฑด์ ๋ง๋ ๋ฐ์ดํฐ๋ง ํํฐ๋ง
- distinct(): ์คํธ๋ฆผ ์์ ์ค๋ณต ์ ๊ฑฐ
๋งคํ - map()
- map(): ๊ธฐ์กด Stream ์์ โ ์๋ก์ด Stream ๋์ฒด
โ ์คํธ๋ฆผ์ ์คํธ๋ฆผ ๋ฐํ - flatMap(): ์์๋ฅผ ๋์ฒดํ๋ ๋ณต์ ๊ฐ์ ์์๋ค๋ก ๊ตฌ์ฑ๋ ์๋ก์ด ์คํธ๋ฆผ ๋ฆฌํด
โ ์คํธ๋ฆผ ๋ฐํ
์ ๋ ฌ - sorted()
- Stream ์์ ์ ๋ ฌ
- ํ๋ผ๋ฏธํฐ๋ก Comparator ๋๊ธฐ๊ธฐ ๊ฐ๋ฅ
- ์ค๋ฆ์ฐจ์: Comparator ์ธ์ ์์ด ํธ์ถ
- ๋ด๋ฆผ์ฐจ์: reverseOrder ์ฌ์ฉ
list.stream()
.sorted() // ์ค๋ฆ์ฐจ์
.forEach(n -> System.out.println(n));
System.out.println();
list.stream()
.sorted(Comparator.reverseOrder()) // ๋ด๋ฆผ์ฐจ์
.forEach(n -> System.out.println(n));
์ฐ์ฐ ๊ฒฐ๊ณผ ํ์ธ - peek()
- ์ฐ์ฐ ์ค๊ฐ์ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํ์ฌ ๋๋ฒ๊น ํ๋ ค๊ณ ํ ๋ ์ฌ์ฉ
intStream
.filter(a -> a%2 ==0)
.peek(n-> System.out.println(n))
.sum();
์ต์ข ์ฐ์ฐ
์ฐ์ฐ ๊ฒฐ๊ณผ ํ์ธ - forEach()
- ํ์ดํ๋ผ์ธ ๋ง์ง๋ง์์ ์์๋ฅผ ํ๋์ฉ ์ฐ์ฐ
intStream
.filter(a -> a%2 ==0)
.forEach(n -> System.out.println(n));
๋งค์นญ - match()
- Stream ์์๋ค์ด ํน์ ํ ์กฐ๊ฑด์ ์ถฉ์กฑํ๋์ง ๊ฒ์ฌ
- ํจ์ํ ์ธํฐํ์ด์ค Predicate๋ก ํด๋น ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ๊ฒ์ฌ โ boolean ๋ฐํ
- ์ข
๋ฅ
- allMatch(): ๋ชจ๋ ์์๋ค์ด ๋งค๊ฐ๊ฐ์ผ๋ก ์ฃผ์ด์ง Predicate ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ๊ฒ์ฌ
- anyMatch(): ์ต์ํ ํ ๊ฐ์ ์์๊ฐ ๋งค๊ฐ๊ฐ์ผ๋ก ์ฃผ์ด์ง Predicate ์กฐ๊ฑด์ ๋ง์กฑํ๋์ง ๊ฒ์ฌ
- noneMatch(): ๋ชจ๋ ์์๋ค์ด ๋งค๊ฐ๊ฐ์ผ๋ก ์ฃผ์ด์ง Predicate์ ์กฐ๊ฑด์ ๋ง์กฑํ์ง ์๋์ง ๊ฒ์ฌ
int[] intArr = {2,4,6};
boolean result = Arrays.stream(intArr).allMatch(a -> a % 2 == 0);
System.out.println("๋ชจ๋ 2์ ๋ฐฐ์์ธ๊ฐ? " + result); // true
result = Arrays.stream(intArr).anyMatch(a -> a % 3 == 0);
System.out.println("ํ๋๋ผ๋ 3์ ๋ฐฐ์๊ฐ ์๋๊ฐ? " + result); // true
result = Arrays.stream(intArr).noneMatch(a -> a % 3 == 0);
System.out.println("3์ ๋ฐฐ์๊ฐ ์๋๊ฐ? " + result); // false
๊ธฐ๋ณธ ์ง๊ณ - sum(), count(), average(), max(), min()
- ์์๋ค์ ์ฐ์ฐํ์ฌ ํ๋์ ๊ฐ์ผ๋ก ์ฐ์ถํ๋ ๊ฒ
int[] intArr = {1,2,3,4,5};
long count = Arrays.stream(intArr).count();
System.out.println("intArr์ ์ ์ฒด ์์ ๊ฐ์: " + count);
long sum = Arrays.stream(intArr).sum();
System.out.println("intArr์ ์ ์ฒด ์์ ํฉ: " + sum);
double avg = Arrays.stream(intArr).average().getAsDouble();
System.out.println("์ ์ฒด ์์์ ํ๊ท ๊ฐ: " + avg);
int max = Arrays.stream(intArr).max().getAsInt();
System.out.println("์ต๋๊ฐ: " + max);
int min = Arrays.stream(intArr).min().getAsInt();
System.out.println("์ต์๊ฐ: " + min);
int first = Arrays.stream(intArr).findFirst().getAsInt();
System.out.println("๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์์: " + first);
๋ค์ํ ์ง๊ณ ๊ฒฐ๊ณผ๋ฌผ - reduce()
- ๋์ ํ์ฌ ํ๋๋ก ์์ถ(reduce)ํ๋ ๋ฐฉ์
- ์์ ๋ ์์์ ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ ๋ฐํ์ผ๋ก ๋ค์ ์์์ ์ฐ์ฐ
- Accumulator: ๊ฐ ์์๋ฅผ ๊ณ์ฐํ ์ค๊ฐ ๊ฒฐ๊ณผ๋ฅผ ์์ฑํ๊ธฐ ์ํด ์ฌ์ฉ
- Identity: ๊ณ์ฐ์ ์ํํ๊ธฐ ์ํ ์ด๊ธฐ๊ฐ
- Combiner: ๋ณ๋ ฌ ์คํธ๋ฆผ(Parlallel Stream)์์ ๋๋์ด ๊ณ์ฐ๋ ๊ฒฐ๊ณผ๋ฅผ ํ๋๋ก ํฉ์นจ
int[] intArr = {1,2,3,4,5};
long sum = Arrays.stream(intArr).sum();
System.out.println("intArr์ ์ ์ฒด ์์ ํฉ: " + sum);
int sum1 = Arrays.stream(intArr)
.map(el -> el*2)
.reduce((a,b) -> a+b)
.getAsInt();
System.out.println("์ด๊ธฐ๊ฐ ์๋ reduce: " + sum1);
int sum2= Arrays.stream(intArr)
.map(el -> el*2)
.reduce(0, (a,b) -> a+b);
System.out.println("์ด๊ธฐ๊ฐ ์กด์ฌํ๋ reduce: " + sum2)
Stream์์ ๋ค๋ฅธ ์ข ๋ฅ๋ก ์์ง - collect()
- Stream์ ์์๋ค์ ๋ค๋ฅธ ์ข ๋ฅ(List, Set, Map ๋ฑ)์ ๊ฒฐ๊ณผ๋ก ์์ง
- ์ผ๋ฐ์ ์ผ๋ก List๋ก Stream์ ์์๋ค์ ๋ง์ด ์์ง
โ ์์ฃผ ์ฌ์ฉํ๋ ์์ ์ Collectors ๊ฐ์ฒด์์ static ๋ฉ์๋๋ก ์ ๊ณต
โ ์ํ๋ ๊ฒ์ด ์์ผ๋ฉด Collector ์ธํฐํ์ด์ค๋ฅผ ์ง์ ๊ตฌํํ์ฌ ์ฌ์ฉ
๐ค Optional<T>
- NullPointerException(NPE)์์ null ๊ฐ์ผ๋ก ์ธํด ์๋ฌ๊ฐ ๋ฐ์ํ๋ ํ์์ ๊ฐ์ฒด ์ฐจ์์์ ํจ์จ์ ์ผ๋ก ๋ฐฉ์งํ๊ณ ์ ๋์
- ์ฐ์ฐ ๊ฒฐ๊ณผ๋ฅผ Optional์ ๋ด์์ ๋ฐํํ๋ฉด, ๋ฐ๋ก ์กฐ๊ฑด๋ฌธ์ ์์ฑํ์ง ์์๋ NPE๊ฐ ๋ฐ์ํ์ง ์๋๋ก ์ฝ๋์์ฑ ๊ฐ๋ฅ
Optional ๊ฐ์ฒด ์์ฑ
- of() ์ฌ์ฉ
- ์ฐธ์กฐ๋ณ์์ ๊ฐ์ด null์ผ ๊ฐ๋ฅ์ฑ์ด ์๋ค๋ฉด ofNullable() ์ฌ์ฉ
Optional<String> opt1 = Optional.ofNullable(null);
Optional<String> opt2 = Optional.ofNullable("123");
Optional<String> opt3 = Optional.<String>empty(); // ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ด๊ธฐํ
๋ฉ์๋ ์ฒด์ด๋
- ์ฌ๋ฌ ๋ฉ์๋๋ฅผ ์ฐ๊ฒฐํด์ ์์ฑ
โ Ref.
- Optional ๊ฐ์ฒด์์ ์ ๊ณตํ๋ ์ ์ฒด ๋ฉ์๋
https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
Optional (Java Platform SE 8 )
A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value. Additional methods that depend on the presence or absence of a contained value are provided, such as orEl
docs.oracle.com
๐ ์ค๋์ ์๊ฐ ์กฐ๊ฐ๋ชจ์
- ๋ฉ์๋ ๋ ํผ๋ฐ์ค๋ ๋๋ค์์ผ๋ก ๊ฐ๋จํด์ง ์ต๋ช ๊ฐ์ฒด๋ฅผ ๋ ๊ฐ๋จํ๊ฒ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค. ๊ฐ๋จํด์ง ์ต๋ช ๊ฐ์ฒด๋ฅผ ๋! ๊ฐ๋จ!ํ๊ฒ!! ์ธ๊ฐ์ ์์ฌ์ ๋์ด ์๊ณ โฆ ๋๋ ๋ฌด์จ๋ง์ธ์ง ๋ชจ๋ฅด๊ฒ ๊ณ โฆ ๐ตโ๐ซ
- I/O๋ ๋ด์ผ ... ใ .ใ
'SEB > TIL' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
023 | Data Structure - Stack & Queue (0) | 2022.07.25 |
---|---|
019 | Java - I/O, Thread, JVM (0) | 2022.07.19 |
017 | Java - ๐ฅ Practical | Collection Framework (0) | 2022.07.16 |
016 | Java - Generics, Collection Framework (2) | 2022.07.15 |
015 | Java (0) | 2022.07.13 |