날아라쩡글이의 블로그입니다.
Set interface, List interface(iterator) 본문
중앙 HTA (2106기) story/java API story
Set interface, List interface(iterator)
날아라쩡글이 2021. 10. 7. 17:00728x90
반응형
- java.Lang.package안에는
- Object,List,Set,Map,ArrayList,HashSet,HashMap,LinkedList,TreeSet,HashTable,Stack,Vector
- Date,Arrays,Collection,Objects,Random,Calendar
- 이 존재한다. 첫번째의 경우는 자료구에 해당되며 오늘 작성할 친구들이다.
Collection Framwork란
- Framwork란 개발방법을 구체화 시켜놓은것
- 자바의 자료구조를 구현해 놓은 것, 자료구조를 구현해 놓은 것
- 자료구조란 객체의 저장/삭제/조회 등의 기능을 제공한것
- 다른 객체를 다룰때, 꺼내고, 삭제하고, 확인할 때 사용하는 방법이다.
- 자바의 모든 자료구조의 구현 클래스는 Collection인터페이스를 구현한 클래스이다.
- Collection인터페이스에 정의된 모든 기능을 구현하고 있다.
- Collection<E>
- ArrayList, LinkedList, HashSet, TreeSet, Vector, Stack등 이게 전부 Collection<E>으로 구현되고 있다.
- method
- add();
- addAll();
- clear();
- contains(Object e); -->e의 객체를 확인하는
- isEmpty -->비어있으면 true, 아니면 false
- Iterator : 반복자
- remove(Object e)
- size
- toArray : 배열에 담아서 반환
대표적인 자료구조이다.
HashSet<E>의 부모의 형태이다.
Collection<E>인터페이스
- 모든 자료 구조 구현 클래스가 반드시 구현할 기능을 정의하고 있다.
- 모든 자료 구조 구현 클래스의 표본이다.
Set<E>인터페이스
- 중복을 허용하지 않는 자료 구조 구현 클래스가 반드시 구현할 기능을 정의하고 있다.
- 중복을 허용하지 않는 자료 구조 구현클래스의 표준이다.
이제부터는 배열을 사용하지 않고, Collection을 이용할 것이다.
자바의 자료구조 특징
- 객체만 저장할 수 있다.
- 제네릭을 사용하기 때문에 객체만 저장할 수 있다.
- 크기가 가변적이다.
- 배열은 크기가 고정적이다.
- 자료구조는 index가 부족시 index가 늘어나고 삭제시 줄어든다.
- 다양한 메소드를 가진다.
Collection<E>제네릭의 형태로 객체만 저장이 가능하고, 기본자료형은 저장할 수 없다.
Set<E>
- 중복을 허용하지 않는다. 동일한 객체가 2개가 저장되지 않는다.
- HashSet<E>
- 가장 많이 사용하는 Set의 구현 클래스이다.
- 같은 객체인지 확인하고, 같은 객체일 경우 해쉬코드가 동일하다.
- 해쉬코드로 동일성 여부를 확인하기 때문에 hash와 equals를 이용하여, 동등성 비교로 재정의 해주는 것이 좋다.
- TreeSet<E>
- 저장되는 요소가 오름차순/ 내림차순으로 정렬되어서 저장된다.
- 제일 처음부터 오름차순/ 내림차순으로 정렬되어서 저장한다.
- new HashSet<객체>();
- 자체적인 저장소를 가졌다.
- 객체의 경우 제네릭타입으로 사용시 바로 지정할 수 있다,
- memory가 허락하는 한 모든 객체를 담을 수 있다.
HashSet<E>
- 여러개의 객체를 담는 배열
- 배열의 인덱스는 index를 알아야한다.
- 인덱스의 범위를 초과하면 java.lang.ArrayIndexOutOfBoundsException이라는 에러가 발생한다.
- 배열의 인덱스,범위를 초과 했을 때 발생하는 오류정보를 포함하고 있는 예외클래스 이다.
- 배열은 자동으로 크기가 증가되지 않는다.
- 그러나 hashSet의 경우 담을 때마다 인덱스가 증가한다.
- HashSet<String> set = new HashSet<>();
- HashSet객체에 데이터(객체)를 저장할 때는 add(E e)메소드를 실행해서 데이터를 저장한다.
- 배열보다 쉽게 데이터를 저장할 수 있다. index를 몰라도 되기 때문이다.
- 저장공간이 부족하면 자동으로 저장공간을 늘린다.
- set.add("문자열");
- 계속해서 들어가고 순서는 그냥 막들어간다. hashcode의 순서대로 입력된다.
구분 | 배열 | 콜렉션 |
데이터 | 기본자료형, 객체 | 객체 |
길이 | 불변 | 가변적 |
저장 | 인덱스 필요 | 맨 마지막요소의 끝에 자동으로 저장 |
삭제 | 인덱스 필요, 해당부분 데이터 empty | 삭제후 다음요소 해당위치 자동채워짐 |
Enhanced-for(향상된 for문) | 배열의 끝까지 반복(null exception남) | 요소가 있는 부분까지 반복 |
HashSet<E>의 주요 API사용하기
- import시켜줘야한다.
- Set<String> set = new HashSet<>();
- Set이 구현객체기 때문에 이렇게 만들어 줄 수있다.
- boolean add(E e ) : 지정된 객체를 HashSet객체에 저장한다.
- 저장이 성공하면 true를 반환한다.
- boolean값은 다시 받지 않는다. 저장된걸 확인하면 된다.
- boolean isEmpty(); : HashSet<E>이 비어있으면 true를 반환한다.
- void clear(); : HashSet<E>에 저장된 모든 객체를 삭제한다.
- String toString();
- HashSet<E>는 Object의 toString();메소드를 재정의 했다.
- HashSet<E>는 저장된 객체의 toString()을 실행한다.
- boolean addAll(Collection <? extends E> collection);
- 다른 collection의 구현객체에 저장된 데이터를 전부 저장한다.
- Collection<? extends E >는 Collection구현 객체가 E나 E의 하위타입을 저장하고 있어야한다.
- E는 addAll()메소드를 호출하는 객체의 타입파라미터를 따른다.
- 우리가 생성한 객체는 HashSet<String>이기 때문에 E는 String이다.
- 따라서 Collection<String> , Set<String> , List<String> , HashSet<String>, ArraysList<String>, Vector<String> , LinkedList<String>, Stack<String>이 가능하다.
- <? extends String>으로 변환된다. String은 자식객체가 없기 때문에 String만 가능하다.
- HashSet<E>의 부모인터페이스(Set<E>)에는 set.of() 정적메소드가 존재한다.
- Set<E> Set.of() : Set의 구현객체가 생성한다.
- Set<E> Set.of(E e) :객체가 하나저장된 Set구현객체를 생성한다.
- Set<E> Set.of(E e, E e) :객체가 두 개 저장된 Set구현객체를 생성한다.
- Set<E> Set.of(E e....E e) :객체가 여러개 저장된 Set구현객체를 생성한다.
- int size() : HashSet<E> 객체에 저장된 객체의 갯수를 반환한다.
- boolean contains(Object e) : HashSet<E>객체에 지정된 객체가 존재하면 true를 반환한다.
- 원하는 문자열이 있는지, 객체의 존재여부를 출력한다.
- boolean remove(Object e ) : HashSet<E>객체에 지정된 객체가 존재하면 삭제하고 true를 반환한다.
- System.out.println(set);
- HashSet에 담을 줄 알아야하고, 꺼낼 수 있고, 몇 개 있는지, 비어있는지 확인이 가능해야한다.
- main클래스를 설정하고, 정적 내부 클래스에 매개변수, 생성자, 동등성의 원칙을 위하여 hashCode와 equals에 대한 재정의를 하고, 디버그를 확인하기 위한 toString()도 재정의를 해준다.
- 정적 내부 클래스의 객체를 넣은 HashSet()을 선언한다.
- HashSet<Employee> employees = new HashSet<>();
- employee.add(new Employee(100,"이순신","관리팀"));
- add메소드를 이용하여, 객체를 바로, 바로 추가해준다.
- 동등성의 메소드를 이용해서 입력하지 않으면, 객체는 따로, 따로 생성이 되기 때문에 같은 객체로 보지 않는다.
- 그리고 미리 값을 확인하고 싶어도, 재정의 전인 toString이 클래스 name@ 해시코드로 나오기 때문에
- example_10_06_01_collection.HashSetSample3$Employee@83값으로 출력된다.
- 동등성비교과 toString을 재정의해주면 System.out.println(변수의 이름)을 넣으면
- 재정의 후 Employee [id=100, name=김유신, dept=홍보팀];으로 출력된다.
- addAll()다른 컬렉션을 한꺼번에 담고 싶을 때 사용 가능하다.
- add는 한번씩 밖에 담지 못한다.
TreeSet<E>
- 저장되는 객체를 오름차순으로 정렬해서 저장한다.
- 저장되는 방식에 차이가 있다. 메소드는 동일하다.
- TreeSet에만 사용되는 method가 존재한다.
- java에서는 정렬은 잘 사용되지 않는다.
- 우리가 사용하는 DB에서는 정렬이 완료된 데이터를 가져오기 때문에 많이 사용되지 않는다.
Vector와 Stack은..
- 1.0부터 만들어진 존재들이다.
- 제일 처음에는 메소드가 통일되지 않았다.
- Vector에서는 elements라는 것이 사용되었고, Stack에서는 push, pop이 사용되었다.
- collection<E>는 1.2부터 도입이 되었다.
- 원래는 자료구조에 따라서 전부 메소드가 달랐고,
- Set<E>, List<E>를 만들어서 메소드를 동일하게 만들었다.
- 그래서 1.0에 만들어진 애들은 추가적으로 본인의 고유한 메소드가 존재한다.
- 잘 사용하지 않기 때문에 따로 수업은 진행하지 않는다.
- 고유의 기능이 정보처리기사에 나오는 Stack push, pop 같은 존재이다.
ArrayList<E>
- 정말정말정말 많이 사용하는 것이다.
- 순서가 보장된다는게 중요한 class이다.
- ArrayList<String> list = new ArrayList<>();
- 메소드
- HashSet<E>과 사용방법은 동일하다.
- boolean add(E e ) : ArrayList객체에 객체를 저장한다. 맨 마지막 객체 다음에 객체가 저장된다.
- void clear() : ArrayList객체에 저장된 모든 객체를 삭제한다.
- boolean isEmpty() : ArrayList객체에 저장된 객체가 하나도 없으면 true를 반환한다.
- int size() : ArrayList객체에 저장된 객체의 갯수를 반환한다.
- boolean contains(Object e ): ArrayList객체에 지정된 객체가 존재하면 true를 반환한다.
- boolean remove(Obejct e ) : ArrayList객체에서 지정된 객체를 삭제한다.
- 맨 처음 발견된 객체만 삭제한다.
- 인덱스 메소드
- HashSet과 다르게 인덱스를 이용하여 더하거나 삭제가 가능하다.
- List계열들이 이런 기능을 가지고 있다.
- void add(int index, E e) : 지정된 인덱스에 객체를 추가한다. 기존 객체는 뒤로 이동된다.
- E set(int index, E e ) :지정된 인덱스에 저장된 객체를 새로운 객체와 교체한다.
- E remove(int index) :지정된 인덱스에 저장된 객체를 삭제한다.
- E get(int index) :지정된 인덱스 위치에 저장된 객체를 반환한다.
- for문의 조건식에서 list.size()로 바로 대입하여 데이터의 갯수를 조회하는 것은 실행성능을 나쁘게 만든다.
- int length = list.get(index);처럼 인덱스의 크기를 기본변수타입에 대입하여 조건식에 넣는 것도 좋다.
return타입의 확인
- public Set<E>XXX() {}
- XXX() 메소드를 호출하면 중복된 객체가 없는 자료구조 객체를 제공받게 됩니다.
- public List<E>XXX(){}
- XXX()메소드를 호출하면 저장했던 순서 그대로 다시 꺼낼 수 있는 자료구조 객체를 제공받게 됩니다.
자바 7이하의 버젼에서 타입추론이 등장하게 되었기 때문에 이전버젼의 경우는 <String>우측에 있는 제네릭에도 객체의 타입을 작성해주어야한다.
List
ArrayList<E>와 LinkedList<E>차이점
- ArrayList<E>는 순서대로 저장하고 순서대로 꺼내기 편하다.
- ArrayList<E> 중간에 저장된 객체를 삭제하거나 중간에 새로운객체를 추가할 때는 LinkedList<E>에 비해서 처리속도가 느리다.
- 데이터가 빈번하게 추가/ 삭제가 발생할 때는 LinkedList가 적합하다
- LinkedList<E>
- 데이터가 빈번하게 추가/삭제가 발생하는 경우에 사용한다.
- 데이터 추가/ 삭제로 인한 부하가 ArrayList<E>에 비해서 적다.
- 저장하는 방식의 차이
방식들이 전부 다 다르게 저장된다.
구현객체가 전부 다 달라도 동일한 방식으로 꺼내고 싶어서 1.2부터 추가가 되었다. 향상된 for문은 1.5부터 등장하였다.
Set, List
- 꺼내는 방법이 있어야한다.
- Collection 꺼내는 경우에는 향상된 for문을 사용하지만,
- 객체를 꺼내고 삭제할 때는 Iterator을 사용해야한다. -->기존의 소스를 변경해야하는 프로젝트가 많다.
Iterator<E> name = 꺼낼데이터name.Iterator();// 메소드를 호출한다. 일회용으로 한번 사용 후 끝이다.
Iterator<E> 꺼내는 방법에 대한 표준
- Interface Iterator<E> //collection<E>구현객체에 데이터를 반복처리하는 표준
- boolean hasNext( ); //자료구조구구현 객체에 반복처리할 데이터가 남아 있으면 true를 반환한다.
- E next(); //자료구조구현객체에서 객체를 꺼낸다.
- void remove(); //현재 반복처리 중인 객체를 자료구조구현객체에서 삭제한다.
public class ArrayList<E> extends AbstractList<E> implements List<E>{
- public boolean add(E e) {...}
- public E get(int index) {...}
- public class ArrayListIterator<E> umplements Iterator<E>{ //ArrayList객체에 저장된 객체를 반복처리할 수 있는 Iterator<E>구현 클래스 (멤버내부클래스)
- public boolean hasNaxt(){...} //ArrayList객체에 반복처리 할 데이터가 남아있으면 true를 반환
- public E next(){...} //ArrayList객체 반복처리할 다음 데이터를 반환
- public void remove(){...} //ArrayList객체에서 현재 반복처리한 데이터를 삭제한다.
- }
- }
모든 Collection<E>자료구조 자식들은 Iterator<E> iterator();을 무조건 구현하고 있다.
while()문 사용시점
- 특별한 객체와 연관되어 있을 경우
- 반복을 언제 끝내줘야 할지 알려주는 메소드와 함께해야함
- Iterator<E>내부의 hasNext();
- next()
- Enumaration<E>내부의 hasMoreElements()
- nextElement()
- boolean의 꺼내는 메소드들을 while문은 이렇게만 사용한다.
- 반복을 지속하는 메소드와 함께쓰는 것이 while문이다.
- while문으로 초기식, 조건식, 증감식을 흉내내지는 않는다.
- while문은 아래에서 예를 든 객체처럼 반복을 계속 실행해야하는지 알려주는 메소드가 있는 객체 경우에만 사용한다.
- Iterator<String> iter = names.iterator(); // ArraysList가 구현한 Iterator구현 객체를 획득한다.
- while(iter.hasNext()) { //반복
- String name = iter.next();
- name.remove();
- 배열의 remove를 사용하게 되면 맨 처음에 지정된 객체밖에 삭제가 되지 않는다.
- 데이터에 얼마나 있는지 모르기 때문에 여러번의 효율은 좋지 않다.
- 향상된 for문으로 사용하게 될 경우
- java.util.ConcurrentModificationException의 오류가 발생하게 된다.
- 추가는 가능하지만 삭제가 되지 않는다.
- 이렇게 사용을 해야한다.
- Iterator의 경우 데이터를 아예 영구적으로 삭제할 때 사용할 수 있다.
- 1회용으로 사용하기 때문에 , 반복작업에 사용한 Iterator를 재사용할 수 없다.
- 다시 만들어서 사용해야한다.
반응형
'중앙 HTA (2106기) story > java API story' 카테고리의 다른 글
java.util.유틸리티 클래스 (0) | 2021.10.08 |
---|---|
Map interface (0) | 2021.10.08 |
Generic(제네릭) (0) | 2021.10.05 |
System, Wrapper, math class (0) | 2021.10.03 |
StringBuilder, StringBuffer (0) | 2021.10.03 |
Comments