Programming/Java

14. JAVA Collections

주죵 2021. 1. 15. 00:12
728x90
반응형

컬렉션이란

우리말로 쉽게 말하면 자료구조이고 더 쉽게 말하면 배열이다. 앞에서 배운 단순한 배열 뿐 아니라 다른 훌륭한 자료구조를 자바가 많이 만들어놨다. 따라서 그 API를 우리가 잘~ 사용하면된다 ㅋㅋ

 

JAVA도 결국 효과적인 데이터를 처리하기 위한 수단

자바도 결국 다른 언어랑 마찬가지로 데이터를 효과적으로 정리하기 위한 언어다. 

데이터를 어떻게 정리하고 활용하냐에 따라 효율성이 많이 달라질 수 있다. 따라서 데이터의 성격에 따라 잘 관리를 해야한다. 이를 위해 자바에서도 다양한 자료구조형을 제공한다.

 

실제로 오늘 다루는 내용의 일부는 학부시절 "데이터구조론(걍 자료구조)"에서 배웠던 내용이 꽤  나온다.

그때 담당 교수님이 이상한 바람이 불어서 그해의 자료구조 수업을 파이썬으로 하셨는데(약 6년전...) 당시 파이썬 자료구조는 쪼~꼼 조악한 느낌이 있었던것같다.ㅋㅋ 그당시 "파이썬이 떠오르는 언어다~" 라곤 했지만 요즘처럼 많이들 다루는 언어는 아니었다. 근데 웃긴게 요즘 열리는 강의에서는 자바로 수업하시더라 ㅎㅎ;

 

자료구조의 관리

기초데이터는 메모리 안에 값을 가졌지만 객체데이터는 메모리 안에 저장한 값을 가르키는 메모리 주소를 할당한다는 것을 앞에서도 많이 배웠다. 갑자기 이말을 하는 이유는 눈치챘을듯하다.

자료구조형안에서는 객체의 레퍼런스(주소값)만을 관리한다. 실제 객체는 다른곳에 존재한다. 앞에서 봤던 Array 예시에서도 말했던것처럼 Array의 메모리는 데이터 값 그자체가 아니라 그 데이터를 가르키는 레퍼런스를 가진다.

 

List계열 컬렉션 클래스

ArrayList

ArrayList는 배열과 매우 비슷하다. 인덱스가 존재하며 데이터가 중복되어도 상관이 없다. 데이터 전처리하다보면 인덱싱이 참 짜증나게하던 경우가 많았던것처럼 ArrayList에선 인덱스가 아주 중요하다고 한다.

Arraylist 메소드는 뭐가있나 함 보자

1) add : append라고 보면 된다. arraylist에 값 추가할때 쓰이는 메소드

2) toString : Arraylist안에 있는 값을 String값으로 출력한다

3) set(index, value) : Arraylist의 index안에 있는 값을 value로 설정(교체)하는 메소드

4) remove(index) : 그렇다. 해당되는 지우는거다

5) clear : 그렇다. 싹다지우는거다

6) size : 사이즈 출력이다. length 혹은 shape 느낌

 

LinkedList

ArrayList와 비슷하다. 지금 듣고있는 이 강의에선 '비슷하다, 속도차이가 있다는데 별차이없다' 라고 설명하고 넘어간다. 초보개발자들의 눈높이에 맞춘 간단한강의 넘좋앙~

LinkedList가 더 빠른 이유는 간단히 말그대로 array안에 담고있는 정보와 인덱스가 linked 되어있기 때문에 호출하는 시간이 더 빠르다라고 생각하자. 더 자세한 내용은 정통 자료구조 내용을 찾아보는걸로~

 

메소드를 살펴보자

1) add(index, value) : 위와 비슷하다. 하지만 linked! list이므로 index와 연결시켜  내가 원하는 위치에 끼워넣기가 가능하다. 물론 index 입력없이 value값만 입력하면 arraylist의 add와 똑같이 작동한다

2) remove : 위와동일ㅋㅋ

3) clear : 얘또한ㅋㅋ

 

Vector

벡터도 Arraylist와 비슷하다. 하지만 속도가 조금 떨어진다. arraylist보다 멀티스레드 환경에서는 안전한 구조라서 여전히 많이 쓰인다.

 

Map계열 컬렉션 클래스 살펴보기

Map계열의 자료구조는 사물함을 생각하면 된다. 사물함은 번호가 있어도 번호보다 중요한건 사물함을 여는 '키'이다. 즉 키만 있으면 해당하는 사물함을 슥슥 열고닫고 할 수 있다는 것이다.

파이썬에선 hash 자료구조를 dictionary형으로 많이 쓰니(key : value로 연결) 파이썬에 친숙한 사람들은 그렇게 생각하면 편할것이다.

Hashmap

회사 프로그램의 소스코드를 보면 HashMap 굉장히 많이쓰더라. 아직 개허접인 코린이 사원에게는 많이쓰는 컬렉션만 봐도 신기하다. 

HashMap <Integer,String> hashmap = new Hashmap<Integer,String? //Key 값 : Integer  value : String
hashmap.put(0,"str0");
hashmap.put(1,"str1");
hashmap.put(2,"str2");
hashmap.put(3,"str3"); // add대신 put!

String str = hashmap.get(2); //key값을 이용한 value 호출

hashmap.remove(3); //remove도 마찬가지
hahsmap.clear();

