본문 바로가기

신세게 - Java 공부

5주차 배운점 느낀점 - Properties, TreeSet, TreeMap, Comporable, Comprator

728x90
반응형

5주차

 

강사님이 코테준비할때 이진트리 필요하다고 하셨다. 공부해야겠다.
TreeSet, TreeMap를 배웠다. 이 자료구조는 명확한 비교 기준이 없기 때문에 Sort() 시키면 오류가 난다. 정렬을 위한 인터페이스 Comporable, Comparator 도 배웠다.

 

배운점

 

Properties
Properties는 Hashtable의 자식 클래스. 키와 값을 String 타입으로 제한한 컬렉션
주로 확장자가 .properties인 프로퍼티 파일을 읽을 때 사용
프로퍼티 파일은 키와 값이 = 기호로 연결된 텍스트 파일(ISO 8859-1 문자셋, 한글은 \u+유니코드)
Properties 객체를 생성하고, load() 메소드로 프로퍼티 파일의 내용을 메모리로 로드

 

driver = oracle.jdbc.OracleDriver
url = jdbc:oracle:thin:@localhost:1521:ord
username=scott
password = tiger
admin = \u064D\uAE38\uB3D9
..
database.properties 로 메모장 만듦

 

외장하드에있는 내용 (외부)의 자료를 활용하기위해서 불러들임 , 리소스 접근해서 안에들어있는 내 메모리 영역으로 데이터 가져오는 클래스다 !

객체를 이용해서 자바 어플리케이션 메모리에 외부 것을 읽어 오기

 

public static void main(String[] args) throws Exception{
    //Properties컬렉션 생성
    Properties properties = new Properties();
    //database.properties 파일 로드
    properties.load(PropertiesEx.class.getResourceAsStream("database.properties"));

    //주어진 키에 대한 값을 읽기
    String driver = properties.getProperty("driver");
    String url = properties.getProperty("url");
    String username = properties.getProperty("username");
    String password = properties.getProperty("password");
    String admin = properties.getProperty("admin");

    System.out.println("driver: "+ driver);
    System.out.println("url: " + url);
    System.out.println("username: " + username);
    System.out.println("password: "+password);
    System.out.println("admin: "+admin);
  }

 

TreeSet


이진 트리를 기반으로 한 Set 컬렉션
여러 개의 노드가 트리 형태로 연결된 구조. 루트 노드에서 시작해 각 노드에 최대 2개의 노드를 연결할 수 있음
TreeSet에 객체를 저장하면 부모 노드의 객체와 비교해서 낮은 것은 왼쪽 자식 노드에, 높은 것은 오른쪽 자식 노드에 저장
사이클이 이루지 않음!! 돌면 그래프
이진탐색트리: 조건이 있음 큰건 오른쪽, 작은건 왼쪽, 탐색속도가 빠름

 

 

 

TreeSet


이진트리는 여러개의 노드가 트리 형태로 연결된 구조
TreeSet에 객체 저장하면 자동정렬이 된다.

TreeSet 컬렉션을 생성하는 방법

 

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

 

Set 타입 변수에 대입해도 되지만 TreeSet 타입으로 대입한 이유는 검색 관련 메소드가 TreeSet에만 정의되어 있기 때문

 

예시:

 

