java.lang패키지3 : String 클래스, StringBuffer와 StringBuilder 클래스의 메서드

람다식을 이용한 함수형 프로그래밍2 : 메서드

표준 함수형 인터페이스 메서드

  • java.util.function패키지의 인터페이스들은 모두 하나 이상의 default 또는 static 메서드를 포함하고 있는데 이들 메서드를 이용해서 동일한 계열의 여러 동작을 연결해서 사용할 수 있다.
Read More

[ITWILL : JAVA] 람다식을 이용한 함수형 프로그래밍1 : 계열

ITWILL학원 : 22강 JAVA BY 윤미영강사

  • 자바 8에서는 빈번히 사용되는 함수형 인터페이스들을 java.util.function패키지를 통해 제공한다.

https://altongmon.tistory.com/245

https://brunch.co.kr/@oemilk/205

1. Consumer 계열

  • 소비자계열은 무엇을 소비할까? 바로 파라미터이다.
  • 전달받은 파라미터를 받아서 소비하는 소비자이며 리턴값은 없다
  • Consumer 계열의 인터페이스 :
    • biConsumer는 bi가 두 개라는 의미로 두 개의 파라미터를 받는다.
    • 객체를 처리하지않고 기본형을 처리하는 경우 double, long, int 값을 처리할 수 있다.
      https://altongmon.tistory.com/245

2. Supplier 계열

  • 공급자계열은 무엇을 공급할까? 바로 리턴값이다.
  • 파라미터를 받지 않고 자체적으로 리턴할 값을 생성한다
  • 파라미터가 없기때문에 bi가 붙는 형태는 없다.
인터페이스명 메서드 설명
Supplier T get() T타입 객체 리턴
pSupplier p getAsp() p타입의 값 리턴
참고 p는 boolean, int, long, double를 의미한다

3. Function 계열

  • 파라미터도 받고, 리턴도 존재한다.

https://altongmon.tistory.com/245

4. Operator 계열

  • function계열과 유사하게 파라미터와 리턴 타입을 모두 갖는다.
  • 차이점 :
    • function계열 : 파라미터와 리턴 타입이 무관
    • operator계열 : 파라미터를 이용해 어떤 연산을 수행한 후 파라미터와 같은 타입이 리턴된다.

https://altongmon.tistory.com/246

5. Predicate 계열

  • 파라미터와 리턴타입을 갖는데 리턴타입이 boolean으로 고정.

https://altongmon.tistory.com/246

[ITWILL : JAVA]람다식개념, 인터페이스 Comparator

ITWILL학원 : 21강 JAVA BY 윤미영강사

1. 람다식

  • 자바 8에서 추가된 가장 큰 특징으로 함수형 프로그래밍 형태를 받아들인 결과
  • 메서드 vs 함수
    • 객체지향 프로그래밍개념에서 : 메서드와 함수는 동일하다
    • 함수형 프로그래밍개념에서 : 메서드(특정객체가 수행하는 기능) vs 함수(특정 객체에 속하지않는 기능)
  • 람다식을 쓰는 이유 : 코드가 간결해짐.
  • 람다식 사용가능한 곳 :
    • 함수형 인터페이스 중 익명클래스를 사용한 부분만 람다식으로 대체해서 사용가능.
    • 함수형 인터페이스가 뭘까?
    • 함수형 인터페이스 : 인터페이스 중에서 한 개의 abstract메서드를 가진 인터페이스
  • 사용법 :
1
2
3
4
5
6
7
8
9
10
11
12
13
//기본 람다식
(파라미터타입) -> {실행문;}

//예시 : 매개변수없음 + 리턴없는 경우
() -> System.out.println("Hi");

//예시 : 매개변수있음 + 리턴없는 경우
(msg) -> System.out.println(msg);

//예시 : 매개변수있음 + 리턴있는 경우
(msg) -> { System.out.println(msg);
return msg;
}
  • 이클립스 단축키 : new연산자의 대괄호{} 전체 선택 후 ctrl + 1 -> convert to lambda expression 를 선택하면 자동으로 람다식을 생성해준다.

