List
1. List 인터페이스
: 순서가 있는 데이터의 집합으로, 같은 데이터의 중복 저장을 허용한다.
- ArrayList, LinkedList, Vector, Stack
ArrayList
- 크기 변경이 불가능한 배열의 단점을 보완. 기본 배열보다 느릴 수는 있지만 동적 배열이 구현돼 있다.
- ArrayList 인스턴스를 생성하게 되면 내부적으로 10칸짜리 배열을 생성해서 관리한다.
- 크기 변경, 요소 추가/삭제/정렬 기능들을 메소드로 제공한다.
- ArrayList는 스레드 간 동기화가 지원되지 않기 때문에, 다수의 스레드가 동시에 접근하여 데이터를 조작하게 될 경우 데이터 훼손이 일어날 수 있다.
- cf. 모든 컬렉션 프레임워크는 제네릭 클래스로 작성 되어 있다.
List<String> stringList = new ArrayList<>();
stringList.add("apple");
stringList.add("banana");
stringList.add("orange");
stringList.add("mango");
stringList.add("grape");
// stringList.add(123);
1. ArrayList 선언하기
- 다형성을 이용해서 상위 레퍼런스로 ArrayList 객체를 참조할 수 있다.
- List 인터페이스 하위의 다양한 구현체들로 타입 변경이 가능하므로, 상위 타입으로 선언하는 것이 더 유연한 코드이다.
ArrayList alist = new ArrayList();
List list = new ArrayList(); // 레퍼런스 타입은 List로 해두는 것이 유연하다.
Collection clist = new ArrayList();
2. 요소 저장하기
- Object 클래스의 하위 타입 인스턴스를 모두 저장 가능
alist.add("apple");
alist.add(123); //autoBoxing 처리됨(값(int) -> 객체(Integer))
alist.add(45.67); // autoBoxing 처리됨(값(double) -> 객체(Double))
alist.add(new Date());
/*데이터의 중복 저장 허용(인덱스가 다른 위치에 동일한 값 저장 가능)*/
alist.add("apple");
System.out.println("alist : " + alist);
/* 원하는 위치에 값을 추가할 수 있다.
값을 중간에 추가하는 경우 인덱스 위치에 덮어쓰는 것이 아니고,
새로운 값이 들어가는 인덱스 위치에 값을 넣고 이후 인덱스는 하나씩 뒤로 밀리게 된다.*/
alist.add(1, "banana");
System.out.println("alist : " + alist);
3. 요소의 개수 반환
- 내부 관리 배열의 사이즈는 외부에서 알 필요가 없으므로 제공하지 않는다.
System.out.println("alist.size() : " + alist.size());
4. 요소에 접근하기
/* get 메소드에 index를 전달하여 하나의 요소에 접근 가능하다. */
for(int i = 0; i < alist.size(); i++) {
System.out.println(i + " : " + alist.get(i));
}
5. 요소 삭제하기
/* 저장 된 값을 삭제할 때는 remove().
중간 인덱스의 값을 삭제하는 경우 자동으로 인덱스를 하나씩 앞으로 당긴다.*/
alist.remove(2);
System.out.println("alist : " + alist);
6. 지정된 위치의 값 수정하기
// 인덱스 1의 값 수정
alist.set(1, true);
System.out.println("alist : " + alist);
7. 오름차순으로 정렬하기
/*toString() 메소드가 overriding 되어 있다. 출력해보면 저장 순서를 유지하고 있다.*/
System.out.println("alist : " + alist);
/* 저장 순서대로 유지 된 리스트가 정렬을 하면 문자열 오름차순으로 정렬 된다.
* Collections 는 컬렉션에서 활용되는 기능들을 static 메소드로 구현해 둔 클래스이다.
* sort() 메소드를 사용하면 list가 오름차순 정렬 처리된 후 정렬 상태가 유지된다.*/
System.out.println("stringList : " + stringList);
Collections.sort(stringList);
System.out.println("stringList : " + stringList);
8. 내림차순으로 정렬하기
- 기본적으로 ArrayList에는 역순으로 정렬하는 기능이 제공되지 않기 때문에,
역순으로 정렬하려면 역순 정렬 기능이 있는 LinkedList를 이용해야한다. (ArrayList는 LinkedList로 변경 가능)
- Iterator 반복자 인터페이스를 이용해보면, LinkedList 타입으로 형변환을 해준 후 descendingIterator() 메소드를 사용하면 내림차순으로 정렬된 Iterator 타입의 목록으로 반환해준다.
* Iterator
- 반복자로, 반복문을 이용해서 목록을 하나씩 꺼내는 방식으로 사용한다. 인덱스로 관리되는 컬렉션이 아닌 경우에는 반복문을 사용해서 요소에 하나씩 접근할 수 없기 때문에 인덱스를 사용하지 않고도 반복문을 사용하기 위한 목록을 만들어주는 역할이다.
- hasNext(): 다음 요소를 가지고 있는 경우 true, 없는 경우 false를 반환
- next(): 다음 요소를 반환
stringList = new LinkedList<>(stringList);
Iterator<String> dIter = ((LinkedList<String>) stringList).descendingIterator();
/*역순으로 정렬된 결과를 저장하기 위해선 새로운 ArrayList를 만들어서 저장해두면 된다.*/
list<String> descList = new ArrayList<>();
while(dIter.hasNext()) {
descList.add(dIter.next());
}
System.out.println("descList: " + descList);
* ArrayList 사용 예제
public class BookDTO implements Comparable<BookDTO> {
private int number;
private String title;
private String author;
private int price;
public BookDTO(int number, String title, String author, int price) {
this.number = number;
this.title = title;
this.author = author;
this.price = price;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@Override
public String toString() {
return "BookDTO{" +
"number=" + number +
", title='" + title + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
/* 제목 내림차순 정렬 기준을 내부 기준으로 설정 */
@Override
public int compareTo(BookDTO o) {
return o.getTitle().compareTo(getTitle()); // 여기에 있는 compareTo는 String 클래스의 compareTo 메서드이다.
/* String 클래스의 compareTo 메서드는 두 문자열을 사전순으로 비교해서
현재 문자열이 비교 대상 문자열보다 사전 순으로 앞에 위치할 경우 음수,
두 문자열이 같을 경우 0, 사전 순으로 뒤에 위치할 경우 양수를 반환한다.*/
}
}
/* Compartor 사용 시 제네릭 선언을 함께 해야 compare 메소드의 매개변수 타입이 정의 된다.
* Object 타입인 경우 다운 캐스팅 해서 사용해야 하므로 불편하다. */
public class AscendingPrice implements Comparator<BookDTO> {
/* sort() 메소드에서 내부적으로 compare 메소드를 호출하여 swap 여부를 결정 */
@Override
public int compare(BookDTO o1, BookDTO o2) {
/* 인스턴스의 가격이 오름차순 정렬 되기 위해서는 앞의 가격이 더 작은 가격이어야 한다.
* 만약 뒤의 가격이 더 작은 경우 두 인스턴스의 순서를 바꿔야 한다.
* 그 때 두 값을 바꾸라는 신호로 양수를 반환하면 정렬 시 순서를 바꾸는 조건으로 사용 된다.
* */
int result = 0;
if(o1.getPrice() > o2.getPrice()) {
result = 1;
} else if(o1.getPrice() < o2.getPrice()) {
result = -1;
}
return result;
}
}
public class Application2 {
public static void main(String[] args) {
List<BookDTO> bookList = new ArrayList<>();
bookList.add(new BookDTO(1, "홍길동전", "허균", 50000));
bookList.add(new BookDTO(2, "목민심서", "정약용", 30000));
bookList.add(new BookDTO(3, "동의보감", "허준", 40000));
bookList.add(new BookDTO(4, "삼국사기", "김부식", 46000));
bookList.add(new BookDTO(5, "삼국유사", "일연", 58000));
for(BookDTO bookDTO : bookList) {
System.out.println(bookDTO);
}
/* implements Comparable 을 통해 compareTo 메소드(정렬 기준 반환)가 재정의 되어야만 사용 가능 */
// 우리는 BookDTO에 implements Comparable을 해주지 않았기 때문에 컴파일 에러 발생
// Collections.sort(bookList); 컴파일 에러
/* Comparator 인터페이스를 구현한 정렬 기준을 작성한다. */
System.out.println("가격 오름차순 정렬 ==============");
// Collections.sort(bookList, new AscendingPrice());
bookList.sort(new AscendingPrice());
for(BookDTO bookDTO : bookList) {
System.out.println(bookDTO);
}
/* 정렬 기준을 계속 사용하는 경우 별도의 클래스를 만들어서 사용해도 되지만
* 한 번만 사용하기 위해서 더 간편하게 익명 클래스(Anonymous class)를 사용할 수도 있다. */
System.out.println("가격 내림차순 정렬 ==============");
bookList.sort(new Comparator<BookDTO>() {
@Override
public int compare(BookDTO o1, BookDTO o2) {
return o2.getPrice() - o1.getPrice();
}
});
for(BookDTO bookDTO : bookList) {
System.out.println(bookDTO);
}
System.out.println("제목 오름차순 정렬 ===========");
bookList.sort(new Comparator<BookDTO>() {
@Override
public int compare(BookDTO o1, BookDTO o2) {
/* 문자열 대소비교는 String 클래스에 정의 된 compareTo() 메소드를 활용한다. */
return o1.getTitle().compareTo(o2.getTitle());
}
});
for(BookDTO bookDTO : bookList) {
System.out.println(bookDTO);
}
System.out.println("제목 내림차순 정렬 ===========");
/* implements Comparable<BookDTO> 수행 후에는 해당 코드가 동작 된다. */
Collections.sort(bookList);
for(BookDTO bookDTO : bookList) {
System.out.println(bookDTO);
}
}
}
'Java' 카테고리의 다른 글
[Java] 13. Collection (3) Stack & Queue (0) | 2024.08.23 |
---|---|
[Java] 13. Collection (2) List - LinkedList (0) | 2024.08.22 |
[Java] 13. Collection (0) | 2024.08.22 |
[Java] 12. 제네릭 프로그래밍 (0) | 2024.08.21 |
[Java] 11. 입출력 (0) | 2024.08.21 |