문법/기본 문법
컬렉션
코딩 화이팅
2023. 1. 27. 14:54
- 객체들을 한 곳에 모아두고 편리하게 사용할 수 있는 환경을 제공
정적 자료구조
- 배열이 대표적인 정적 자료구조
- 고정된 크기의 자료구조
동적 자료구조
- 요소의 개수에 따라 자료구조의 크기가 동적으로 증가하거나 감소
- ex) 리스트 스택 큐 등
Collection Interface
package test01_list;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
public class test01 {
public static void main(String[] args) {
// List
// 순서(index)가 있는 자료구조 / 중복 허용
// List<String> names = new ArrayList<>();
// List<String> names = new LinkedList<>();
List<String> names = new Vector<>();
// 원소 추가
names.add("안중근");
names.add("이봉창");
names.add("이순신");
names.add(0, "이순신");// 0번 인덱스에다가 선언
System.out.println(names);
// 비었는지 확인
System.out.println(names.isEmpty());
// 원소의 갯수
System.out.println(names.size());
// 인덱스 수정
names.set(2, "세종대왕");
System.out.println(names);
// 조회
for (String name : names) {
System.out.println(names);
}
// 반복자 사용
Iterator<String> e = names.iterator();
while (e.hasNext()) {//다음 원소가 있다면
System.out.println(e.next());//그 다음 원소를 출력한다.
}
// 삭제
names.remove(2);
System.out.println(names);
// 값 삭제
names.remove("이순신");
System.out.println(names);
// 전부 삭제
names.clear();
System.out.println(names);
names.add("강현");
names.add("강현");
names.add("현강");
for (int i = 0; i < names.size(); i++) {
System.out.println(names.get(i));//get-특정 인덱스에 있는것을 가져온다
}
// 강현 삭제하고싶다
// for (int i = 0; i < names.size(); i++) {//크기가 동적으로 변하므로 names.size가 변한다. 따라서 한개의 강현밖에 안 사라짐
// if (names.get(i).equals("강현")) {
// names.remove(i);
// }
// }
for (int i = names.size() - 1; i >= 0; i--) {// 뒤에서부터 지우면 강현을 다 지울 수 있다. / 때로 뒤에서부터 수행해야 할 때가 있다.
if (names.get(i).equals("강현")) {
names.remove(i);
}
System.out.println(names);
}
}
}
//ArrayList, LinkedList, Vector 성능 비교
//추가, 수정, 조회
package test01_list;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;
public class test02 {
public static void main(String[] args) {
List<Object> al= new ArrayList<Object>();
List<Object> ll= new LinkedList<Object>();
List<Object> v = new Vector<Object>();
test1("순차적 추가 - ArrayList -", al);
test1("순차적 추가 - LinkedList -", ll);
test1("순차적 추가 - Vector -", v);
test2("중간에 추가 - ArrayList -", al);
test2("중간에 추가 - LinkedList -", ll);
test2("중간에 추가 - Vector -", v);
test3("데이터 조회 - ArrayList -", al);
test3("데이터 조회 - LinkedList -", ll);
test3("데이터 조회 - Vector -", v);
}
public static void test1(String testname, List<Object> list) {
long start=System.nanoTime(); //시작 시간
for (int i = 0; i < 50000; i++) {
list.add(new String("Hello"));//뒤에다가 추가
}
long end=System.nanoTime(); // 끝 시간
System.out.printf("%s \t 소요시간:%15d ns. \n", testname, end-start);
}
public static void test2(String testname, List<Object> list) {
long start=System.nanoTime(); //시작 시간
for (int i = 0; i < 50000; i++) {
list.add(0, new String("Hello")); //맨 앞에다가 추가(중간에 추가)
}
long end=System.nanoTime(); // 끝 시간
System.out.printf("%s \t 소요시간:%15d ns. \n", testname, end-start);
}
public static void test3(String testname, List<Object> list) {
long start=System.nanoTime(); //시작 시간
//리스트에 있는 모든 원소 조회
for (int i = 0; i < list.size(); i++) {
list.get(i);
}
long end=System.nanoTime(); // 끝 시간
System.out.printf("%s \t 소요시간:%15d ns. \n", testname, end-start);
}
}
/*
순차적 추가 - ArrayList - 소요시간: 3520200 ns.
순차적 추가 - LinkedList - 소요시간: 1914000 ns.
순차적 추가 - Vector - 소요시간: 1787000 ns.
중간에 추가 - ArrayList - 소요시간: 590436100 ns.
중간에 추가 - LinkedList - 소요시간: 2414300 ns.
중간에 추가 - Vector - 소요시간: 595096300 ns.
데이터 조회 - ArrayList - 소요시간: 3247300 ns.
데이터 조회 - LinkedList - 소요시간: 4176980200 ns.
데이터 조회 - Vector - 소요시간: 4165700 ns.
*/
List
- 순서가 있고, 중복을 허용(배열과 유사)
- 구현 클래스 : ArrayList / LinkedList / Vector
- 내부적으로 배열을 이용하여 데이터를 관리(ArrayList, Vector)
- 배열과 다르게 크기가 유동적으로 변함(동적 자료구조)
ArrayList
- 장점 : 가장 기본적인 형태의 자료구조, 간단하며 사용이 쉬움 / 접근 속도가 빠름 / 조회할 때 빠름
- 단점 : 크기를 변경할 수 없어 데이터를 위해 새로운 배열을 만들고 복사해야함. / 비 순차적 데이터의 추가, 삭제에 많은 시간이 걸림 / 추가와 삭제에 불리하다.
LinkedList
- 각 요소를 Node로 정의하고 Node는 다음 요소의 참조 값과 데이터로 구성됨
- 각 요소가 다음 요소의 링크 정보를 가지며 연속적으로 구성될 필요가 없음
- 장점 : 추가 삭제에서 유리
- 단점 : 조회에서 불리
package test02_set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class test01 {
public static void main(String[] args) {
//set
//집합을 나타내는 자료구조
//중복을 허용X
//순서도 없음
Set<String> set = new HashSet<>();//해쉬 테이블에 원소를 저장 / 성능면에서 우수 / 원소들의 순서가 일정하지 않다
// Set<String> set = new TreeSet<>();//red-black tree에 원소 저장 / 값에 따라서 순서가 결정 / 값을 순서대로 정렬할 필요가 있다면 고려해볼만한 선택지
set.add("강현");
set.add("강현");
set.add("강현일");
set.add("강현이");
System.out.println(set);
System.out.println("강현".hashCode());//고유한 정수값으로 나타낸 것
System.out.println("강".hashCode());
System.out.println(new String("강현").hashCode());//같은 문자열이면 같은 해쉬코드가 나온다.
System.out.println("강현".equals("강현"));//해시코드가 같다면 equals 메소드에 참 출력
//반복자
Iterator<String> e=set.iterator();
while (e.hasNext()) {
System.out.println(e.next());
}
}
}
//HashSet일 때
[강현이, 강현, 강현일]
1420431
44053
1420431
true
강현이
강현
강현일
//TreeSet일 때
[강현, 강현이, 강현일]
1420431
44053
1420431
true
강현
강현이
강현일
package test02_set;
import java.util.HashSet;
import java.util.Set;
public class test02 {
public static void main(String[] args) {
Set<person> set=new HashSet<>();//hashcode, equals 두개가 같아야 같은 걸로 봄
person p1=new person("강현", "980821");
person p2=new person("강현", "980821");
set.add(p1);
set.add(p2);
System.out.println(p1.hashCode());
System.out.println(p2.hashCode());
System.out.println(p1.equals(p2));
System.out.println(set);
}
}
===============================================================
package test02_set;
public class person {
private String name;
private String id;
public person(String name, String id) {
super();
this.name = name;
this.id = id;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.id.hashCode();//해시코드를 리턴한다.
}
@Override
public boolean equals(Object obj) {
if (obj instanceof person) {//만약 obj가 person 클래스의 객체라면
person other=(person) obj; //other라는 변수에 obj를 person클래스로 형변환해서 선언
return this.id.equals(other.id);//id만 같다면 equals해라
}
else {
return false;
}
}
@Override
public String toString() {
return "person [name=" + name + ", id=" + id + "]";
}
}
Set
- 순서가 없고, 중복을 허용하지 않음
- 장점 : 빠른 속도, 효율적인 중복 데이터 제거 수단
- 단점 : 단순 집합의 개념으로 정렬하려면 별도의 처리가 필요하다.
- 구현 클래스 : HashSet / TreeSet
package test03_map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;
public class test01 {
public static void main(String[] args) {
//map
//사전과 같은 자료구조
//키&값 쌍으로 저장
//키로 구별
//키는 중복X
//값은 중복 가능
Map<String, String> map=new HashMap<>();
// Map<String, String> map=new TreeMap<>();
//맵에 값 저장
map.put("강", "010-1234-1234");
map.put("현", "010-1111-1111");
map.put("강현", "010-2222-2222");
//중복된 키로 값을 넣을 경우 새로운 값으로 대체
map.put("강현", "010-3333-3333");
System.out.println(map);
//값을 가져오는 것
System.out.println(map.get("강"));
//없는 키로 값을 가져온다면
System.out.println(map.get("현강"));
//키가 있는지 미리 확인
System.out.println(map.containsKey("현강"));
//값이 있는지 확인
System.out.println(map.containsValue("010-3333-3333"));
//반복문
for(Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+" : "+entry.getValue());
}
//
현 : 010-1111-1111
강 : 010-1234-1234
강현 : 010-3333-3333
Iterator<String> e=map.keySet().iterator();
while (e.hasNext()) {
String key=e.next();
System.out.printf("키: %s, 값: %s \n", key, map.get(key));
}
for(String key:map.keySet()) {
System.out.printf("키: %s, 값: %s \n", key, map.get(key));
}
//
키: 현, 값: 010-1111-1111
키: 강, 값: 010-1234-1234
키: 강현, 값: 010-3333-3333
키: 현, 값: 010-1111-1111
키: 강, 값: 010-1234-1234
키: 강현, 값: 010-3333-3333
System.out.println(map.size());//키의 갯수
}
}
Map
- Key와 value를 하나의 Entry로 묶어서 데이터 관리, 순서는 없으며, 키에 대한 중복은 없음
- 장점 : 빠른 속도
- 구현 클래스 : HashMap, TreeMap
Queue(큐)
- 인터페이스, 구현체는 LinkedList를 사용
- 큐 자료구조 : FIFO, 가장 먼저 들어온거부터 빠져나감
Stack
- 스택 클래스를 사용
- 스택 자료구조 : LIFO, 가장 나중에 들어온 값이 가장 먼저 빠져나감
package test06_sort;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class test01 {
public static void main(String[] args) {
String[] arr= {"samsung", "sofyware", "academy", "for", "youth"};
List<String> list=Arrays.asList(arr);
System.out.println(list);
//[samsung, sofyware, academy, for, youth]
//cf.Arrays.sort
//collection을 정렬할 때는
//collection.sort()
Collections.sort(list);
System.out.println(list);
//[academy, for, samsung, sofyware, youth]
}
}
정렬
- 요소를 기준에 대한 내림차순 또는 오름차순으로 배치하는 것
- 순서를 가지는 Collection들만 정렬 가능
List 계열
Set에서는 SortedSet의 자식 객체
Map에서는 SortedMap의 자식 객체(Key 기준) - Collection의 sort()를 이용한 정렬
객체가 Comparable을 구현하고 있는 경우 내장 알고리즘을 통해 정렬
Comparable interface
package test07_comparable;
//Collections.sort를 사용하고 싶으면 해당 클래스가 comparable 인터페이스를 구현해야한다.
public class person implements Comparable<person>{
private String name;
private String id;
public person(String name, String id) {
super();
this.name = name;
this.id = id;
}
@Override
public int hashCode() {
// TODO Auto-generated method stub
return this.id.hashCode();
}
@Override
public boolean equals(Object obj) {
if (obj instanceof person) {
person other=(person) obj;
return this.id.equals(other.id);
}
else {
return false;
}
}
@Override
public String toString() {
return "person [name=" + name + ", id=" + id + "]";
}
//compareTo
//양수 : 자리를 바꿈
//음수 : 그대로
//0 : 그대로
@Override
public int compareTo(person o) {
//이름 순으로 정렬(String의 메서드를 이용)
// return this.name.compareTo(o.name);
//나이 순으로
return Integer.parseInt(o.id)-Integer.parseInt(this.id);
}
}
==============================================================
package test07_comparable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class test01 {
public static void main(String[] args) {
List<person> list=new ArrayList<person>();
list.add(new person("강","980822"));
list.add(new person("현","990823"));
list.add(new person("현강","970824"));
Collections.sort(list);
System.out.println(list);
}
}
//
[person [name=현, id=990823], person [name=강, id=980822], person [name=현강, id=970824]]
Comparator Interface
package test08_comparator;
import java.util.Comparator;
public class ageComparator implements Comparator<person>{
@Override
public int compare(person o1, person o2) {
return Integer.parseInt(o1.getId())-Integer.parseInt(o2.getId());
}
}
==============================================================
package test08_comparator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class test01 {
public static void main(String[] args) {
List<person> list=new ArrayList<person>();
list.add(new person("강","990822"));
list.add(new person("현","908823"));
list.add(new person("현강","980824"));
Collections.sort(list, new ageComparator());
System.out.println(list);
}
}