본문 바로가기

JAVA공부(이것이 자바다)

컬렉션 자료구조

Set

저장순서가 유지되지 않는 컬렉션, 저장 순서가 유지 되지 않는다. 중복이 허용되지 않는다. 같으면 저장을 하지 않기 때문에 처음 데이터가 남아있다. Object를 통해서 매개변수를 받는 거는 equals와 hashCode를 재정의해야한다.

 

 

HashSet

hashCode()값과 equals 값이 둘다 true면 동일객체로 판단하고 중복저장하지 않는다

Set<E> set = new HashSet<>();

Iterator

반복자를 얻어와서 객체를 하나씩 순회하는 것이다

키가 많아지면 for-each보다 성능이 좋아진다.

Set<E> set = new HashSet<>();
Iterator<E> iterator = set.iterator();

--> iterator로 순회하면서 제거할 것을 찾아 삭제하는 건 멍청한 짓. 걍 remove로 삭제할 수 있기 때문이다.

 

 

Map

Map은 중첩클래스로 키와 값쌍으로 엔트리 객체를저장한다.

키는 중복저장이 불가능하지만 값은 중복저장할 수 잇다. 배열보다 속도가 빠르다

키값이 같으면 해당 키의 값을 변경하기 때문에 마지막에 추가한 데이터가 남아있다. Object를 통해서 매개변수를 받는 거는 equals와 hashCode를 재정의해야한다.

 

HashMap

동일 키를 중복저장하지 않는다. 단일 스레드에서 동작한다.

Map<String, Integer> map = new HashMap<>();

 

 

Hashtable

멀티스레드에서 안전하게 객체를 추가, 삭제할수있다. 동기화된 메소드를 갖고 있다.

Map<String, Integer> map = new Hashtable<>();

 

properties

HashTable의 키 ,값을 String으로 제한한 자식 클래스이고 주로 파일을 읽어와서 load를 통해 올리고 파일안에서 키 값은 =기호로 연결한다. 파일의 위치를 가져올 때는 getResourceAsStream으로 가져오는데 사용자마다 각자 다른 곳에서 실행 할 수 있기 때문에 실행되는 클래스를 기준으로 찾아가는 것이 좋다.

Properties properties = new Properties();
properties.load(xxxx.class.getResourceAsStream("database.properties");

 

 

Map의 키값 가져오기 Iterator라는 쓰레기에서 for-each라는 편리함으로 바꾸기

//키 Set 컬렉션을 얻고, 반복해서 키와 값을 얻기
Set<String> keySet = map.keySet();
Iterator<String> keyIterator = keySet.iterator();
while (keyIterator.hasNext()) {
    String k = keyIterator.next();
    Integer v = map.get(k);
    System.out.println(k + " : " + v);
}
System.out.println();
///바꾸기
for (String k : map.keySet()) {
    Integer v = map.get(k);
    System.out.println(k + " : " + v);
}
System.out.println();

Map의 entryset으로 키와 값을 둘다 가져오기 iterator에서 for- each로 바꾸기

//엔트리 Set 컬렉션을 얻고, 반복해서 키와 값을 얻기
Set<Entry<String, Integer>> entrySet = map.entrySet();
Iterator<Entry<String, Integer>> entryIterator = entrySet.iterator();
while (entryIterator.hasNext()) {
    Entry<String, Integer> entry = entryIterator.next();
    String k = entry.getKey();
    Integer v = entry.getValue();
    System.out.println(k + " : " + v);
}
System.out.println();

for(Entry<String, Integer> entry : map.entrySet()) {
    String k = entry.getKey();
    Integer v = entry.getValue();
    System.out.println(k + " : " + v);
}
System.out.println();

 

검색 기능을 강화시킨 컬렉션

 

TreeSet

부모노드와 비교헤서 낮은 객체는 왼쪽 자식에 높은것은 오른쪽 자식에 저장한다. 값만 존재하고 중복은 허용하지 않는다. 검색이 set보다 빠르다.

이진트리 기반 set컬렉션이다. 하지만 TreeSet에만 존재하는 함수가 존재해서 set에 대입하지 않는다.

TreeSet<E> treeSet = new TreeSet<>();

 

TreeMap

키값 쌍의 Entry객체로 저장하고 키를 기준으로 자동 정렬된다. 낮은 것은 왼쪽, 높은 것은 오른쪽에 둔다. 이진트리 기반 Map컬렉션으로 중복을 허용하지 않는다. Map보다 검색이 빠르다.

TreeMap<K,V> treeMap = new TreeMap<>();

 

Comparable

소스에 수정 권한이 있을때 객체를 비교하여 양수, 음수, 0을 리턴해서 값을 정렬하는 것!

compareTo() 함수를 재정의해서 사용한다. 사용자 정의 객체를 저장할때는 반드시 comparable을 구현하고 있어야한다.

public int compareTo(T o){

}

Comparator

소스에 대한 수정권한이 없을 때 객체를 비교하여 정렬하기 위한 인터페이스 

 

 

Comparator를 익명객체로 삽입

TreeSet<Fruit> treeSet = new TreeSet<Fruit>(new Comparator<Fruit>() {
			public int compare(Fruit o1, Fruit o2)  {
				return o1.getPrice() - o2.getPrice();
			}
		});

비교기능이 없는 Comparable 비구현 객체를 저장하려면 TreeSet과 TreeMap에 비교자를  제공하면된다.

TreeSet<E> treeSet = new TreeSet<E>(new ComparatorImpl());

TreeMap<K,V> treeMap = new TreeMap<K,V>(new ComparatorImpl());

 

 

스택 (LIFO)

-포인터 하나

push() 객체 넣기

pop()맨위에 객체 빼기

Stack<E> stack = new Stack<>();

 

큐(FIFO))

