자료구조를 구현한 Java의 API 클래스들 대량의 데이터를 효율적으로 관리하기 위한 것
데이터의 주소값들을 저장함
순서 | 인덱스 번호 | 중복 | 종류 | |
---|---|---|---|---|
List | O | O | O | Vector / ArrayList/ LinkedList |
Set | X | X | X | HashSet / TreeSet |
Map | X | 인덱스 번호 대신 key | key - X / value - O | HashMap / Hashtable / TreeMap |
이름에서도 티가 나듯 ArrayList는 배열의 특성을 가지고 있다
메모리에 연속적으로 등록하고 데이터의 삽입/삭제 시 내부에서 자동으로 배열 복사한다
데이터 저장은 연속적, 접근은 인덱스를 통해 한다
검색 속도가 빠른 장점과 데이터 추가/삭제 할땐 느리다는 단점이있다
import java.util.*;
public class ListTest {
public static void main(String[] args) {
//List 인터페이스를 구현한 하위 클래스 3개 : Vector, ArrayList, LinkedList
//3개 모두 사용문법은 거의 같음 단지 성능 차이
//List list = new List(); //error : 인터페이스는 직접 객체생성 불가
// List이터페이스를 구현한 하위클래스를 객체로 생성하여 사용
ArrayList<String> list = new ArrayList<>();
//[1]ArrayList클래스가 데이터를 제어하기 위해 만들어놓은 기능 (메소드) 실슴
//ArrayList는 내부적으론 배열이다
//->내부적으로 배열을 복사하는 것을 알아서 하는것뿐
//1. 요소의 개수 : .size()
int size = list.size();
System.out.println("요소 개수 : " + size);
//2. 요소의 추가 : .add()
String s = new String("hong");
list.add(s); //주소값 대입
list.add("kim");
list.add("ccc");
System.out.println("요소 개수 : " + list.size());
//3. 요소 얻어오기 : .get()
String s1 = list.get(0);
System.out.println(s1);
System.out.println(list.get(1)+"\n");
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//4. 요소 석제하기 : .remove()
list.remove(0);
System.out.println("요소 개수 : " + list.size());
System.out.println(list.get(0));
System.out.println(list.get(1)); //데이터 삭제 후 숏팅 자동으로 됨
System.out.println();
//5. 특정 위치에 요소 추가하기 : .add(index, element)
list.add(0, "ddd");
System.out.println("요소 개수 : " + list.size());
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
//6. 제거할때 인덱스 번호가 아니라 객체의 주소값(참조변수)로 제거 가능
String sss = new String("Test");
list.add(sss);
System.out.println("요소 개수 : " + list.size());
list.remove(sss);
System.out.println("요소 개수 : " + list.size());
System.out.println();
//7. 요소 모두를 한번에 깨끗이 제거 : .clear()
list.clear();
System.out.println("요소 개수 : " + list.size());
System.out.println();
//8. 리스트가 비어있는지 확인하는 메소드 : .isEmpty()
System.out.println(list.isEmpty());
System.out.println();
//9. 중복된 데이터 허용(특징)
list.add("aaa");
list.add("aaa");
list.add("aaa");
System.out.println("요소 개수 : " + list.size()); // => 3개
System.out.println();
//10. list 안에 특정 요소가 있는지 여부[true/ false] : .contains()
System.out.println(list.contains(sss));
System.out.println(list.contains("aaa"));
//11. *다른 리스트*의 요소들을 한 번에 추가하기 : .addAll()
list.clear();
list.add("aaa");
list.add("bbb");
list.add("ccc");
ArrayList<String> list2 = new ArrayList<>();
list2.add("sam");
list2.add("robin");
list.addAll(list2);
System.out.println("요소 개수 : " + list.size()); // => 5개
//12. 반복문 없이 단순히 요소값 console창에서 보고싶으면 toString() 기능 사용
System.out.println(list.toString()); //=> [aaa, bbb, ccc, sam, robin]
//13. 다른 리스트의 요소들과 같은 요소들을 모두 제거하기 : .removeAll()
ArrayList<String> list3 = new ArrayList<>();
list3.add("bbb");
list3.add("sam");
list.removeAll(list3);
System.out.println(list.toString()); // => [aaa, ccc, robin]
//14. 다른 리스트의 요소들과 같은 요소들만 남기고 나머지 모두 제거 : .retainAll()
ArrayList<String> list4 = new ArrayList<>();
list4.add("aaa");
list4.add("robin");
list.retainAll(list4);
System.out.println(list.toString()); // => [aaa, robin]
//15. 특정 요소들이 모두 포함되어 있는지 여부 : .containsAll()
ArrayList<String> list5 = new ArrayList<>();
list5.add("aaa");
list5.add("robin");
list5.add("kkk");
System.out.println(list.containsAll(list5));// => false
//16. 특정 요소가 몇번째에 있는지.. 인덱스 번호 리턴 :.indexOf()
System.out.println(list.indexOf("robin"));
System.out.println(list.indexOf("kim")); // => -1
list.add("aaa");
list.add("sss");
System.out.println(list.toString()); //=> [aaa, robin, aaa, sss]
System.out.println(list.indexOf("aaa")); // => 0
System.out.println(list.lastIndexOf("aaa")); // => 2
//17. 특정 요소값 변경 : set
list.set(0, "lee");
System.out.println(list.toString()); // => [lee, robin, aaa, sss]
System.out.println();
//18. 요소들을 순차적으로 얻어오기
//1) for문
for (int i = 0; i < list.size(); i++) {
String t = list.get(i);
System.out.println(t);
}
System.out.println();
//2) 확장포문
for(String t : list) {
System.out.println(t);
}
System.out.println();
//19. 경우에 따라서는 list를 배열로 변환하는 경우
//list를 배열로 변환
//toArray = 내부적으로 배열에 복사함
String[] arr = new String[list.size()]; //리스트 개수와 같은 크기 배열
list.toArray(arr); //리스트의 요소값을 배열에 복사
System.out.println(list.toString());
//배열객체의 요소값들을 문자열로 내보내는 static 메소드
System.out.println(Arrays.toString(arr));
//19-1. 배열 -> list
String[] bbb = new String[] {"sam", "bin", "hong"};
//ArrayList<String> list7 = (ArrayList<String>) Arrays.asList(bbb); //java.lang.ClassCastException
//오류 이유 => Arrays.asList 는 지가 진짜 ArrayList인지 LinkedList인지 뭔지 모름
//타입캐스팅을 해도 오류남
//때문에 그것의 조상인 List로 받아야함!
List<String> list7 = Arrays.asList(bbb);
System.out.println(list7.toString());
☝ Array와 ArrayList의 차이점
Array
- 데이터 삽입/삭제 시 위치를 직접 이동시켜야함
- 한번 정해진 배열의 크기변경은 불가함
ArrayList
- 데이터 삽입/삭제 시 위치 자동 이동
- 크기 변경이 유동적임
사용방법은 arrayList와 같음
성능의 차이가 있음 빈번하게 요소를 추가/삭제를 할때 속도가 빠르다 => ArrayList 성능이 지금은 많이 향상돼서 굳이 고민하지않고 그냥 arrayList쓴다
단점 : 특정 요소값을 얻어올 때는 느리다
특정요소를 찾아와 하면 그 위치로 바로 못가고 0번부터 찾아가야됨 -> 검색할때 시간 오래걸림
내부적으로 LinkedList은 실제로 옆에 있지않지만 preview와 next를 들고 있어서 연결된 거 처럼 있다
새로 추가 삭제되면 preview와 next의 주소값만 바꾸면 된다 => 속도가 빠름
LinkedList<String> linkList = new LinkedList<>();
linkList.add("aaa");
linkList.add("bbb");
linkList.add("ccc");
linkList.remove(1);
System.out.println(linkList.toString());
//LinkedList에만 있는 메소드
linkList.addFirst("sam");
linkList.addLast("robin");
System.out.println(linkList.toString());
ArrayList와 완전 같음
ArrayList와 딱 하나 다른점 -> 동기화 처리가 되어있다 -> add가 되는 도중 delete되는 것을 막을 수 있다
Vector<String> vector = new Vector<>();
vector.add("aaa");
System.out.println(vector.toString());
☝ 참고사항
ArrayList, LinkedList, Vector 클래스 모두 List 인터페이스를 구현한 클래스다
즉, List인터페이스는 위 3개클래스의 부모가 됨
부모참조변수로 자식객체를 참조할 수 있음 [up casting]
List<String> listL = null;
listL = new ArrayList<>();
listL = new LinkedList<>();
listL = new Vector<>();
//일부러 이렇게 쓰는 경우 많음 나중에 확장되거나 변경될 경우를 대비해서
순서 X, 인덱스 X, 중복 X
데이터 넣고 뺄땐 성능 최고, 성능이 가장 우수
값의 오름차순으로 저장되어짐 - 성능 중간쯤
내가 먼저 저장한 값보다 작으면 왼쪽 크면 오른쪽에 저장
읽을 땐 맨 앞에 있는 노드부터 읽음 (꼭지점 부터 읽는 거 아님)
import java.util.*;
public class SetTest {
public static void main(String[] args) {
//Set : 순서 X, 인덱스 X, 중복 X
//Set<String> set = new Set(); //error 인터페이스는 객체생성 불가
//Set인터페이스를 구현한 하위클래스
//HashSet, TreeSet , LinkedHashSet
//[1] HashSet
//데이터 넣고 뺄땐 성능 최고
//HashSet<String> set = new HashSet<>(); //성능이 가장 우수
//TreeSet<String> set = new TreeSet<>(); //값의 오름차순으로 저장되어짐 - 성능 중간쯤
//내가 저장한 값보다 작으면 왼쪽 크면 오른쪽에 저장
LinkedHashSet<String> set = new LinkedHashSet<>(); //값을 저장한 순서대로 - 성능 최하
//1. 요소추가
set.add("aaa");
set.add("eee");
set.add("ccc");
set.add("ddd");
set.add("bbb");
set.add("ccc"); //중복데이터를 추가해보기 - 무시됨
//2. 요소 출력 및 요소값 확인
System.out.println(set.size() + " : " + set.toString());
// => 5 : [aaa, ccc, bbb, eee, ddd]
//3. 요소값을 얻어오는 기능 .get() 이 없음
// set.get(); // error - why? 인덱스번호가 없어서 못찾아옴
//일반적으로는 set의 요소 하나를 얻어오기보다는
//모든 요소들을 순차적으로 얻어오는 경우가 많음
//순차적으로 요소값을 얻어오기
//1) for이용 불가! - 인덱스번호 없어서
//2) 확장 for 가능
for(String t : set) {
System.out.println(t);
}
System.out.println();
//3) iterator(반복자) 이용
Iterator<String> datas =set.iterator();
System.out.println(datas.next());
while(datas.hasNext()) {
String s = datas.next();
System.out.println(s);
}
System.out.println();
//4) 배열로 변환하여 접근
String[] aaa = new String[set.size()];
set.toArray(aaa); //index가 생겨서 for문 돌릴 수 있게됨
System.out.println(aaa[0]);
System.out.println(aaa[1]);
System.out.println(aaa[2]);
//사용자 정의 클래스를 set요소로 사용해보기
//중복 체크 될까?
HashSet<Person> p = new HashSet<>();
p.add(new Person("sam",20));
p.add(new Person("sam",20));
System.out.println(p.size()); //2개
//set은 중복값을 허용안하는데
//Set이 객체가 중복되었다고 판단하는 기준은.
//그 객체의 기능메소드 중 .hashCode()와 .equals()메소드의 결과가 같을때임.
HashSet<String> set2 = new HashSet<>();
set2.add(new String("aa"));
set2.add(new String("aa"));
System.out.println(set2.size());
}
}
class Person{
String name;
int age;
////////두개를 오버라이드 해서 만들면 내가 원하는 것으로 중복체크/////////
@Override
public int hashCode() {
return age;
}
@Override
public boolean equals(Object obj) {
Person p =(Person)obj;
return this.name.equals(p.name);
}
//////////////////////////////
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
Map : key - value 쌍(Entry라 부름)으로 데이터 저장
import java.util.*;
import java.util.Map.Entry;
public class MapTest {
public static void main(String[] args) {
//Map : key - value 상으로 데이터 저장 (Entry라 부름)
//Map도 인터페이스에서 바로 객체생성 불가능
//Map 인터페이스를 구현한 하위 클래스들
//HashMap, TreeMap, LinkedHashMap, HashTable
//[1] HashMap
//HashMap <key, value>
//가장 성능이 좋음
//HashMap<String, String> map = new HashMap<>();
//[2] TreeMap
//key값을 오름차순으로 저장
//성능 중간 정도
//TreeMap<String, String> map = new TreeMap<>();
//[3] LinkedHashMap
//저장된 순서 대로
//성능 최하
//TreeMap<String, String> map = new TreeMap<>();
//[4] HashTable
// HashMap과 동일 , 동기화 처리가 되어 있음
TreeMap<String, String> map = new TreeMap<>();
//1. 요소추가
map.put("name", "sam");
map.put("id", "abcd");
map.put("passWd", "1234");
map.put("kkk", "sam"); //데이타 중복, 키값 x => 추가
map.put("kkk", "hong"); //키값 중복되면 새로 추가되지 않고 그 위치값의 값이 변경됨
//2. 요소개수
System.out.println("요소 개수: "+map.size());
//3. 요소 얻어오기
System.out.println(map.get("name"));
System.out.println(map.get("id"));
System.out.println(map.get("passWd"));
System.out.println(map.get("kkk"));
System.out.println();
//4. 순서대로 요소값 출력
//1) for문 불가 - index번호 없어서
//2) 확장 for문 불가 - 내부적으로 key값을 제어할 방법이 없음
//3) 키 값들만 Set객체로 우선 얻어와서 반복문으로 처리
Set<String> keys = map.keySet();
//3.1) key들을 가진 Set 컬렉션 객체를 반복문으로 접근
for(String t : keys) {
System.out.println(map.get(t));
}
System.out.println();
//3.2) key들을 가진 Set 컬렉션 객체의 반복자 iterator 이용
Iterator<String> datas = keys.iterator();
while (datas.hasNext()) {
String k = datas.next();
System.out.println(map.get(k));
}
System.out.println();
//4) Map객체를 Set 객체로 변환하여 접근
//Map의 요소객체(키 - 밸류)인 Entry들을 가진 Set으로 변환
Set<Entry<String, String>> entries = map.entrySet();
for(Entry<String, String> t : entries) {
System.out.println(t.getKey()+ ":" + t.getValue());
}
//5. 요소삭제
map.remove("kkk");
System.out.println(map.toString());
System.out.println();
///////////////////////////////////////
//키값을 그냥 정수 숫자로 할 수도 있음
HashMap<Integer, String> map2 = new HashMap<>();
map2.put(1, "aaa");
map2.put(2, "aaa");
map2.put(3, "aaa");
//사용자 정의 클래스를 value로 사용 할 수 있음
HashMap<String, Person> map3 = new HashMap<>();
map3.put("사장", new Person("sam", 50));
map3.put("부장", new Person("kim", 50));
map3.put("과장", new Person("lee", 50));
}
}
가장 성능이 좋음
key값을 오름차순으로 저장, 성능 중간 정도
저장된 순서 대로, 성능 최하
HashMap과 동일 , 동기화 처리가 되어 있음
Collections Class의 유용한 static 기능 메소드
Collections.sort()와 Collections.shuffle()
import java.util.ArrayList;
import java.util.Collections;
public class CollectionsClass {
public static void main(String[] args) {
ArrayList<String> datas = new ArrayList<>();
datas.add("name");
datas.add("nice");
datas.add("hello");
datas.add("put");
datas.add("good");
datas.add("ios");
System.out.println(datas.toString());
//1) Collections.sort() : 오름차순 정렬
Collections.sort(datas);
System.out.println(datas.toString());
//2) Collections.shuffle() : 요소 뒤집기
//random 대신~쓰면 개 편함
Collections.shuffle(datas);
System.out.println(datas.toString());
}
}
메서드 | 설명 |
---|---|
hasNext() | 커서 다음 요소가 있는지 확인 |
next() | 커서 다음 요소 반환 후 다음으로 아동 |
remove() | 커서 다음 요소 삭제 |
ArrayList<String> list = new ArrayList<>();
interator<String> iter = list.interator();
while(iter.hasNext()){
system.out.println(iter.next());
}