List<E>를 구현하는 클래스들과 달리 Set<E>를 구현하는 클래스들은 데이터의 중복저장을 허용하지 않는다.
(단, 동일 데이터에 대한 기준은 프로그래머가 정의)
package Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
// HashSet 인스턴스 생성 : 인스턴스를 저장하기 위한 저장 공간 생성
// set : 집합, 저장순서 유지하지않는다.
Set<String> set = new HashSet<String>();
set.add("First");
set.add("Second");
set.add("Third");
set.add("First"); // 중복이라 저장되지 않는다.
System.out.println("set 요소의 개수 : "+ set.size());
Iterator<String> itr=set.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
}
}
}
<출력>
set 요소의 개수 : 3 Second Third First
// Set<e>는 저장하는 순서를 가지지 않기 때문에 // 일괄처리를 위해서는 Iterator<E> 인스턴스를 이용해서 처리한다. // Collection<E>에는 Iterater() 메서드를 가지고 있고 Iterator<E>를 반환한다.
HashSet<E>클래스의 동등비교
String에는 Hashcode() 가 있어서 지 알아서 중복 분류해주지만 나머지는 해시코드를 만들어줘야한다
package Collection;
public class SimpleNumber {
int num;
public SimpleNumber(int num) {
this.num = num;
}
@Override
public String toString() {
return String.valueOf(num);
}
}
package Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SimpleNumberMain {
public static void main(String[] args) {
// set 인스턴스 생성
Set<SimpleNumber> set=new HashSet<SimpleNumber>();
set.add(new SimpleNumber(10));
set.add(new SimpleNumber(20));
set.add(new SimpleNumber(10));
System.out.println("Set 요소의 개수 : "+set.size());
Iterator<SimpleNumber> itr = set.iterator();
while(itr.hasNext()) {
System.out.println(itr.next());
}
}
}
<출력>
Set 요소의 개수 : 3 10 10 20
<SimpleNumber 수정>
쉬프트 알트 o > gernerate hashcode() and equals()
package Collection;
public class SimpleNumber {
int num;
// Set 동등 비교를 위한 Hashcode(), equals() 오버라이딩
@Override
public int hashCode() {
// final int prime = 31;
// int result = 1;
// result = prime * result + num;
return num%3; // 0 or 1 or 2
}
@Override
public boolean equals(Object obj) {
if (this == obj) // 참조 주소값 == 전달받은 참조 주소값
return true;
if (obj == null) // 들어오는 객체가 null ex) set.add(null)인 경우
return false;
if (getClass() != obj.getClass()) // 클래스 이름비교, 같은 타입인가
return false;
SimpleNumber other = (SimpleNumber) obj;
if (num != other.num)
return false;
return true;
}
public SimpleNumber(int num) {
this.num = num;
}
@Override
public String toString() {
return String.valueOf(num);
}
}
기본 자료형 정보를 이용해서 제네릭 인스턴스 생성 불가능! 따라서 Wraper클래스를 기반으로 컬렉션 인스턴스를 생성한다. (Int 말고 ⭕Integer⭕)
- ArrayList <어떤Type> 이름
형식
기능
이름.get(index)
index에 저장된 저장값 불러오기
이름.size
저장된 요소의 갯수
이름.remove(index)
index에 저장된 것 삭제
이름.add(추가할값)
추가
이름.add(index, 추가할값)
index에 추가할 값을 추가 (그 뒤는 index 하나씩 알아서 뒤로 밀림)
이름.containts(어떤값)
어떤값이 추가하는지 true/false 반환
이름.set(index,수정값)
index 자리에 있는 값을 수정값으로 수정
이름.indexOf(특정값)
특정값이 잇는 index를 반환
이름.isEmpty();
값을 가지고 있으면 true 아니면 false
이름clear();
모든 원소 삭제
package Collection;
import java.util.ArrayList;
public class ArrayListTest {
public static void main(String[] args) {
// 인스턴스 저장을 목적으로 하는 클래스
// List<E> : 저장 순서 유지 (반복문이용 용이), 중복저장 허용
//ArrayList<Integer> list = new ArrayList<Integer>();
//List<Integer> list = new ArrayList();
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.println("list의 첫번째 요소의 값 : " + list.get(0));
System.out.println("list 요소의 갯수 : " + list.size());
System.out.println("list 출력");
for (Integer i : list) {
System.out.println(i);
}
// 삭제
list.remove(2);
System.out.println("삭제 후 list 출력");
for (Integer i : list) {
System.out.println(i);
}
}
}
<출력>
list의 첫번째 요소의 값 : 1 list 요소의 갯수 : 4 list 출력 1 2 3 4 삭제 후 list 출력 1 2 4
자바에서 컬렉션 프레임워크(collection framework)란 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미합니다, 즉, 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것입니다. 이러한 컬렉션 프레임워크는 자바의 인터페이스(interface)를 사용하여 구현됩니다.
컬렉션 프레임워크 주요 인터페이스
컬렉션 프레임워크에서는 데이터를 저장하는 자료 구조에 따라 다음과 같은 핵심이 되는 주요 인터페이스를 정의하고 있습니다.
1. List 인터페이스
2. Set 인터페이스
3. Map 인터페이스
이 중에서 List와 Set 인터페이스는 모두 Collection 인터페이스를 상속받지만, 구조상의 차이로 인해 Map 인터페이스는 별도로 정의됩니다. 따라서 List 인터페이스와 Set 인터페이스의 공통된 부분을 Collection 인터페이스에서 정의하고 있습니다. 자바 컬렉션 프레임워크의 주요 인터페이스에 대한 더 자세한 사항은 다음 페이지를 참고하면 됩니다.
자바에서 컬렉션 프레임워크를 구성하고 있는 인터페이스 간의 상속 관계는 다음 그림과 같습니다.
위의 그림에서 <E>나 <K, V>라는 것은 컬렉션 프레임워크를 구성하는 모든 클래스가 제네릭으로 표현되어 있음을 알려줍니다.
주요 인터페이스의 간략한 특징
자바에서 컬렉션 프레임워크를 구성하고 있는 주요 인터페이스의 간략한 특징은 다음과 같습니다.
List<E>
순서가 있는 데이터의 집합으로, 데이터의 중복을 허용함.
Vector, ArrayList, LinkedList, Stack, Queue
Set<E>
순서가 없는 데이터의 집합으로, 데이터의 중복을 허용하지 않음.
HashSet, TreeSet
Map<K, V>
키와 값의 한 쌍으로 이루어지는 데이터의 집합으로, 순서가 없음.
이때 키는 중복을 허용하지 않지만, 값은 중복될 수 있음.
HashMap, TreeMap, Hashtable, Properties
컬렉션 클래스(collection class)
컬렉션 프레임워크에 속하는 인터페이스를 구현한 클래스를 컬렉션 클래스(collection class)라고 합니다. 컬렉션 프레임워크의 모든 컬렉션 클래스는 List와 Set, Map 인터페이스 중 하나의 인터페이스를 구현하고 있습니다. 또한, 클래스 이름에도 구현한 인터페이스의 이름이 포함되므로 바로 구분할 수 있습니다. Vector나 Hashtable과 같은 컬렉션 클래스는 예전부터 사용해 왔으므로, 기존 코드와의 호환을 위해 아직도 남아 있습니다. 하지만 기존에 사용하던 컬렉션 클래스를 사용하는 것보다는 새로 추가된 ArrayList나 HashMap 클래스를 사용하는 것이 성능 면에서도 더 나은 결과를 얻을 수 있습니다. 다음 예제는 ArrayList 클래스를 이용하여 리스트를 생성하고 조작하는 예제입니다.
예제
import java.util.*;
public class Collection01 {
public static void main(String[] args) {
// 리스트 생성
ArrayList<String> arrList = new ArrayList<String>();
// 리스트에 요소의 저장
arrList.add("넷");
arrList.add("둘");
arrList.add("셋");
arrList.add("하나");
// 리스트 요소의 출력
for(int i = 0; i < arrList.size(); i++) {
System.out.println(arrList.get(i));
}
}
}
실행 결과
넷
둘
셋
하나
Collection 인터페이스
List와 Set 인터페이스의 많은 공통된 부분을 Collection 인터페이스에서 정의하고, 두 인터페이스는 그것을 상속받습니다. 따라서 Collection 인터페이스는 컬렉션을 다루는데 가장 기본적인 동작들을 정의하고, 그것을 메소드로 제공하고 있습니다. Collection 인터페이스에서 제공하는 주요 메소드는 다음과 같습니다.
package generic;
public class Apple {
private int weight; // 사과의 무게
Apple(int weight){
this.weight= weight;
}
public void showWeight() {
System.out.println("사과의 무게 : " + weight);
}
}
package generic;
public class Orange {
private int sugarContent; // 오렌지 당도
Orange(int sugar){
this.sugarContent=sugar;
}
public void showsugarContent() {
System.out.println("오렌지의 당도 : " + sugarContent);
}
}
package generic;
public class AppleBox {
Apple apple;
public void store(Apple apple) {
this.apple=apple;
}
public Apple PullOut() {
return apple;
}
}
package generic;
public class OrangeBox {
Orange orange;
public void store(Orange orange) {
this.orange=orange;
}
public Orange PullOut() {
return orange;
}
}
package generic;
public class FruitBoxMain {
public static void main(String[] args) {
AppleBox appleBox = new AppleBox();
appleBox.store(new Apple(10));
Apple apple = appleBox.PullOut();
apple.showWeight();
OrangeBox orangeBox = new OrangeBox();
// orangeBox.store(new String("오렌지"));
orangeBox.store(new Orange(100));
Orange orange = orangeBox.PullOut();
orange.showsugarContent();
}
}
2.
fruitBox를 만들어서 사과와 오렌지를 각각 집어넣어줄 수 있지만,
아무거나 들어가도 빨간줄이 생기지 않지만, 실행하면 에러가 난다.
package generic;
public class FruitBox {
Object fruit;
public void store(Object fruit) {
this.fruit=fruit;
}
public Object PullOut() {
return fruit;
}
}
package generic;
public class FruitBoxMain {
public static void main(String[] args) {
FruitBox box1 = new FruitBox();
box1.store(new Apple(100));
Apple apple = (Apple)box1.PullOut();
apple.showWeight();
FruitBox box2 = new FruitBox();
box2.store("Apple"); // Apple 타입만 들어가야 한다. (아무거나 들어가도 ㅇㅋ인게 문제점..)
Orange orange = (Orange)box2.PullOut();//형변환
orange.showsugarContent();
}
}
3.
제네릭을 이용해 FuritBox<T>를 생성해주면
형변환도 필요없고 알아서 올바르지 않은 타입이 들어가면 빨간줄이 생긴다.
package generic;
public class FruitBox <T> { // T > Apple / Orange
T fruit; // Apple fruit
public void store(T fruit) { // store(Apple fruit)
this.fruit=fruit;
}
public T PullOut() { // public Apple PullOut()
return fruit;
}
}
package generic;
public class FruitBoxMain {
public static void main(String[] args) {
FruitBox<Apple> box1 = new FruitBox<Apple>();
// box1.store("Apple"); 에러남
box1.store(new Apple(10));
Apple apple = box1.PullOut();
apple.showWeight();
FruitBox<Orange> box2 = new FruitBox<Orange>();
// box2.store(new Apple(10)); // Orange만 들어갈 수 있게 됨
box2.store(new Orange(100));
Orange orange = box2.PullOut(); //형변환도필요없다.
orange.showsugarContent();
}
}
4.
FruitBox<T>에 초기화 생성자를 추가하면 더욱 편리하다.
package generic;
public class FruitBox<T> { // T > Apple / Orange
T fruit; // Apple fruit
FruitBox(T fruit){ // FruitBox(Apple fruit){
this.fruit=fruit;
}
public void store(T fruit) { // store(Apple fruit)
this.fruit=fruit;
}
public T PullOut() { // public Apple PullOut()
return fruit;
}
}
package generic;
public class FruitBoxMain {
public static void main(String[] args) {
FruitBox<Apple> box1 = new FruitBox<Apple>(new Apple(10));
Apple apple = box1.PullOut();
apple.showWeight();
FruitBox<Orange> box2 = new FruitBox<Orange>(new Orange(100));
Orange orange = box2.PullOut(); //형변환도필요없다.
orange.showsugarContent();
}
}
package Basic;
import java.util.StringTokenizer;
public class Token {
public static void main(String[] args) {
String s="11:22:33:44:55";
StringTokenizer st = new StringTokenizer(s, ":");
while(st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
}
}
11 22 33 44 55
import java.util.StringTokenizer;
public class Token {
public static void main(String[] args) {
System.out.println("-----------------------1번");
String a = "11:22:33:44:55";
StringTokenizer t = new StringTokenizer(a, ":"); // ":"가 true이면 출력
while (t.hasMoreTokens()) {
System.out.println(t.nextToken());
}
System.out.println("-----------------------2번");
String s = "11:22:33:44:55";
StringTokenizer st = new StringTokenizer(s, ":", true); // ":"가 true이면 출력
while (st.hasMoreTokens()) {
System.out.println(st.nextToken());
}
System.out.println("-----------------------3번");
String pNum = "Tel 82-010-1234-5678";
StringTokenizer st1 = new StringTokenizer(pNum);
while (st1.hasMoreTokens()) {
System.out.println(st1.nextToken());
}
System.out.println("-----------------------4번");
StringTokenizer st2 = new StringTokenizer(pNum, " -"); // 구분자는 "-" " " 로 처리
while (st2.hasMoreTokens()) {
System.out.println(st2.nextToken());
}
System.out.println("-----------------------5번");
StringTokenizer st3 = new StringTokenizer(pNum, "- ", true);
while (st3.hasMoreTokens()) {
System.out.println(st3.nextToken());
}
}
}
-----------------------1번 11 22 33 44 55 -----------------------2번 11 : 22 : 33 : 44 : 55 -----------------------3번 Tel 82-010-1234-5678 -----------------------4번 Tel 82 010 1234 5678 -----------------------5번 Tel