public static void main(String[] args) {
    TreeSet<Integer> scores = new TreeSet<>();
    // Integer 점수 저장

    scores.add(75);
    scores.add(80);
    scores.add(87);
    scores.add(70);
    scores.add(65);
    scores.add(63);
    scores.add(90);
    scores.add(95);

    Iterator<Integer> iterator;
    //점수를 foreach문을 이용해서 전체 점수 출력
    iterator = scores.iterator();
    while(iterator.hasNext()){
      System.out.println(iterator.next());
    }

    scores.forEach(System.out::println);

    //특정 점수를 가져오기
    System.out.println(scores.floor(87));

    // 가장 낮은 점수 출력
    System.out.println(scores.first());

    // 가장 높은 점수 출력
    System.out.println(scores.last());

    //90점 아래 점수
    System.out.println(scores.headSet(scores.floor(90),false));
    System.out.println(scores.headSet(90, false));

    //90점 위 점수
    System.out.println(scores.tailSet(scores.floor(90),false));
    System.out.println(scores.tailSet(90, false));

    // 90점이거나 바로 아래 점수
    System.out.println(scores.lower(90));

    // 80점이거나 바로 위의 점수
    System.out.println(scores.higher(90));

    // 내림차순 정렬하기
    iterator = scores.descendingIterator();
    while(iterator.hasNext()){
      System.out.print(iterator.next());
    }
     NavigableSet<Integer> descendingScores = scores.descendingSet();
    for(Integer s : descendingScores){
      System.out.println(s + " ");
    }

    System.out.println(scores.descendingSet());

    // 범위 검색(80<=)
    System.out.println(scores.tailSet(scores.floor(80),true));
    System.out.println(scores.tailSet(80, true));

    // 범위 검색(80<= scores < 90)
    System.out.println(scores.subSet(scores.floor(80),true,scores.floor(90),false));
    System.out.println(scores.subSet(80,true,scores.floor(90),false));
  }

 

TreeMap


키 기반 어센딩
이진 트리를 기반으로 한 Map 컬렉션. 키와 값이 저장된 엔트리 저장
부모 키 값과 비교해서 낮은 것은 왼쪽, 높은 것은 오른쪽 자식 노드에 Entry 객체를 저장
이진 검색트리의 형태로 키와 값의 쌍으로 이루어진 데이터 저장 SortedMap 인터페이스를 구현하고 있어 Key 기준으로 정렬된다.
정렬된 순서로 Key/Value 저장, 범위 검색시 빠른 검색 보장
정렬되는 순서는 숫자, 알파벳 대문자, 소문자, 한글 순으로 정렬된다.

 

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

 

 

정렬 Comporable, Comparator


TreeSet에 저장되는 객체와 TreeMap에 저장되는 키 객체를 정렬
Comparable 인터페이스에는 compareTo() 메소드가 정의. 사용자 정의 클래스에서 이 메소드를 재정의해서 비교 결과를 정수 값으로 리턴

 

 

String, Integer, Double 등 ==> compare()
기본적으로 오름차순으로 제공(내림차순하고 싶으면 매개변수 순서변경)
비교 기능이 없는 Comparable 비구현 객체를 저장하려면 비교자 Comparator를 제공
비교자는 compare() 메소드를 재정의해서 비교 결과를 정수 값으로 리턴

 

Comporable


정렬 수행할때, 정렬기준이 되는 메서드를 정의해 놓는 인터페이스
Comparable 인터페이스를 implements 하여 구현
compareTo() 메소드를 원하는 정렬 기준대로 구현한다.
추상메소드, int리턴 0 리턴, 주어진객체가 적으면 -1, 주어진객체보다 큰값은 양수리턴..
기존정렬에 기준을 바꿀 수 있다.

 

main class

public static void main(String[] args) {
    TreeSet<Member> members = new TreeSet<>();
    //객체 저장
    members.add(new Member("김진염", 22)); 
    members.add(new Member("김진아", 21));
    members.add(new Member("김소영", 21));
    members.add(new Member("박소영", 25));

    // implements 안해주면 member는 기준이없어서 에러남
    // overriding 안해주면 김진염 22 만나옴
    for (Member m : members) {
      System.out.println(m.name + " " + m.age);
    }
  }

 

Member class


compareTo를 오버라이딩 해놓으니까 기준이 생김.
출력될때 정렬된다 orderby!!

 

public class Member implements Comparable<Member>{
  public String name;
  public Integer age;
  public Member(String name, Integer age){
    this.name = name;
    this.age = age;
  }
  public int hashCode(){
    return name.hashCode() + age;
  }

  public boolean equals(Object o){
    if(o instanceof Member m){
      return m.name.equals(name) && (m.age == age);
    }else {
      return false;
    }
  }

  //오름차순 정렬하고 싶다.
  // 기준점 제시
  @Override
  public int compareTo(Member o) {
    if(age<o.age) return  1; //주어진것보다 작으면
    else if(age == o.age) return 0; // 같으면
    else return -1;
  }
  
}

 

