반응형
List
- 데이터를 순서대로 저장하는 자료구조
- 자료구조에서는 배열을 Dense List 라고 하기도 합니다.
1.ArrayList(Vector 는 ArrayList의 Legacy 버전)
- 데이터를 물리적으로 연속해서 저장하는 List
- 크기 변경이 가능
- 제너릭이 구현(인스턴스를 만들 때 데이터 1개의 자료형을 확정을 해야 합니다.)
- 인스턴스를 만들 때 자료형을 확정하지 않으면 경고가 발생하고 데이터를 가져올 때 Object 타입으로 리턴되서 사용을 하고자 하면 강제 형 변환을 해야 합니다.
- Linked List 에 비해서 메모리 낭비가 적고 접근 속도가 빠릅니다.
- Linked List 에 비해서 데이터를 중간에 삽입하거나 삭제하는 경우 속도가 느립니다.
- Linked List는 논리적으로 연속해서 데이터를 저장
- 주요 메소드로는
boolean add(E e)
,E get(int index)
,int size()
,E remove(int index)
,void sort(Comparator<E>)
등이 있습니다.
2.LinkedList
- 데이터를 논리적으로(다음 데이터의 참조를 기억) 연속해서 저장하는 List
- 사용하는 모든 메소드가 ArrayList 와 같은데 동작 방식이 다름
3.ArrayList 와 LinkedList의 작업 속도 측정
public static void main(String[] args) {
//10 과 30을 갖는 ArrayList 생성
ArrayList<Integer> al = new ArrayList<>();
//데이터 삽입
al.add(10);
al.add(30);
//현재 시간 저장
long start = System.currentTimeMillis();
//20이라는 데이터를 10만번 2번째 칸에 삽입
for(int i=0; i<100000; i=i+1) {
al.add(1, 20);
}
//현재 시간 저장
long end = System.currentTimeMillis();
System.out.println("al:" + (end-start));
//LinkedList 생성
LinkedList<Integer> li = new LinkedList<>();
li.add(10);
li.add(30);
//현재 시간 저장
start = System.currentTimeMillis();
//20이라는 데이터를 10만번 2번째 칸에 삽입
for(int i=0; i<100000; i=i+1) {
li.add(1, 20);
}
//현재 시간 저장
end = System.currentTimeMillis();
System.out.println("li:" + (end-start));
//현재 시간 저장
start = System.currentTimeMillis();
//모든 데이터 읽어서 출력
for(int i=0; i<li.size(); i=i+1) {
System.out.println(li.get(i));
}
//현재 시간 저장
end = System.currentTimeMillis();
System.out.println("li:" + (end-start));
}
4.Vector
- ArrayList 가 만들어지기 전에 ArrayList와 동일한 용도로 사용하던 자료구조인데 데이터를 수정하거나 삭제할 때 다른 스레드가 사용 중인지 확인하고 작업을 수행하던 클래스
- java에서 Vector 클래스는 최근에는 거의 사용을 하지 않기 때문에 중요하지 않을 수 있는데 c++ 하던 분들이 ArrayList 라고 하지 않고 Vector라고 합니다.
5.Stack
- LIFO(Last In First Out)
- 마지막에 삽입된 데이터가 가장 먼저 출력되는 자료구조 클래스
- 데이터를 삽입하는 동작을 push 라고 하고 마지막 데이터를 꺼내는 동작을 pop 이라고 합니다.
- 실제 사용된 곳은 메소드를 호출할 때 메소드가 저장하는 자신의 데이터 영역을 Stack으로 만들고 스마트 폰 등에서 화면 저장도 Stack을 사용합니다.
- 삽입은 E push(E e), 삭제는 E pop(), 삭제하지 않고 마지막 데이터를 가져오는 E peek()
- 제너릭이 적용되어 있어서 인스턴스를 만들 때 저장할 요소의 자료형을 설정해야 합니다.
public static void main(String[] args) {
//문자열 저장하는 스택 생성
Stack <String> stack = new Stack<>();
//데이터 저장은 push
stack.push("안중근");
stack.push("윤봉길");
stack.push("김좌진");
//마지막 데이터 제거하면서 가져오기
String human = stack.pop();
System.out.println(human);
//마지막 데이터를 제거하지 않고 가져오기
human = stack.peek();
System.out.println(human);
human = stack.peek();
System.out.println(human);
}
- Stack 의 size를 설정한 경우에 Stack에 이미 데이터가 전부 저장된 상태에서 데이터를 push 하는 경우를 Stack Overflow 라고 합니다.
- Stack에서 데이터가 없는 상태에서 pop을 하는 경우를 Stack Underflow 라고 합니다.
6.Queue
- FIFO(First In First Out)
- 먼저 삽입된 데이터를 먼저 제거하는 자료구조
- 자바에서는 인터페이스로 제공되고 여러 List 클래스에 구현되어 있습니다.
- PriorityQueue 라는 우선순위 큐에도 구현되어 있습니다.
- 우선순위 큐는 우선순위에 따라 데이터를 정렬하고 있는 큐입니다.
- 데이터를 삽입하는 메소드는 add 이고 데이터를 꺼내는 메소드는 peek 와 poll
- 용도는 스케줄링에 주로 이용
- 입력받은 내용을 순서대로 실행하고자 할 때 Queue를 이용합니다.
public static void main(String[] args) {
//우선 순위 큐: 데이터를 크기 순서대로 접근할 수 있도록 만든 큐
//내부적으로 데이터가 정렬된 것이 아니고 정렬된 순서대로 접근할 수 있는 이진 트리를 생성
PriorityQueue<String> pq =
new PriorityQueue<>();
pq.add("서울");
pq.add("런던");
pq.add("크라이스처치");
pq.add("블라디보스톡");
pq.add("불산");
//빠른 열거를 이용해서 데이터를 1개씩 꺼내와서 출력
//트리의 순회를 이용하지 않기 때문에 데이터가 정렬된 순서가 아닐 수 있음
for(String city : pq) {
System.out.print(city + "\t");
}
System.out.print("\n");
//지우면서 가져올 때는 데이터의 개수나 인덱스가 변할 수 있으므로 주의
int len = pq.size();
//데이터를 poll을 이용해서 1개씩 가져와서 출력
//트리의 순회를 이용하기 때문에 데이터가 정렬된 순서대로 출력
for(int i=0; i<len; i=i+1) {
System.out.print(pq.poll() + "\t");
}
}
7.Deque
- 양쪽에서 삽입과 삭제가 가능한 자료구조
- 자바에서는 인터페이스 형태로 제공
- ArrayDeque 라는 클래스가 Deque 인터페이스를 implements
- Deque를 구현한 경우는 ScrollView 계열이 전부 Deque를 이용합니다.
- 삽입하거나 꺼내는 메소드 이름들에 First 와 Last 가 붙습니다.
ArrayDeque <String> deque = new ArrayDeque<>();
//데이터를 앞에서 저장
deque.addFirst("한국");
//데이터를 뒤에 저장
deque.addLast("미국");
deque.addLast("중국");
deque.addFirst("뉴질랜드");
- 저장 순서는 뉴질랜드 -> 한국 -> 미국 -> 중국
String nation = deque.pollFirst(); //뉴질랜드
nation = deque.pollLast(); //중국
8.사용자 정의 클래스의 List 정렬
- 사용자 정의 클래스의 List 가 테이블 구조
public static void main(String[] args) {
//매개변수가 없는 생성자를 이용한 인스턴스 생성 및 필드 값 설정
Player player1 = new Player();
player1.setNum(1);
player1.setName("백인천");
player1.setHitrate(0.412);
//매개변수가 있는 생성자를 이용한 인스턴스 생성 및 필드 값 설정
Player player2 = new Player(2, "이종범", 0.393);
Player player3 = new Player(3, "장효조", 0.387);
Player player4 = new Player(4, "테임즈", 0.381);
Player player5 = new Player(5, "최형우", 0.376);
//5개의 인스턴스를 소유한 ArrayList 인스턴스 생성
ArrayList<Player> list = new ArrayList<>();
list.add(player1);
list.add(player2);
list.add(player3);
list.add(player4);
list.add(player5);
//Player 클래스의 인스턴스 비교 인스턴스 : 타율의 오름차순
Comparator <Player> comparator =
new Comparator<Player>() {
@Override
public int compare(Player arg0, Player arg1) {
/*
if(arg0.getHitrate() > arg1.getHitrate()) {
return 1;
}else if(arg0.getHitrate() == arg1.getHitrate()) {
return 0;
}else {
return -1;
}
*/
return arg0.getName().compareTo(arg1.getName()) * -1;
}
};
//데이터 정렬
list.sort(comparator);
//데이터 출력
for(Player player : list) {
System.out.println(player);
}
}
Set
- 데이터를 해싱을 이용해서 저장위치를 선정하고 중복된 데이터는 저장하지 않는 자료구조
- 데이터의 저장 순서를 모르기 때문에 인덱스의 개념이 없습니다.
- 제너릭이 구현 : 인스턴스를 만들 때 요소의 자료형을 결정
1.구현된 클래스
- HashSet: 저장 순서를 알 수 없는 Set
- LinkedHashSet: 저장 순서를 알 수 있는 Set 으로 전체를 순서대로 접근하면 저장된 순서대로 리턴
- TreeSet: Comparator 인터페이스의 compareTo 메소드를 이용해서 크기 순서대로 리턴하는 Set
2.주요 메소드
boolean add(E e)
: 데이터를 추가하고 성공 여부를 리턴, 동일한 값의 데이터를 삽입할려고 하면 데이터를 삽입하지 않고 false를 리턴boolean remove(E e)
: e에 해당하는 데이터가 있으면 삭제하고 결과를 리턴int size()
: 데이터 개수 리턴데이터 1개를 접근하는 메소드는 없고 for(임시변수 : Set) 을 이용해서 데이터 전체를 접근
3.Set 사용
public static void main(String[] args) {
//Set 인스턴스 생성 - HashSet, LinkedHashSet, TreeSet 으로 변경하면서 확인
Set<Integer> set = new TreeSet<Integer>();
//Set에 데이터 추가
set.add(100);
set.add(300);
set.add(200);
set.add(500);
set.add(400);
//데이터 전부 출력
for(Integer temp : set) {
System.out.println(temp);
}
}
4.1-45 사이의 숫자를 6개 입력받아서 오름차순 정렬해서 출력
- 데이터 6개는 하나의 이름으로 저장
- 동일한 데이터는 입력받지 않아야 합니다.
- 데이터는 오름차순 정렬
- 데이터 6개를 하나의 이름으로 저장할 수 있는 자료구조: 배열, ArrayList, LinkedList, Stack, PriorityQueue, ArrayDeque, HashSet, LinkedHashSet, TreeSet
Map
- Key 와 Value를 쌍으로 저장하는 자료구조
- Key는 중복될 수 없지만 Value는 중복되거나 null 일 수 있습니다.
- 미지정 자료형이 2개라서 인스턴스를 생성할 때 Key 와 Value 자료형 2개를 설정해야 합니다.
- Key는 특별한 경우가 아니라면 String
- 여러 종류의 데이터를 하나로 묶기 위한 용도로 주로 이용
- DTO 클래스의 용도와 유사
- 관계형 데이터베이스의 테이블은 DTO 클래스의 List 이고 No SQL의 Collection 은 Map의 List 입니다.
- Map은 Key를 무한정 추가시킬 수 있습니다.
- DTO 클래스는 클래스를 만들 때 사용한 필드를 제외하고는 확장이 안됩니다.
1.Map 구현 클래스
1) HashMap(Hashtable): Key를 해싱에의해서 저장하기 때문에 Key의 순서를 알 수 없습니다.
2) LinkedHashMap: Key가 데이터를 저장한 순서대로 배치
3) TreeMap: Key가 compareTo 메소드를 이용해서 비교한 후 크기 순서대로 배치
2.인스턴스 생성
HashMap<String, 실제데이터의 자료형> map = new HashMap<String, 실제데이터의 자료형>();
3.데이터 관련 메소드
void put(key, value)
: key 값에 value를 저장, 동일한 key 이름을 입력하면 수정Object get(key)
: key에 해당하는 값 리턴, key가 없으면 null 리턴- 리턴되는 데이터가 Object 라서 출력하는 것이 아니고 사용할 거라면 저장할 때의 자료형으로 강제 형 변환해서 사용
Object remove(key)
: key에 해당하는 데이터 삭제Set<Key의 자료형> keyset()
: Map 의 모든 key를 Set으로 리턴
4.Map의 기본 사용 방법
public static void main(String[] args) {
//Map 인스턴스 생성
HashMap<String, Object> map =
new HashMap<String, Object>();
//데이터 저장
map.put("baseball", "야구");
map.put("soccer", "축구");
map.put("volleyball", "배구");
//데이터 가져오기 - 출력만 할 때는 강제 형 변환이 필요없지만 다른 용도로 사용할 때는 강제 형 변환을 해서 가져옵니다.
String obj = (String)map.get("soccer");
System.out.println(obj.toUpperCase());
//없는 key의 값 가져오기 - 언어마다 다르므로 확인
Object value = map.get("basketball");
System.out.println(value);
//동일한 key에 데이터를 삽입하면 업데이트
map.put("soccer", "발로 하는 축구");
obj = (String)map.get("soccer");
System.out.println(obj.toUpperCase());
//Map의 모든 데이터를 출력 - key의 이름을 사용하지 않음
System.out.println("=============================");
//모든 key의 값을 가져오기
Set<String> keys = map.keySet();
//Set을 순회
for(String key : keys) {
System.out.println(key + ":" + map.get(key));
}
}
5.Class 와 Map을 이용한 저장의 차이
public static void main(String[] args) {
//번호, 이름, 타율을 저장하는 Player 클래스의 인스턴스를 만들어서 데이터를 저장
Player player = new Player(1, "이종범", 0.393);
//3개를 저장하는 Map을 인스턴스를 생성해서 데이터를 저장
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("num", 2);
map.put("name", "장효조");
map.put("hitrate", 0.387);
//대부분의 IDE에서 일반 인스턴스를 사용할 때 Code Sense가 동작
//하나의 속성을 가져올 때는 클래스가 유용
//map은 key를 기억해야 합니다.
String name = player.getName();
name = (String)map.get("name");
//전체를 출력할 때나 속성을 확장할 때는 Map이 유리
//DTO 클래스의 인스턴스는 속성 확장이 안됩니다.
//DTO 클래스의 인스턴스는 속성을 확장할려면 클래스 구조를 변경해야 합니다.
//map은 제한이 없음
map.put("homerun", 31);
//DTO 클래스의 인스턴스는 각각의 데이터를 하나씩 출력해야 한다면 메소드를 일일이 호출: 반복문 사용 불가
System.out.println(player.getNum());
System.out.println(player.getName());
System.out.println(player.getHitrate());
//Map의 인스턴스는 keySet()을 이용해서 반복문으로 출력 가능
//모든 Map은 아래 구문으로 전체 데이터를 출력할 수 있습니다.
Set<String> keys = map.keySet();
for(String key:keys) {
System.out.println(key + ":" + map.get(key));
}
}
6.List의 List(Matrix - numpy) 와 Map의 List(DataFrame - pandas)
public static void main(String[] args) {
//각 팀별 선수명단
ArrayList<String> kia = new ArrayList<String>();
kia.add("최형우");
kia.add("김주찬");
kia.add("김선빈");
ArrayList<String> dusan = new ArrayList<String>();
dusan.add("권혁");
dusan.add("정수빈");
dusan.add("최주환");
ArrayList<String> hanhwa = new ArrayList<String>();
hanhwa.add("김태균");
hanhwa.add("이성열");
//팀별 명단을 다시 List로 만들기
ArrayList<ArrayList<String>> players =
new ArrayList<ArrayList<String>>();
players.add(kia);
players.add(dusan);
//팀이 추가되는 경우 팀 이름을 출력하기 위해서 출력하는 로직을 수정
players.add(hanhwa);
//데이터 출력하기
//전체 리스트를 하나 하나의 리스트로 imsi에 대입
for(int i=0; i<players.size(); i=i+1) {
if(i == 0) {
System.out.print("기아:");
}else {
System.out.print("두산:");
}
ArrayList<String> imsi = players.get(i);
//imsi 의 데이터를 하나씩 temp에 대입
for(String temp : imsi) {
System.out.print(temp + "\t");
}
System.out.print("\n");
}
System.out.println("============================");
//앞에서의 문제는 List 의 List를 만들 때 각 List의 특징을 같이 저장하지 못한다는데 있습니다.
//팀이름은 문자열이고 팀의 선수 명단은 배열이라서 같이 List에 저장을 못합니다.
//이 부분을 Map이나 Class로 해결해야 합니다.
//List 와 팀이름을 갖는 Map을 생성
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("team", "기아");
map1.put("player", kia);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("team", "두산");
map2.put("player", dusan);
Map<String, Object> map3 = new HashMap<String, Object>();
map3.put("team", "한화");
map3.put("player", hanhwa);
//Map의 List를 생성
ArrayList<Map<String, Object>> kbo =
new ArrayList<Map<String, Object>>();
kbo.add(map1);
kbo.add(map2);
kbo.add(map3);
//출력하는 부분
for(Map<String, Object> map : kbo) {
System.out.print(map.get("team") + ":");
ArrayList<String> p = (ArrayList<String>)map.get("player");
for(String temp : p) {
System.out.print(temp + "\t");
}
System.out.print("\n");
}
}
7.데이터 저장
1) 하나의 행은 Map 이나 DTO 클래스를 이용
- Map이나 DTO 클래스는 서로 다른 자료형의 데이터를 묶어서 저장이 가능합니다.
- List 나 배열은 동일한 종류의 데이터를 묶어줍니다.
- List 나 배열로는 특성이 다른 데이터를 묶을 수 없습니다.
2) 하나의 열을 만들 때 List 나 배열을 사용
- 열 방향의 데이터는 일반적으로 동일한 자료형으로 구성되기 때문입니다.
MVC(Model - View - Controller) 패턴
- 애플리케이션을 구현할 때 역할 별로 분리해서 구현하도록 하는 패턴
- 애플리케이션을 역할 별로 잘 구별해서 분리하지 않으면 어느 하나의 변경이 다른 하나의 변경에 영향을 미치게 됩니다.
- 유지보수가 어려워집니다.
- Model에 변화가 생기더라도 View를 변경하지 않아도 되도록 구현하라는 패턴
반응형
'Language_Study > JAVA' 카테고리의 다른 글
[JAVA, App] 15.MutualExclusion (0) | 2020.12.27 |
---|---|
[JAVA, App] 14.기본API클래스 (0) | 2020.12.27 |
[JAVA, App] 12.Interface (0) | 2020.12.25 |
[JAVA, App] 11.Package (0) | 2020.12.25 |
[JAVA, App] 10.예외처리 (0) | 2020.12.25 |