오늘 배운 것은 드디어 리스트 !
파이썬때는 리스트를 엄청많이 썼기때문에 왜 리스트같은게 자바에는 없을까? 라고 생각했는데
역시나 없을리가...
배열에비해 20000000배 편리한 리스트에 대해 알아본다.
배열의 문제점
- 배열은 크기 변경이 불가능
- 넉넉하게 크기를 할당하면 메모리낭비, 적게 할당하면 다시 할당해야하는 번거로움.
- 중간요소 삭제시, 뒤 요소들을 하나씩 당겨서 빈 공간이 없도록 직접 배열을 수정하는 코드 작성해야 함.
- 중간요소 추가시, 기존데이터를 하나씩 뒤로 밀어서 공간이 생기도록 수정하는 코드를 작성해야 함.
* 참고로 ArrayList <- List <- Collection <- Iterable 순으로 인터페이스에 상속되어있음. Iterable이 가장 조상(?) 급.
Generic - 타입제한
1. 요소 추가시 해당타입의 요소만 추가가능
2. 요소를 가져올 경우, 해당 타입으로 반환
Generic에서는 기본형을 사용할 수 없다. 기본형인 경우에는 Wrapper 클래스 사용.
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
// list.add(Integer.valueOf(1)); //자동으로 wrapper타입으로 변환 -> 박싱
list.add(2);
//list.add("안녕");//Integer가 아닌 요소는 추가를 거부
Integer n=list.get(0);
System.out.println(n.intValue());
int m=list.get(1);
//int m=list.get(1).intValue();//wrapper타입을 자동으로 기본형으로 변환 -> 언박싱
list.add(1);
list.add(Integer.valueOf(1)); 은 같은 코드.
int m=list.get(1);
int m=list.get(1).intValue(); 도 같은 코드.
List의 함수들
* list 선언시 우항의 Generic은 좌항과 늘 똑같으므로 생략이 가능하다. (java 1.7이상부터 가능)
- add(값) : 마지막에 값 추가
- add(i ,값) : i 번째 인덱스에 값 추가
- set(i ,값) : i 번째 인덱스를 '값'으로 변경
- remove(i) : i 번째 인덱스 요소를 제거 ( 타입 있음 )
ex) Double justRemoved = list.remove(2); // 2번째 인덱스의 double형인 값이 justRemoved에 저장
- remove(값) : 값이 제거 되었냐에 따라 true/false 리턴
- contains(값) : 값이 존재하는지에 따라 true/false 리턴
- indexOf(값) : 값이 존재하는 경우 위치인덱스값 반환, 없을경우 -1 반환. 앞에서부터 찾아서 가장 먼저 뜨는 것.
- lastIndexOf(값) : indexOf랑 같은데 뒤에서부터 처음 검색된 요소의 인덱스.
- 리스트A.equals(리스트B) : 요소가 모두 일치할때 두 리스트의 equals는 true를 반환
- clear() : 모든 요소 제거
- 리스트이름.isEmpty() : 리스트가 비어있으면 true 반환
- 다른 리스트 합치기
List<Double> other = new ArrayList<>();
other.add(3.45);
other.add(4.56);
other.add(5.67);
list.addAll(1, other); //1위치에 시작해서 합치기
-모든 요소를 열람하는법
1. for문
for(int i=0;i<list.size();i++) {
System.out.print(list.get(i)+(i != list.size()-1 ? " " : "\n"));
}
2. for each문
for(Double d:list)
System.out.println(d+" ");
System.out.println();
3. Iterator (StringTokenizer와 비슷)
Iterator<Double> iter=list.iterator(); // 반복 접근 가능한 객체
while(iter.hasNext()) {
Double d=iter.next();
System.out.print(d+" ");
}
요소 정렬하는법
1. 기본정렬(1개) - 해당 타입 클래스에서 Comparable 인터페이스를 구현 -> compareTo 정렬기준메소드를 오버라이드
2. 기타정렬(n개) - 별도의 Comparator 인터페이스 구현 클래스를 작성 -> compared 정렬기준메소드를 오버라이드
intList = [5,3,2,4,1] 일 때, 오름차순(기본정렬) 과 내림차순(역순정렬)을 해보겠다.
Collections.sort(intList); //오름차순 기본정렬
Comparator<Integer> comp=Collections.reverseOrder(); //기본정렬을 뒤집기
Collections.sort(intList,comp); //내림차순 역순정렬
내림차순(역순정렬)은 Comparator<Wrapper> name = Collections.reverseOrder(); 의 형태를 가진 Comperator를 이용한다.
커스텀클래스 정렬
학생의 번호와 이름이 있는 클래스 Student가 존재할 때, 정렬의 방법은 4가지가 있다.
1. 번호 오름차순
2. 번호 내림차순
3. 이름 오름차순
4. 이름 내림차순
1. 번호 오름차순의 경우, Student클래스 선언부에 implements Comparable<Student>를 붙이고, 함수 내부에 compareTo를 오버라이드 선언한다.
compareTo는 기본정렬 기준필드를 대상으로 비교해서 음수, 0, 양수를 리턴한다.
@Override
public int compareTo(Student other) {
/* if(this.no<other.no)
return -1;
else if(this.no==other.no)
return 0;
else
return 1;
위아래 코드 같음
*/
return this.no-other.no;
}
2. 번호 내림차순은 번호 오름차순을 Comparator써서 역순으로 뒤집는다.
3. 이름순은 존재하지 않기 때문에 별도의 comparent를 구현한다.
Comparator<Student> studentNameAscComp=new StudentNameAscComp();
다음과 같이 선언하면, Student~~에 빨간불이 들어오고 class를 만들 수 있게 된다.
이때 만든다.
import java.util.Comparator;
public class StudentNameAscComp implements Comparator<Student> {
/**
* 기준필드를 비교해서 음수, 0, 양수 중 하나를 리턴
*/
@Override
public int compare(Student o1, Student o2) {
//문자열의 기본 정렬기준 메소드. 문자열을 하나하나 비교함.
return o1.getName().compareTo(o2.getName());
}
}
문자열의 기본 정렬을 돕는 메소드 compareTo가 존재하니 이를 Override 해서 내부에 작성해주자.
그렇다면 메인에서 사용 가능!
4. 3번을 Comparator 사용하면 역순으로 사용 가능 !!
Collection Framework 중에서 오늘 배운 List는 단지 하나에 불과하다.
자바 콜렉션 프레임워크를 쳐보니 다음과 같다고 한다.
오늘 강사님께서 List와 Set, Map을 언급하셨다.
배울게 산더미라는 생각을 새삼 다시 한번 더 했다. ㅠㅠ