2. 인터페이스 Comparator

  • 객체정렬방식 2가지

    • Comparable 인터페이스 : 정렬 대상 클래스를 자바에서 기본적으로 제공하고 있는 Comparable 인터페이스를 구현하도록 변경
    • 만약 이미 존재하고 있는 정렬 기준과 다른 정렬 기준으로 정렬을 하고 싶을 때는 어떻게 해야할까?
    • Comparator 인터페이스 : 정렬 기준을 누락된 클래스의 객체나 기존 정렬 기준을 무시하고 새로운 정렬 기준으로 객체를 정렬가능.
  • 데이터타입별 비교방법

    • int 데이터타입은 부등호로 서로 비교가능
    • String은 부등호로 비교가 안됨 => compareTo()메서드사용해서 비교해야함
  • int compare(T o1, T o2) : Compares its two arguments for order. Returns a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second.

    • 리턴값이 -1이면 위치가 앞으로 , 0이면 가만히, 1이면 뒤로
    • o1 > o2 : negative integer
    • o1 = o2 : zero
    • o1 < o2 : positive integer
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83

public class Person {
//1. 멤버변수생성
String name;
int age;

//3. 생성자만들기
public Person(int age, String name) {
this.age = age;
this.name = name;
}

//2. getter와 setter만들기
public String getName() {
return name;
}

(생략)

//5. toString생성
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}

public static void main(String[] args) {

//4. 배열만들기
Person[] people = new Person[3];
people[0] = new Person(22, "홍");
people[1] = new Person(20, "길");
people[2] = new Person(24, "동");

//4-1. 배열출력하기 - toString사용
System.out.println("배열의 인덱스출력 : "+people[0]);
System.out.println("toString이용 배열출력(입력순) : "+Arrays.toString(people));

//6. sort하기 :
//Arrays.sort(people); //에러발생
//왜 에러날까? sort하기위해서는 정렬의 기준이 필요하다. 멤버변수 두개중에 어떤걸 기준잡을지 말해야한다 = Comparator
//7-2. comparator이용해서 나이순으로 sort하기
Arrays.sort(people, new Comp());
System.out.println("sort+외부클래스사용 배열출력(나이오름차순) : "+Arrays.toString(people));
//7-3. 익명클래스를 사용해서 나이순으로 sort하기
Arrays.sort(people, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if(o1.age > o2.age) return -1;
else return 1;
}
});
System.out.println("sort+내부클래스사용+age(나이내림차순) 배열출력 : "+Arrays.toString(people));

//7-4. 이름순으로 정렬하기
//String은 부등호로 비교가 안됨 => compareTo()메서드사용해서 비교해야함
Arrays.sort(people, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if(o1.name.compareTo(o2.name) > 0) return 1; //가나다순
else return -1;
}
});

System.out.println("sort+내부클래스사용+name 배열출력(가나다순) : "+Arrays.toString(people));

}//main매서드닫음


}//Person클래스닫음


//7. comparaor생성(내부클래스말고 독립적인 클래스로 생성)
class Comp implements Comparator<Person>{
//7-1. 추상메서드 오버라이딩
@Override
public int compare(Person arg0, Person arg1) {
if(arg0.age < arg1.age){
return -1; //오름차순(arg0보다 arg1이 더 큰 경우)
}else{
return 1;
}
}
}//Comp클래스닫음
  • Comparator 객체는 메서드가 하나 뿐인 함수형 인터페이스를 구현하기 때문에 람다 함수로 대체가 가능.
  • 기존에 있던 new Comparator<Person>() { @Override public int compare를 화살표로 대체해주면 람다식완성.
  • 데이터 타입도 지울 수 있다 : (Person o1, Person o2) -> (o1, o2)로 가능.
1
2
3
4
5
6
7
//7-4. 이름순으로 정렬하기(람다식 사용)
Arrays.sort(people, (o1, o2) ->
if(o1.name.compareTo(o2.name) > 0) return 1; //가나다순
else return -1;
}
);
System.out.println(Arrays.toString(people));

참고링크 : Comparable과 Comparator
참고링크 : 객체 정렬하기 1부 - Comparable vs Comparator

[ITWILL : JAVA]로깅, 디버깅

ITWILL학원 : 20강 JAVA BY 윤미영강사

1. 로깅(Logging)

  • 로깅 : 사용자의 요청사항을 출력하는 것 이외에 애플리케이션에서 발생하는 사건들을 기록하는 것.

참고링크 : java.util.Logging.Logger의 메서드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class SimpleLoggingFile {

private final static Logger logger = Logger.getLogger(SimpleLoggingFile.class.getName());

public static void main(String[] args) throws SecurityException, IOException {
FileHandler fHandler = new FileHandler("mylog_%g.log");
logger.addHandler(fHandler);
logger.log(Level.INFO, "INTO LOG");
logger.info("메서드 타입 인포 로그");
logger.warning("메서드 타입 경고 로그");
logger.severe("메서드 타입 시비어 로그");
}

}

