1. 자료구조
: 프로그램에서 데이터를 처리하기 위해 만든 구조
-> Array, List, Map, [Tuple, Dictionary]
1) 배열 (Array)
-하나의 변수명으로 여러개의 데이터를 처리가능
-데이터를 순차적으로 저장 [0부터 시작하는 인덱스로 접근]
- 고정된 크기
- 데이터의 위치를 모르는 경우 효율이 떨어짐.
- 모두 동일한 자료형인 데이터
- 배열 중간에 값을 추가 -> 기존 데이터를 모두 이동해야 한다.
-> 따라서 배열보다 List를 더 많이 사용
2) 리스트 (List)
-배열과 유사한 순차적 자료구조
-배열의 모든 문제점을 해결한 자료구조
- 고정되지 않은 크기
- 다양한 데이터 핸들링 방법
- 서로 다른 타입의 데이터 가능하지만 -> 관리가 어려워 보통은 동일한 타입
- 배열 중간에 값을 추가하거나 삭제하기 쉬움.
- 특정 데이터가 포함 여부 확인 가능 -> 검색을 위해서는 별도 구현이 필요.
리스트의 종류
(1) Linked List
-불연속적으로 존재하는 데이터를 서로 연결할 수 있는 방법을 제공
(2) Double Linked List
-이전과 다음 데이터 정보를 모두 가지고 있는 형태
-> 자바의 경우 LinkedList 클래스가 제공되는데 Double Circular Linked List(순환구조가 추가된 Double Linked List) 형태를 구현
3) 맵(Map)
:Key:Value(키:값)의 쌍으로 저장하는 방식의 자료구조
실제 데이터가 저장되는 형태는 내부구조에 따르며 사용하는 쪽에서는 내부구조에 대해 신경쓸 필요가 없는 형태
- 데이터를 저장할 때 해당 데이터를 찾기 위한 Key를 부여.
- Key값을 알면 언제든 쉽게 데이터를 찾을 수 있음.
- Value 에 객체형이 들어갈 수 있어 복잡한 데이터 처리가 가능.
-> 학생들의 성적을 관리하는 자료구조를 만들때 학생별 성적을 List 로 만들고 학번을 Key 로 하는 Map 을 만들어 List 를 저장하면 학번을 통해 손쉽게 성적관리가 가능
4) 이터레이터 (Iterator)
: 서로다른 자료구조(Vector, ArrayList, LinkedList)의 데이터를 동일한 방법으로 다음 데이터에 접근하는 방법을 제공하는 인터페이스
2. 컬렉션 프레임워크
자바에서 데이터를 저장하는 클래스들을 표준화한 설계 구조
인터페이스 | 설 명 | 특 징 | 대표 구현 클래스 |
List | 순서가 있는 데이터의 집합. | 데이터의 중복을 허용 | ArrayList, LinkedList |
Set | 순서를 유지하지 않는 데이터의 집합. | 데이터의 중복을 허용하지 않음 | HashSet, LinkedHashSet |
Map | 키(key)와 값(value)의 쌍으로 이루어진 데이터 집합. | 순서 유지 X, 키 중복 X, 값 중복 O | HashMap, LinkedHashMap, Properties |
Collection 인터페이스
: List와 Set의 상위 인터페이스
-> Collection 인터페이스의 메서드만 사용가능 [구현클래스와 상관없이 동일한 방법으로 데이터 핸들링 가능]
-> 타입이 다른 경우 일관된 처리가 어려워 타입 파라미터 사용
Collection<String> c = new HashSet<>();
- 순서가 없고 데이터 중복을 허용하지 않는 자료구조인 HashSet 객체 생성.
- 저장되는 데이터는 문자열로 한정.
- 원래는 new HashSet<String>(); 이지만 타입추론을 통해 생략 가능.
컬랙션 객체의 생성
-> java.util 패키지
컬랙션 객체
- 참조변수 선언 : 상위 인터페이스 타입을 사용
- 객체 생성 : 필요에 따라 구체적인 클래스들을 사용
List<Type_Name> (list_Name) = new ArrayList<>();
Collection<String> c1 = new HashSet<>();
//객체 : HashSet 생성
//데이터 : add() 통해 삽입
Collection<String> c2 = Arrays.asList("three", "four");
//객체 : 두 개의 데이터를 가지는 List 생성
Collection<String> c3 = Collections.singleton("five");
//객체 : 데이터가 하나인 유일한 인스턴스를 보장하는 Set 생성
컬랙션에 데이터 추가 및 삭제
데이터 추가 : add(), addAll() 메서드
add() : 지정된 타입의 데이터 하나씩 추가
addAll() 컬렉션 타입 추가하기 위해 개별 원소를 꺼내어 추가
c1.add("one");
c1.addAll(c2);
데이터의 삭제 : remove(), removeAll(), retainAll(), clear() 메서드
retainAll() : 인자의 데이터를 제외한 나머지 데이터 모두 삭제
clear() : 모든 데이터를 삭제
c1.remove("one");
c1.remove("c2");
c1.retainAll("four");
c1.clear();
컬랙션 데이터 확인 및 변환
: 특정 데이터의 존재 여부 확인 / 크기 확인 가능
c1.isEmpty();
c1.contains("zero");
c1.containsAll(c2);
컬랙션 데이터 크기 : size() 메서드
데이터 변환 : toArray() 메서드
-> Object 타입으로 리턴 되므로 특정 타입을 원한다면 해당 객체 생성 코드가 필요하다.
(Type_Name)[] (Object_Name) = (Instance_Name).toArray(new (Type_Name)[(Instance_Name).size()]);
int size = c1.size();
Object[] converted1 = c1.toArray();
String[] converted2 = c1.toArray(new String[c1.size()]);
컬랙션 데이터 사용
: 컬랙션은 구체적인 구현이 아니므로 직접적인 데이터의 접근을 위해서는 다른 방법이 필요
-> List, Set 인터페이스를 이용해 처리 / Collection 인터페이스 타입으로 처리
a) 배열로 변환해 for문과 사용
: 순차적으로 데이터를 사용하는 경우 : for문 사용
for(String s : c1) {
System.out.println(s);
}
-> 특정 위치의 데이터 : toArray() 메서드를 이용해 배열로 변환해 사용
(배열 데이터는 인덱스로 접근 가능하므로)
String[] converted2 = c1.toArray(new String[c1.size()]);
for(int i=0; i < converted2.length; i++) {
System.out.println(converted2[i]);
}
b) Iterator를 사용
: 다음 데이터에 접근하는 방법을 제공하는 인터페이스
Collection 인터페이스는 Iterable 인터페이스를 상속받고, Iterator() 메서드로 Iterator 객체를 구할 수 있습니다.
-> 획득한 데이터를 조작하거나 다른 메서드의 인자로 전달 가능
Iterator iter = c1.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
c) forEach()를 사용 (-> 함수형 프로그래밍과 람다)
c1.forEach(s -> System.out.println(s));
c1.forEach(System.out::println);
3. List, Set
: List, Set은 Collection 인터페이스 상속받고, List의 구현 클래스는 AbstractList 클래스를 상속 받는다.
리스트(List)
: 중복을 허용하고 저장순서가 유지되는 배열
-> Vector, ArraryList, LinkedList
메서드 | 설명 |
add(), addAll() | 새로운 요소를 추가, 위치를 지정하거나 컬렉션 데이터를 한번에 추가하는 것이 가능 |
get() | 지정된 위치(index)에 있는 객체 반환 |
indexOf() | 객체의 위치(index) 반환 |
lastIndexOf() | List의 마지막 요소부터 역방향으로 위치 반환 |
listIterator() | List의 객체에 접근할 수 있는 ListIterator를 반환 |
remove() | 지정된 위치에 있는 객체를 삭제하고 삭제된 객체를 반환 |
set() | 지정된 위치에 객체를 저장 |
sort() | 지정된 Comparator로 List 요소 정렬 |
subList() | 지정된 범위에 있는 객체를 새로운 List로 반환 |
ArrayList, LinkedList
: 일반적인 List 구현 클래스로, 데이터 추가나 삭제가 잦은 경우 속도에 영향이 미친다.
->ArrayList : 내부는 배열 구조로 중간에 데이터 추가나 삭제가 불가능
->LinkedList : 중간에 데이터 추가나 삭제 가능
# 타입 선언 : 인터페이스 타입
# 객체 생성 : ArrayList나 LinkedList 사용
List<String> l1 = new ArrayList<>();
List<String> l2 = Arrays.asList("one", "two");
List<String> l3 = List.of("three", "four");
l1.add("five");
l1.allAll(l2);
l1.set(0,"zero");
System.out.println(l1.get(0));
LinkedList<String> llist = new LinkedList<>();
llist.addAll(l2);
llist.addAll(1,l3);
llist.add("five");
ArrayList와 LinkedList
-> 요소의 추가와 삭제 방법이 다르다
정렬
1) Collections.sort(List <T> list) : 내림차순 정렬, 원소들이 정렬된 결과로 전환
-> 올림차순 정렬 불가 [Comparator를 이용해 추가로 인자 작성시 가능]
Collections.sort(l1);
System.out.println(l1);
2) List의 sort(Comparator <? super E> c) 메서드 이용 [Comparator 객체 필요]
-> 별도 클래스로 만든 요소 타입 사용시 Comparable 인터페이스 구현하고 compareTo() 메서드 구현
-> 또는, sort() 메서드의 인자 부분에 직접 내부 익명 클래스로 구현
l1.sort(new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
return o2.toString().compareTo(o1.toString());
}
});
- 여기서는 올림차순 정렬로 두번째 인자.compareTo() 결과를 리턴
- 내림차순의 경우 첫번째 인자.compareTo() 결과를 리턴
- compare() 결과는 같으면 0, 자신이 크면 양수, 인자가 크면 음수를 리턴.
3) stream api 이용
l1.stream().sorted((o1, o2) -> o2.toString().compareTo(o1.toString())).forEach(System.out::println);
- List 객체를 stream() 메서드를 이용해 스트림으로 변환한 다음 sorted() 메서드를 사용.
- sorted() 는 람다식을 이용해 Comparator 를 구현
- 변환된 스트림은 forEach() 를 이용해 출력.
Set
: List와 유사한 자료구조로, 중복허용되지 않고 순서유지안되는 자료구조
-> 대표적인 구현클래스 : HashSet, LinkedHashSet, EnumSet, TreeSet, CopyOnWriteArraySet
[가장 자주 쓰이는 클래스 : HashSet, 순서가 필요한 경우 : LinkedHashSet, TreeSet]
메서드 | 설명 |
add(), addAll() | 기존에 없는 새로운 요소를 추가, 컬렉션 데이터를 한번에 추가하는 것도 가능 |
clear() | 모든 요소를 삭제 |
contains(), containsAll() | 인자의 객체를 포함하고 있는지 확인, 컬렉션 전체를 비교할수도 있음 |
isEmpty | 요소가 하나도 없는지 확인 |
iterator() | 현재 Set의 객체에 접근할 수 있는 Iterator를 반환 |
remove(), removeAll() | 특정 객체를 삭제하거나 컬렉션 전체를 삭제 |
size() | Set 에 저장된 요소의 크기를 반환 |
toArray() | 현재 Set의 요소를 배열로 반환 |
HashSet, LinkedHashSet
: 데이터가 중복되지 않는 자료구조
-> LinkedHashSet : 데이터가 입력된 순서로 저장
#타입 선언 : 인터페이스 타입
객체 생성 : HashSet / LinkedHashSet
(Interface_Type)<Type_Name> (Intance_Name) = new (Implement_Class_Name)<>();
Set<String> s1 = new HashSet<>();
Set<String> s2 = Set.of("three","four");
s1.addAll(Arrays.asList("one","two"));
s1.addAll(s2);
s1.add("five");
s1.add("two"); // 기존에 있으므로 새로 추가 안됨
s1.remove("five");
boolean check = s1.contains("one");
LinkedHashSet : 생성 클래스만 다르다.
LinkedHashSet<String> lset = new LinkedHashSet<>();
lset.addAll(Arrays.asList("one","two","three","four"));
lset.add("five");
Iterator가 필요한 경우 객체를 가지고 와서 사용 가능
Iterator<String> iter = lset.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());
}
TreeSet
: Sorted 인터페이스를 구현한 클래스로 중복 불가능한, 오름차순으로 데이터 정렬하는 자료구조
Set<Integer> tset = new TreeSet<>();
tset.addAll(Arrays.asList(50,10,60,20));
내림차순 정렬시 -> 스트림 api 사용
tset.stream().sorted((o1, o2) -> o2.toString().compareTo(o1.toString())).forEach(System.out::println);
04. Map
: 순차가 아니라, Key와 Value의 쌍으로 데이터 관리하는 자료구조
자체 인터페이스로 여러가지의 구현클래스를 가진다
-> HashMap
- Map은 Collection 인터페이스를 상속하지 않음.
- Key 집합은 Set 으로 볼 수 있음.
- Value 집합은 Collection 으로 볼 수 있음.
Map<String,String> map = new HashMap<>();
map.put("109875","홍길동");
map.put("109894","김사랑");
System.out.println(map.get("109894")); // 김사랑
- 타입 파라미터로 Key,Value 의 타입을 지정
- 문자열 이외 클래스 타입도 가능
- 필요한 데이터를 찾기 위해서는 Key 를 인자로 사용
메서드 | 설명 |
put(), putAll() | 새로운 요소를 추가, 데이터를 한번에 추가하는 것도 가능 |
get() | 특정 Key 에 해당하는 값을 가지고 옴 |
remove | Map 요소 삭제 |
entrySet | key 와 value 값 모두를 Entry 객체로 반환 |
keySet | key 요소만 Set 객체로 반환 |
size | 크기를 반환 |
values | value 요소만 Collection 타입으로 반환 |
'Java > Java 2' 카테고리의 다른 글
[Java] 7. 입출력 프로그래밍 (0) | 2021.11.15 |
---|---|
[Java 실습] 6. 자료구조와 컬랙션프레임워크 (0) | 2021.10.01 |
[Java 실습] 5. 자바 중급 활용 (0) | 2021.10.01 |
[Java] 5. 자바 중급 활용 (0) | 2021.07.16 |
[Java 실습] 4. 객체지향 개념과 자바 (0) | 2021.07.15 |