java 04 자료구조

재생 목록 만들기

class MockSongs {
  // 이 클래스에는 인스턴스 필드가 없고, 인스턴스 필드를 쓸 필요가 없음 -> 정적메서드로 생성 
  public static List<String> getSongStrings(){ // 노래 목록을 리턴하는 메서드 
    List<String> songs = new ArrayList<>(); 
    // ArrayList 역시 List임. ArrayList 생성하고 List에 저장한다음 메서드에서 List 를 리턴할 수 있음. 
    // 구현하는 타입 (ArrayList)을 숨기고 대신 인터페이스 타입(List)을 리턴하는 코드를 많이 사용함. 
    songs.add("somersault");
    songs.add("havana");
    return songs ;
  }
}

알파벳 순으로 정렬하기

import java.util.*;
 
public class Jukebox1 {
  public static void main (String[] args){
    new Jukebox1().go();
  }
}
 
public void go(){
  List<String> songList = MockSongs.getSongStrings(); // 곡명을 String List에 저장하기 
  System.out.println(songList); // songList을 출력하기 
}
 
// tmp
public static List<String> getSongStrings(){ // 노래 목록을 리턴하는 메서드 
  List<String> songs = new ArrayList<>(); 
  // List<String> 을 봤을때 어차피 String이 들어올것을 유추할 수 있으므로 타입을 <> 비워둠. => 타입 추론 
  // ArrayList 역시 List임. ArrayList 생성하고 List에 저장한다음 메서드에서 List 를 리턴할 수 있음. 
  // 구현하는 타입 (ArrayList)을 숨기고 대신 인터페이스 타입(List)을 리턴하는 코드를 많이 사용함. 
  songs.add("somersault");
  songs.add("havana");
  return songs ;
}

List에서는 원소가 추가된 순서대로 저장됨.

컬렉션 ?

java.util.List

java.util.Collections

컬렉션 클래스 : 유틸리티 클래스. 다양한 컬렉션 타입을 다룰때 유용한 메서드들이 있음!

public void go(){
  List<String> songList = MockSongs.getSongStrings(); // 곡명을 String List에 저장하기 
  System.out.println(songList); 
  Collections.sort(songList);  // 정렬
  System.out.println(songList); 
}

String이 아닌 Song 객체를 정렬하기

Class SongV2{
  // 파일에 있는 곡 정보를 위한 세 개의 인스턴스 
  private String title ;
  private String artist ;
  private int bpm ;
 
  SongV2(String title, String artist. int bpm) {
    this.title = title;
    thie.artist = artist;
    this.bpm = bpm ;
  }  
 
  public String getTitle(){
    return title ;
  }  
  public String getArtist(){
    return artist;
  }
  public int getBpm(){
    return bpm;
  }
 
  // System.out.println(aSongObject)를 호출하면 곡명이 출력되도록 toString()메서드를 오버라이드 함. 
  public String toString(){ 
    return title;
  }
}
class MockSongs{
  public static List<String> getSongStrings(){
    ...
  }
  public static List<SongV2> getSongV2(){
    List<SongV2> songs = new ArrayList<>();
    songs.add(new songV2("somersault","zero 7",147));
    songs.add(new songV2("havana","cebello",105));
  }
}
import java.util.*;
 
public class Jukebox2 {
  public static void main (String[] args){
    new Jukebox2().go();
  }
 
  public void go(){
    List<SongV2> songList = MockSongs.getSongV2(); // 곡명을 String List에 저장하기 
    System.out.println(songList); // songList을 출력하기 
 
    Collections.sort(songList); // songList의 무얼 기준으로 정렬해야 할지 알 수 없음.
    System.out.println(songList); // songList을 출력하기 
  }
}

제네릭 ?

타입안정성을 갖춘 컬렉션을 만들기 위한 용도로 사용. => 컴파일 할 때 찾아줄 수 있음.

  • 제네릭이 도입되기 전에는 모든 컬렉션에 Object 타입의 객체를 아무렇게나 집어넣을 수 있었음. => 컴파일러가 뭐라고 안함.
  1. 제네릭을 쓰는 클래스(ArrayList 등)의 인스턴스를 만드는 방법
  • new ArrayList<Song>()
  • ArrayList를 만들 때는 일반 배열을 만들때와 마찬가지로 목록에 들어갈 수 있는 객체 타입을 알려줘야 함.
  1. 제네릭 타입의 변수를 선언하고 변수에 값을 대입하는 방법
  • List<Song> songList = new ArrayList<Song>()
  • 제네릭 타입에 다형성이 작동하는 방법 ?
  1. 제네릭 타입을 인자로 받아들이는 메서드 선언 (호출) 방법
  • void foo (List<Song>list) x.foo(songList)
  • 어떤 메서드에 특정 객체로 구성된 ArrayList를 인자로 받는다 ???

제네릭 클래스(ex ArrayList) 사용하기

public class ArrayList<E> extends Abstract List< E> implements  List<E> ...{
  // <E> : ArrayList를 선언하고 생성할 때 사용할 실제 타입. 인스턴스를 생성할 때 쓰이는 타입  
  public boolean add(E o)
}

제네릭 메서드 사용하기

  • 제네릭 클래스 : 클래스 선언에 타입 매개변수가 들어있는 클래스를 의미함.
  • 제네릭 메서드 : 메서드 선언 서명에 타입 매개변수가 포함되어 있는 메서드.
  1. 클래스 선언부에서 정의된 타입 매개변수를 사용하기
  • 클래스를 정의할 때 타입 매개변수를 선언한 경우, 그 타입을 특정 클래스 또는 인터페이스 타입을 사용하는 것과 동일한 방식으로 사용할 수 있음.
pubic class ArrayList<E> extends AbstractList<E> ... {
  // 클래스를 정의할 때 이미 E를 사용했기 때문에 아래에서 자연스럽게 E를 사용할 수 있음
  pubic boolean add(E o)
}
  1. 클래스 선언부에서 사용되지 않는 타입 매개변수를 사용하기
  • 클래스 자체에서는 타입매개변수를 사용하지 않는 경우에도, 특별한 위치 (리턴타입을 선언하는 곳 바로 앞)에서 선언해주기만 하면 메서드 내에서 타입매개변수를 별도로 지정해서 사용가능.
pubic <T extends Animal> void takeThing(ArrayList<T> list)
// 메서드 선언 시 T를 선언했기 때문에 뒤에서 T를 사용할 수 있음.
// Animal 타입 및 하위 클래스 타입이면 뭐든 T 자리에 들어올 수 있음.
```
`