//출력값
723, 2020 11:11:40 오전 ch9.SimpleLoggingFile main
정보: INTO LOG
723, 2020 11:11:40 오전 ch9.SimpleLoggingFile main
정보: 메서드 타입 인포 로그
723, 2020 11:11:40 오전 ch9.SimpleLoggingFile main
경고: 메서드 타입 경고 로그
723, 2020 11:11:40 오전 ch9.SimpleLoggingFile main
심각: 메서드 타입 시비어 로그
  • 더불어 mylog_0.log파일이 생성되었다.

  • 출력된 로그는 콘솔과 함께 파일에도 기록된다.

  • 실무에서는 logging패키지의 클래스보다 주로 logback과 같은 별도의 로깅 프레임워크들을 사용함.

2. 디버깅

  • 리커시브방법 : 함수가 자기 자신을 계속 호출하는 구조 = 재귀함수

  • break point : 프로그램 동작 중 디버깅을 위해서 동작을 멈추는 지점

    • 중단점을 지정해 놓으면 그 전까지 프로그램이 동작하다가 브레이크포인트에서 사용자의 다음동작을 기다린다.
    • step into를 하면 변수뷰창에서 valables가 어떻게 변화하는지 알수있다.

[ITWILL : JAVA]내부클래스

ITWILL학원 : 20강 JAVA BY 윤미영강사

1. 내부클래스(p363)

  • 클래스가 서로 밀접한 관련이 있을때 객체생성없이 사용하기 용이하다
  • 주로 이미 만들어진 내부클래스라이브러리를 사용.
  • 공통점 : static 변수는 가질 수 없지만, final static 변수는 가질 수 있다.
    • 만약 상수가 아닌 변수형태로 선언이 되어있다면 그건 앞에 final이 생략되어진 것임.
    • 변수를 사용하고싶다면 차라리 외부클래스의 멤버변수로 선언하는 것이 낫다.
  • 내부클래스의 종류 4가지 :

https://github.com/burberry-check/java-basic/wiki/%EC%B6%94%EC%83%81%ED%81%B4%EB%9E%98%EC%8A%A4,-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4

2. 인스턴스 내부클래스

  • 내부클래스를 외부클래스의 멤버변수 선언위치에 선언하는 것.

  • 인스턴스내부클래스는 외부클래스의 멤버변수를 자신의 멤버변수처럼 불러와서 쓸 수 있다.

  • 단독으로 사용하기도한다.

  • 내부클래스의 메서드 사용하는 방법 :

    1. 외부클래스 객체생성 : 외부클래스명 A = new 외부클래스명();
    2. 내부클래스 객체생성 : 내부클래스명 B = A.new 내부클래스명();
    3. 내부클래스의 메서드 사용 : B.method();
    • 이러한 것을 단독사용이라고 한다.
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
public class InstanceInner {
private int outerMember = 1;

private void outerMethod(){
Inner inner = new Inner();
inner.innnerMember = 11;
inner.innerMethod();
}

class Inner{
int innnerMember = 10;
//static int staticMember = 10; staitc멤버변수 선언 불가. 만약 상수가 아닌 변수형태로 선언이 되어있다면 그건 앞에 static이 생략되어진 것임.
static final int finalStaticMember = 20; //단 static final형태는 선언할 수 있다.

private void innerMethod(){
System.out.printf("out : %d, inner %d%n", outerMember, innnerMember);
}
}

//내부클래스 메서드 사용은 어떻게 할까?
public static void main(String[] args) {
InstanceInner ilt = new InstanceInner(); //1.외부클래스객체생성
Inner inner = ilt.new Inner(); //2.내부클래스객채생성
inner.innerMethod(); //3.내부클래스의 메서드사용

}
}

3. 지역클래스(local class)

  • 내부클래스가 외부클래스의 메서드안에서 정의되어지는 것.
  • 지역클래스는 단독으로 사용하지않고 내부에서 객체생성 후 호출해서 사용.
    • 단독사용의 의미 : 직접 메서드를 불러와서사용,
    • 지역클래스인 경우 메서드를 호출하는 순간 객채생성하고 바로 사용할 수 있게해야한다. 즉 단독사용처럼 직접 클래스이름을 불러 사용하는 것이 아니라 지역클래스가 속한 외부클래스메서드를 부르면서 그 속에 있는 클래스가 자동으로 사용되게끔 하는 것이다.