위와같이 해주면 age가 같을경우는 하나 스킵되서 출력됨
김진아 21
김진염 22
박소영 25

 

이렇게 해주면(기본형) 비교할게 없어서 같다하고 끝나버림, 김진염 22만 출력됨

 

  @Override
  public int compareTo(Object o) {
    return 0;
  }

 

이렇게 해주면 내림차순 됨

 

@Override
  public int compareTo(Member o) {
    if(age<o.age) return  -1; //주어진것보다 작으면
    else if(age == o.age) return 0; // 같으면
    else return 1;
  }

 

 

빼기 표현
오버플로우 날 수 있음.

 

@Override
  public int compareTo(Car o) { // 메소드오버라이딩
    int comparePrice = o.getPrice();
    return comparePrice - this.price;  // price기준 내림차순
    return this.price - comparePrice; // price 오름차순
  }

 

이렇게 쓰셈

 

 @Override
  public int compareTo(Node o) {
    return Integer.compare(order,o.order);
  }

 

Comparator


내가 직접만든기준에 의해서 작업하겠다.
compare 메소드를 오버라이딩 해야되고 매개변수 두개다.

 

compare(  , )

 

Dot class

 

public class Dot {
  Integer x,y;

  public Dot(Integer x, Integer y) {
    this.x = x;
    this.y = y;
  }
  ....

 

x값으로 오름차순 할 거다.
compare메소드에서 (Dot o1, Dot o2)를 매개변수 받고 x 가 같은경우 y를 비교한다.

 

compare(o1.getY(),o2.getY());

 

기본적으로 오름차순 정렬인데, 내림차순하고 싶으면 자리를 바꿔준다.

 

compare(o2.getY(),o1.getY());

 

DotMain class


메인에서 익명클래스로 사용함

 

public class DotMain {
  public static void main(String[] args) {
    Dot[] dots = new Dot[3];
    dots[0] = new Dot(1,4);
    dots[1] = new Dot(1,1);
    dots[2] = new Dot(2,2);

    Arrays.sort(dots,new Comparator<Dot>(){
      @Override
      public int compare(Dot o1, Dot o2) {
        if(o1.getX() == o2.getX()){ // x 가 같을 때
          return Integer.compare(o1.getY(),o2.getY());  //y 비교
        }
        return Integer.compare(o1.getX(),o2.getX());
      }
    });
    Arrays.stream(dots).forEach(dot -> System.out.println("("+dot.getX()+","+dot.getY()+")"));
  }
}

 

다른 방법


implements한 클래스에서 써줬다.
score는 내림차순인데 score가 같을 때 id가 오름차순이기때문에 - 를 붙여줬다.

 

@Override
  public int compare(Student o1, Student o2) {
    return COMPARATOR.compare(o2,o1); //내림차순
  }
  private static final Comparator<Student> COMPARATOR =
          Comparator.comparing((Student number) -> number.score)
                  .thenComparing(number -> - number.id); // - 붙임(반대방향)

 

객체를 정렬하는 기준을 알 수 없기때문에 오류가난다. -> 정렬기준을 Comparator와 Comparable로 직접 구현해야한다.

 

Comparable : 자기자신과 매개변수 객체를 비교한다.
Comparator : 두 매개변수 객체 비교
라는 차이가 있다.

 

둘이 동작은 똑같지만 compare은 위에 코드처럼 익명객체(클래스)를 사용할 수 있다.

 

회고

 

부끄럽지만 Comparable과 Comparator 를 처음 보았다. 정렬에 사용되는 인터페이스 인데 많은 예제 파일을 수업따라치면서도 이해가 안되었었다. 차근차근
Integer.compare( , )의 동작을 알았고 그에 따라 풀어 쓴

if(age<o.age) return  1; //주어진것보다 작으면
else if(age == o.age) return 0; // 같으면
else return -1;

도 점점알아가면서 수업이 종료되기전에 오늘 내용을 이해하게 되었다.
알고나면 간단해보이는데 배울때는 힘든 듯 하다.
비슷한 유형이라면 그 중 한개를 먼저 이해하고 , 다른 경우도 차근차근 비교하면 된다를 느꼈다.

반응형