- 포인터 두개

순서를 보장하고 배열로 구성되어있다.

offer() - 넣기

poll() - 빼기

Queue<E> queue = new LinkedList<>();

 

동기화된 컬렉션

비동기화된 메소드를 동기화된 컬렉션으로 래핑하는 메소드가 잇다. 

동기화 컬렉션 보다 성능이 좋고 빠르고 공간도 적게 차지해서 쓰기 좋다.

List - synchronizedList(List<T> list)

Map - synchronizedMap(Map<K,V> m)

Set - synchronizedSEt(Set<T> s)

Map<Integer,String> map = Collections.synchronizedMap(new HashMap<>());

 

수정할 수 없는 컬렉션

요소를 추가 삭제 할 수 없느 ㄴ컬렉션 으로 변경불가능하다.

1. List,Set,Map의 of 메소드를 이용해서 생성할 수 잇다.

List.of();
Set.of();
Map.of();

2. copyOf()로 기존의 컬렉션을 복사해서 수정할 수 잇는 컬렉션을 만들수 잇다.

List.copyOf();
Set.copyOf();
Map.copyOf();

 

람다식

 

함수명에 상관 없이 함수형 인터페이스의 한가지 메소드를 정의해서 쓰는것이다.

함수명을 상관할 필요가 없고 무엇을 상속받는 지 알 필요가 없다. 인터페이스를 익명객체로 재정의해서 호출하는 방법과 유사하다.

()->{}

(a,b)->{}

a -> {}

 

함수형 인터페이스 

@FunctionInterface라는 어노테이션을 달고 인터페이스 안에 함수가 하나만 정의되어있는 인터페이스를 의미한다.

@FunctionInterface어노테이션은 object class의 public으로 선언된 equals, toString, hashCode는 추상메소드로 선언해도 없는 함수로 인정한다. 이 어노테이션은 인터페이스에 재정의할 함수가 하나인지 확인하여 함수형 인터페이스를 정확히 구현하도록하는 어노테이션이다.

 

콜백함수

특정시점에 시스템이 내가 정의해 놓은 함수를 호출해주는 것이다. 인터페이스의 참조변수에 자식클래스를 할당하고 재정의된 함수를 불러오는 것과 같다.

 

메소드 참조 

정적 메소드

클래스::메소드명

person.action((x,y)->Computer.staticMethod(x,y));

person.action(Computer::staticMethod);

 

인스턴스 메소드

a 매개변수의 메소드를 호출해서 b매개변수를 매개값으로 사용하겠다.

(a, b) -> {a.instanceMethod(b);}

참조변수::메소드명

person.action((x,y)->com.instanceMethod(x,y));

person.action(com::instanceMethod);

 

생성자 참조 

단순히 객체를 생성하고리턴만하도록 구성할때 람다식을 생성자 참조로 대치할 수 있다.

클래스명::new

Member m1 = person.getMember1(Member::new);

Member m1 = person.getMember1(a ->{return new Member()});

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'JAVA공부(이것이 자바다)' 카테고리의 다른 글

입출력스트림  (0) 2023.06.14
스트림  (2) 2023.06.13
스레드  (3) 2023.06.09
java.base 이어서  (0) 2023.06.08
java.base 모듈  (2) 2023.06.07