1
2
3
4
5
6
7
8
9
10
class OuterClass(){
...
public methodA(){ //멤버메서드
class InnerClass(){ //로컬클래스
...
}
}
}

//객체생성 후 호출해서 주로 사용

4. 익명클래스(p373)

  • 인터페이스를 구현할 목적으로 사용.
  • 실무에서 자주 사용.
  • 익명클래스의 override는 인터페이스 규칙에 의해 public을 붙여줘야한다
  • 익명클래스를 어떨때 사용할까?
    • 독립적인 클래스 사용 : 인터페이스를 구현한 클래스를 여러번 사용할때 용이.Intf a는 언제어디서나 불러서 사용가능
    • 익명클래스 사용 : 인터페이스를 구현한 클래스를 딱 한번 사용할때 용이. 익명클래스는 Intf b에서만 사용가능. 이름이 없기때문에 불러서 사용할 수 없다.
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
interface Intf{
void methodInf();
}

class A implements Intf{
@Override
public void methodInf() {
System.out.println("인터페이스 메서드 오버라이딩");
}
}

public class test {

public static void main(String[] args){

//기본적인 interface구현(독립적인 클래스사용)
Intf a = new A();
a.methodInf();

//익명클래스를 이용한 interface구현
Intf b = new Intf(){
@Override
public void methodInf() {
System.out.println("익명클래스로 인터페이스 메서드 오버라이딩");
}
};
b.methodInf();
}
}

5. 내부클래스 예시

다양한 내부클래스를 생성한 뒤 main메서드로 호출해보자

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
interface InfoPrintable{
public void printInfo();
}

public class VariousInnerClassTest {

//멤버메서드(매개변수가 인터페이스)
public void useInnerClass(InfoPrintable inner){
inner.printInfo();
}

//멤버메서드
public void useSpeakerTest(){

//로컬 내부클래스생성(메서드안에 선언한 내부클래스=로컬클래스)
class EngSpeaker implements InfoPrintable{
@Override
public void printInfo() {
System.out.println("로컬 내부 클래스");
}
}//EngSpeaker닫음

//멤버메서드사용하여 클래스 부르기
//1. 익명의 내부클래스 생성
useInnerClass(new InfoPrintable(){
@Override
public void printInfo() {
System.out.println("익명의 내부클래스");
}
});

//2. 로컬내부클래스부르기
useInnerClass(new EngSpeaker());

//3. 인스턴스내부클래스부르기
useInnerClass(new InstanceInnerClass());

//4. 걍 밖에있는클래스
useInnerClass(new SomeClass());

}//useSpeakerTest메서드닫음

//인스턴스 내부클래스(외부클래스의 멤버에 생성)
class InstanceInnerClass implements InfoPrintable{
@Override
public void printInfo() {
System.out.println("인스턴스 내부클래스 사용");
}

}//InstanceInnerClass닫음


//만든 내부클래스를 main메서드로 호출해보자
public static void main(String[] args){

VariousInnerClassTest vt = new VariousInnerClassTest();
vt.useSpeakerTest();

}

}//VariousInnerClassTest닫음

//걍 다른 클래스인데 인터페이스구현
class SomeClass implements InfoPrintable{

@Override
public void printInfo() {
System.out.println("걍 상관없는 일반 클래스");
}

}

[JAVA]예외처리기법3가지 및 Error와 Exception 차이

1. 오류 Error

  • 발생하면 복구하거나 되돌릴 수 없는 심각한 상황.
  • 발생상황 예시 : 메모리부족, 메서드끼리 호출을 무한반복등등.
  • 처리방법 : 오류를 발생하는 요인을 찾아서 업애는 디버깅.
  • 예방법 : 코드 짜임새있게 짜기.
    즉, 프로그램을 잘 짜는 것만이 대안이기때문에 예외처리와 무관하다.

2. 예외 Exception

  • 오류와 비교하면 심각도가 낮으며 프로그램의 정상적인 흐름을 방해하는 상황.
  • 발생상황 예시 : 네트워크 연결 끊기는 상황, 해당 파일을 읽지 못하는 상황등등.
  • 예외처리란 : 예외가 발생했을때 비정상적인 종료를 막고 계속해서 사용할 수 있도록 처리하는 것
  • 예외처리 라이브러리 = 최상위 클래스 = Throwable