이번엔 코드를 보고 해보자. list계열과 다른것은 add대신 put을 사용한다는 것.

hash의 핵심인 key - value로 인해서 데이터를 얻거나(get) 지울때(remove)에도 parameter로 key값을 사용한다

 

HashMap <Integer,String> hashmap = new Hashmap<Integer,String? //Key 값 : Integer  value : String
hashmap.put(0,"str0");
hashmap.put(1,"str1");
hashmap.put(2,"str2");
hashmap.put(3,"str3");

Iterator<Integer> iterator = hashmap.keySet().iterator(); //keySet 즉 key값들을 전부 가져옴
while (iterator.hasNext()){
	String string = hashMap.get(iterator.next());
    System.out.println(string);
}

이건 hashmap을 이용해 반복자(iterator 뒤에서다룸) 형성한거다.

keySet은 hashmap에 있는 key값들을 다 가져온거다. 

hasNext는 말그대로 다음이 있냐 없냐 물어서 boolean인 true false 출력하는 메소드이다. while문에 true값이 들어갈땐 루프작업 일어나다가 string값 프린트 되는 구조이다. (귀찮아서 실습코드 안옮기고있었는데 여기서부턴 했다..)

 

Set계열 컬렉션

Hashset

Hash값을 이용한 set이다. 같은 값을 갖는 데이터는 같은 hash값을 가질것이다. Set계열 자료구조는 데이터의 순서가 없다. 하지만 중복된 데이터는 허락되지 않는다.

파이썬에서 중괄호로 표현했고 흔히 우리가 집합이라 생각하면 편한 set이다. 순서가 없고 데이터도 유니크한 자료구조이다.

hash에 객체가 들어가있다고 생각하자. 같은 생성자로부터 이름도 타입도 구성요소도 똑같은 객체가 두개 있다면?

HashSet<Student> hashSet = new HashSet<Student>();
hasSet.add(new Student("홍길동",3));
Student student = new Student("홍길동,3);
hashSet.remove(student);

 

 

위의 예제를 보자. Student타입을 입력받는 HashSet에 홍길동,3 의 데이터를 갖는 객체를 하나 넣었다. 아래에 생성자로부터 홍길동,3의 데이터갖는 객체를 만들고 remove처리해줬다.

저 hashSet안의 홍길동은 사라졌을까?

 

정답은 "사라지지 않았다." 이다. 두 객체는 서로 같은값을 갖지만 생성될때 독립적이고 메모리에 서로다른 주소값을 갖는다. 각 주소값에 hash값을 부여하는 hashSet이기 때문에 사라지지 않는다.

그렇다면 나중에 내가 원하는 데이터를 지우고싶은데 안지워지고 중구난방 헷갈려지는 경우가 생길수도 있지 않을까?

따라서 위와같은 경우에는 equals와 hashCode를 사용해 데이터를 삭제한다.

public class Student(String name, int grade){
	private String name;
    private int grade;
    
    public Student(String name, int grade){
    	this.name = name;
        this.name = grade;
        
    }
    
    @Override
    public String toString(){
    	return name + " : " + grade;
    }
    
    //overide해준다. 참고로 아래의 메소드들은 object에서 오버라이드하는것
    //equals를 이용해 들어온 객체가 똑같은값인지 비교해본다
    public boolean equals(Object obj){
    	String compareValue = obj.toString();
        String thisValue = toString();
        return thisValue.equals(compareValue)
    }
    //toString의 주소값을 정수 hash로 뽑아준다
    public int hashCode(){
    	return toString().hashCode();
    }
}

 equals 만족하고 hashCode만족하면 삭제가 가능하다.

같은 toString으로 hashcode를 재정의하여 return할때 같은 해쉬코드가 되는것이라 생각하면 된다.

 

Iterator 자료구조

이름만들어도 반복할것같은 Iterator다. 아주 유용한 반복자다. 참고로 모든 자료구조는 iterator() 메소드를 지원한다.

위에서 잠깐 봤던 예시를 다시보자

HashMap <Integer,String> hashmap = new HashMap<Integer,String? //Key 값 : Integer  value : String
hashmap.put(0,"str0");
hashmap.put(1,"str1");
hashmap.put(2,"str2");
hashmap.put(3,"str3");

Iterator<Integer> iterator = hashmap.keySet().iterator(); //keySet 즉 key값들을 전부 가져옴
while (iterator.hasNext()){
	String string = hashMap.get(iterator.next());
    System.out.println(string);
}

hashmap 또한 iterator를 제공하기 때문에 iterator로 가져온거다. 다만 주의할것은 key값이 없는 자료구조 ex)arraylist라면 iterator를 바로 사용가능하지만 위의 예제처럼 key값 갖는 hash자료의 경우는 keySet을 한 이후에 iterator 사용해야한다는점이다.

 

다음시간엔 Java의 입출력 I/O에 대해 알아볼것이다

 

출처 : 신입SW인력을 위한 실전자바 (by 블스)

728x90

'Programming > Java' 카테고리의 다른 글

16. 스레드(Thread)  (0) 2021.01.16
15. JAVA 입출력(I/O)  (0) 2021.01.16
13. 예외처리  (0) 2021.01.13
12. API  (0) 2021.01.11
11. 패턴을 통한 객체지향 언어의 이해  (0) 2021.01.10