0708 - JAVA 함수적 인터페이스 / 컬렉션 프레임워크

0708 - JAVA 표준 API의 함수적 인터페이스

andThen() / compose()

  • andThen() 과 compose() 디폴트 메소드
    • 함수적 인터페이스가 가지고 있는 디폴트 메소드
    • 두 개의 함수적 인터페이스를 순차적으로 연결해 실행
    • 첫 번째 리턴값을 두 번째 매개값으로 제공해 최종 결과값 리턴
  • andThen()과 compose()의 차이점은
    • 어떤 함수적 인터페이스부터 처리하느냐에 차이점이 있음
    • andThen()은 A -> B
    • compose()는 B -> A

andThen()

//데이터 소비자를 람다식으로 익명구현객체 생성.
Consumer<Member> consumerA = (m) -> {		//void accept(T t); 
	log.info("consumerA : " + m.getName() );
}; 
// 데이터 소비자를 람다식으로 익명구현객체 생성
Consumer<Member> consumerB = (m) -> {		//void accept(T t);
	log.info("consumerB : " + m.getId());
};
// 위의 2개의 데이터 소비 로직을 하나의 파이프라인(Pipeline)으로 구성 
Consumer<Member> pipline = consumerA.andThen(consumerB);
pipline.accept(new Member("홍길동", "hong"));

프레임워크와 라이브러리의 차이점

  • 라이브러리와 프레임워크의 차이는 제어 흐름에 대한 주도성이 누구에게/어디에 있는가에 있습니다.
  • 즉, 어플리케이션의 Flow(흐름)를 누가 쥐고 있느냐에 달려 있습니다.
  • 프레임워크는 전체적인 흐름을 스스로가 쥐고 있으며 사용자는 그 안에서 필요한 코드를 짜 넣으며 반면에 라이브러리는 사용자가 전체적인 흐름을 만들며 라이브러리를 가져다 쓰는 것이라고 할 수 있습니다.

컬렉션 프레임워크 - ppt 15장

  • 컬렉션 프레임워크 ? -> 객체들을 효율적으로 추가, 삭제, 검색할 수 있도록 제공되는 컬렉션 라이브러리
  • java.util 패키지에 포함

컬렉션 프레임워크의 주요 인터페이스

  • [Collection] -> [List] / [Set]
    최상위 추상메소드(Collection)
  • [Map]

컬렉션 프레임워크의 주요 인터페이스 분류

인터페이스 분류특징구현 클래스
List 계열순서를 유지 O / 중복 저장 OArrayList, LinkedList, Vector
Set 계열순서를 유지 X / 중복 저장 XHashSet, TreeSet
Map 계열키와 값의 쌍으로 저장 / 키는 중복 저장 XHashMap, Hashtable, TreeMap, Properties

- List

  • List는 인덱스로 관리
  • 중복해서 객체를 저장할 수 있다.
  • ArrayList / Vector / LinkedList

ArrayList

  • 추가한 각 요소가 순서를 갖는다 (순서를 보장)
  • 중복된 값이 허용된다. (중복을 허용)
  • add()로 요소를 추가
    • add(3, "nice") --> 인덱스 위치를 직접 지정도 가능
  • remove()로 요소를 제거
    • remove(2) --> 인덱스 위치를 지정해 제거
    • remove("nice") --> 지정된 객체와 동일한 요소를 찾아 제거
  • get(n)으로 요소 값을 참조

리스트의 전체요소를 순회(traverse)하는 방법

    1. 직접 for문과 리스트의 크기를 이용하여 순회
for(int i=0; i<list.size(); i++) {	// 전체 리스트의 요소 순회 
	String str = list.get(i); // 해당 인덱스 번호의 구슬(객체) 얻기 
	log.info(str);
}// classical for
    1. enhanced for문을 이용하는 방법 (단, 인덱스 번호가 필요없을 때 )
for(String s : list) {
	log.info(s);
}//enhanced for 
    1. List.forEach() 최종처리메소드를 이용한 순회 (단, 인덱스 번호가 필요없을 때) 람다식을 이용해서 ArrayList의 전체 요소 출력
//void accept(T t);    T -> String    //타겟타입의 시그니처 메소드 확인 
list.forEach( t -> log.info(t) );  // 람다식으로 구현 해서 요소 출력 
list.forEach(log::info);		// 메소드참조를 이용하여 요소 순회 