https://deftkang.tistory.com/44

  • RuntiomeException = unchecked Exception : 중간에 throws 할 필요없다
  • 그 외 예외 = checked Exception

3. 예외 처리 기법

3-1. try catch finally구문

  • 단축키 : ctrl + space
  • try catch finally :
    • finally블록은 무조건 실행. 예외 발생 여부와 상관없이 반드시 실행되어야하는 내용을 작성.
    • 심지어 return문을 만날때에도 먼저 finally 블록을 실행 후 메서드가 리턴된다.
    • finally 주요 목적 : try블록에서 사용한 시스템 자원(System Resource)의 반납처리.
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
public class TryCatchFinallyFlow {

public static void main(String[] args) {

int num = new Random().nextInt(2);
try{
System.out.println("코드1 : "+ num);
int i = 1/num;
System.out.println("랜덤숫자 1일경우 예외없음");
return;
} catch (ArithmeticException e){
System.out.println("랜덤숫자0일경우 예외처리완료");
} finally {
System.out.println("코드4 : 파이널리 항상 실행");
}
System.out.println("코드5");
}

}
//랜덤숫자가 1일경우 출력값 - return때문에 코드5출력되지않음
코드1 : 1
랜덤숫자 1일경우 예외없음
코드4 : 파이널리 항상 실행

//랜덤숫자가 0일경우 출력값
코드1 : 0
랜덤숫자0일경우 예외처리완료
코드4 : 파이널리 항상 실행
코드5

3-2. Exception 객체 정보 활용

참고링크 : Throwable 메서드

  1. getMessage()사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SimpleException {
public static void main(String[] args) {
int[] intArr = {10};
try {
System.out.println(intArr[2]);
} catch (Exception e) {
System.out.println("예외발생 - 배열확인필요 : "+ e.getMessage());
}
System.out.println("프로그램을 종료합니다.");
}
}

//출력값
예외발생 - 배열확인필요 : 2
프로그램을 종료합니다.
  1. printStackTrace()사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SimpleException {
public static void main(String[] args) {
int[] intArr = {10};
try {
System.out.println(intArr[2]);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("프로그램을 종료합니다.");
}
}
//출력값
java.lang.ArrayIndexOutOfBoundsException: 2
프로그램을 종료합니다.
at ch9.SimpleException.main(SimpleException.java:8)

3-3. try with resources 구문

  • try catch finally 코드가 길다.
  • 따라서 java 7버전에서 새롭게 추가된 기능이 try with resources구문이다.
1
2
3
4
5
try (리소스타입1 res1 = 초기화; 리소스타입2 res2 = 초기화; ...){
//예외 발생 코드
}catch(Exception e){
//예외 처리 코드
}

4. throws 키워드를 통한 예외처리 위임

예외 처리의 두번째방법은 throws 키워드를 통한 위임 또는 전달이다.

  1. throws 키워드
  • throws는 메서드에서 처리해야 할 하나 이상의 예외를 메서드를 호출한 곳으로 던져버린다.
  • 이러한 위임은 처리와는 다름.
  • 첫번째 방법이었던 try catch 에서 catch블록은 예외를 처리해서 없애 버림
  • BUT 위임은 예외를 없애지 못하고 그냥 호출한 곳으로 예외를 전달만 함.
  • 예외를 전달받은 메서드는 다시 예외 처리 책임이 발생함.
  1. throws를 왜 사용할까?
  • 항상 try catch로 처리하는 것은 좋지않다
  • WHY? 특히 API나 다른 모듈에서 사용되는 기능을 제공하는 경우 예외를 전달해서 그 예외에 대해 적절히 대응할 수 있는 코드를 작성할 수 있게 해줄 필요가 있기때문이다.
  • 예 : 어떤 프로그램을 install할때

5. 사용자 정의 예외

  • 예외가 unchecked exception계열이면 중간에 throws절차가 필요없다. (ex : runtiomeException)
  • 고급스러운 코딩이 가능하다.

6. throw와 throws 차이

둘 다 Exception을 발생시키지만 큰 차이가 있다.

  • throws : 예외를 위임하는 예약어
  • throw : 억지로 예외를 발생시키는 예약어, 즉 사용자 정의에 의한 exception = 인위적인 exception이다.
    • 생성자에 exception을 넣으면 예외 문구로 출력된다.
1
throw = new throw("나만의 예외메세지");