Arrays helper 클래스의 asList 메소드를 이용한다면 new 연산자를 사용해서 객체를 생성하지 않아도, 요소의 값을 바로 대입해서 사용할 수 있다.

List<String> list1 = Arrays.<String>asList("홍길동", "신용권", "김자바");
List<Integer> list2 = Arrays.<Integer>asList(1, 2, 3);

Vector

  1. 순서를 보장
  2. 중복을 허용
  • ArrayList와 Vector는 요소를 중간에서 넣고/빼고하게되면, 밀고/땡기는 현상이 발생한다.(주의)
  • Vector의 내부구현은, 99% ArrayList와 동일하다
  • 단지, 멀티쓰레드 환경에서, 요소객체에 대한 조작을 안전하게 할 수 있도록 추가구현
  • 그래서 실무에서는, Thread-safe한 Vector객체를 더 많이 사용한다.
//--1. Thread-safe한 ArrayList 객체 생성 
List<Board> list = new Vector<Board>();

LinkedList

  • LinkedList : 요소를 배열처럼 옆에 붙여놓지 않고, 이곳/저곳에 산발적으로 저장하기때문에, 빈번한 객체 삭제와 삽입이 일어나는 곳에서는 ArrayList보다 좋은성능을 낸다.
    • 1) 따라서 LinkedList는 인덱스 란 개념 자체가 없다
    • 2) 대신, 변경(추가/삭제) 이 자주 발생할 때 생기는 "밀고/땡기는 현상" 자체가 없다.
List<String> list2 = new LinkedList<>(); //타입추론

  • Hash 코드
    최상위 Object 클래스에서 물려주는 hashCode 메소드로
    객체의 물리적인 주소를 논리적인 주소로 변환한 값을 16진수로 표현 -> OID

Set

  • 수학에서 집합에 비유할 수 있다.
  • 저장 순서(X)가 유지되지 않는다.
  • 객체를 중복 저장(X) 불가능하다.
  • 하나의 null만 저장 가능하다.
  • HashSet, LinkedHashSet, TreeSet
  • Set 객체 생성
//Set 객체 생성 
Set<Member> set = new HashSet<>();
  • set은 객체 전체를 순회하기 위해 소위 "반복자(iterator)" 객체를 제공하고, 이 반복자를 이용해서 순회하도록 되어있다.
//Iterator(반복자) 객체반환
Iterator<Member> iterator = set.iterator();		
  • 반복자(iterator)의 hasNext()메소드로 우선 순회할 요소가 남아있는지 확인하고, 있다면(true이면), 반복자의 next() 메소드로 해당 객체를 얻어낼 수가 있다.
while(iterator.hasNext()) {
	Member element = iterator.next();
	log.info("\t" + element);
}//while

Set의 특성상 동일객체(동등객체)는 중복을 허용하지 않기 때문에
Set / HashSet 에 저장되는 객체가 동등객체인지 판단하는 알고리즘이 적용된다.

  • 중복판단을 위한 1단계 알고리즘에 사용 예.
@Override
public int hashCode() {
	log.debug("hashCode() invoked.");
	// 회원의 이름의 해쉬값과 나이를 더한 값으로 회원간의 구분값으로 하자! 
	return name.hashCode() + age;
}//hashCode
  • 중복판단을 위한 2단계 알고리즘에 사용
@Override
public boolean equals(Object obj) {
	log.debug("equals(obj) invoked.");	
	//매개변수로 받은 객체가 같은 회원객체라면
	if(obj instanceof Member) { // 회원객체라면 
		Member member = (Member) obj; // 강제형변환(다형성-1) 			
		//현재 회원과 매개변수로 넘어온 회원간의 비교 기준을,
		//기존 회원의 이름과 나이, 비교 회원의 이름과 나이가 모두 같으면 같은 회원의 판단.
		return member.name.equals(name) && (member.age == age);
	} else {
		return false;  //같은 회원객체가 
	}//if-else
}//equals
  • 이와같은 동등객체(중복판단)판단 알고리즘을 대체하는
    어노테이션이 lombok의 @EqualsAndHashCode 어노테이션

좋은 웹페이지 즐겨찾기