2023.02.01 - 안드로이드 앱개발자 과정

CHA·2023년 2월 4일
0

Java



Generic

class 설계 때 멤버의 자료형을 정하지 않고 객체를 생성할 때 자료형을 정하도록 하는 문법.

Generic 이란 아직 명칭이 정해지지 않은 상품이란 뜻을 가지고 있습니다. 프로그래밍적인 의미로도 동일합니다. 즉, 멤버의 자료형이 정해지지 않았다는 의미입니다.


Generic 사용하기

먼저, 멤버의 자료형이 정해지지 않은 클래스를 설계해봅시다.

public class Box<T> {
	T a;
}

<> 안에 자료형을 작성하고 그 자료형을 토대로 멤버를 설정합니다. <> 안에 자료형은 어떤 단어든 상관없습니다. (물론 String 과 같은 단어는 사용하지 않아야 하겠습니다.) 그리고 Main 클래스에서 Box 클래스의 객체를 생성해봅시다.

public static void main(String[] args) {
	Box<String> box = new Box<String>();
    
    box.a = "Hello";
}

위 코드와 같이 클래스명 오른쪽에 제네릭 타입을 작성해주면 객체 생성이 가능합니다. 물론 사용자 정의 클래스나 다른 클래스들도 제네릭 타입으로 설정할 수 있습니다. 단 기본형 변수, int, short 등은 사용할 수 없습니다. 제네릭은 <> 에 참조형 자료형만 가능하기 때문입니다. 그럼에도 기본형을 사용하고 싶다면 Wrapper 클래스를 이용하면 가능합니다.


기본형 변수와 Wrapper 클래스

기본형 변수를 제네릭으로 사용하려면 Wrapper 클래스를 지정해주면 됩니다. Wrapper 클래스는 다음과 같습니다.

Wrapper class
Boolean, Byte, Character, Short, Integer, Long, Float, Double

즉, 다음과 같이 사용할 수 있습니다.

Box<Integer> box = new Box<Integer>();
box.a = 10;

Box<Double> box2 = new Box<Double>();
box.a = 3.14;

추가로 , 만일 참조변수를 만들 때 자료형을 명시했다면 객체를 생성할 때는 자료형 명시를 하지 않아도 괜찮습니다.
Box<Integer> box = new Box<>();

또한 Box 클래스에는 제네릭이 설정되어 있는 상황에서 Box 의 객체를 생성할때는 <> 를 명시하지 않는다면 기본 Object 자료형으로 만들어 집니다.

Box box5 = new Box();
box5.a = new String("Object");
box5.a = new Integer(10);

메소드와 Generic

아까 말했듯, 제네릭을 사용하고자 할 때는 '멤버' 의 자료형이 정해지지 않았을 때 입니다. 메소드도 멤버의 일부분이기에 메소드의 자료형 또한 정해지지 않을 수 있습니다. 즉, 매개변수의 타입과 리턴 타입이 제네릭 타입으로 대체될 수 있습니다. 간단하게 보고 넘어가겠습니다.

---------------- Box.java
public class Box<T> {

	T a;
    
	void setA(T a){
    	this.a = a;
    }
    T getA() {
    	return this.a;
    }
}

---------------- Main.java
public class Main {
	public static void main(String[] args) {
    	Box<Integer> box = new Box<>();
        
        box.setA(10);
        int num = box.getA();
    }
}

두 개 이상의 자료형

만일, 객체 생성 시 결정해야 할 타입이 여러개 라면, 제네릭 또한 여러개로 설정해줄 수 있습니다. 예제보고 넘어갑시다.

-------------- Box.java
public class Box<T,K> {
	T a;
    K k;
}

-------------- Main.java
public static void main(String[] args) {
	Box<String, Integer> obj = new Box<>();
    obj.a = "hello";
    obj.b = 10;
    
    Box<int[],double[]> obj2 = new Box<>();
    obj2.a = new int[5];
    obj2.b = new double[5];
    
    obj2.a[0] = 10;
    obj2.b[0] = 3.14;
}


Collection API

자료구조를 구현한 Java 의 API 클래스들 : 대량의 데이터를 관리


Collection 인터페이스의 3가지 종류

List 계열과 Set 계열, Map 계열이 있습니다. 3가지 종류 모두 인터페이스 입니다. 그렇기에 바로 사용하는것이 아니라 이를 구현한 하위 클래스의 객체를 사용하는것 입니다. 먼저 List 인터페이스 부터 알아보겠습니다.

List : ArrayList , LinkedList , Vector

1. 순서대로 저장됩니다.

2. 인덱스 번호 있습니다.

3. 중복데이터를 허용합니다.

아래 그림을 잘 숙지합시다. List 는 객체들을 끌고 다니는 기차와 그 개념이 비슷합니다. (원래는 객체가 아니고 객체의 주솟값을 가진 참조변수입니다.) 각 열차 칸마다 번호가 있듯, List 에서도 인덱스가 존재합니다.


📌 ArrayList

먼저 List 인터페이스의 하위 클래스 중 하나인 ArrayList 의 기능과 특징들을 하나씩 살펴보겠습니다.

// 공통 코드
ArrayList<String> list = new ArrayList<>();

요소의 개수

int size = list.size();
System.out.println("요소 개수 : "+size);
// 출력결과 : 0

요소의 추가

list.add("aaa");
String s = new String("bbb");
list.add(s);
list.add("ccc");
System.out.println("요소 개수 : " + list.size());
// 출력결과 : 3

요소 얻어오기

System.out.println(list.get(0));
// 출력결과 : aaa

요소의 제거

list.remove(1);
System.out.println(list);
// 출력결과 : [aaa , bbb]

인덱스가 아닌 주솟값으로 요소 제거하기

String str = new String("TEST");
list.add(str);
list.remove(str);

요소 한꺼번에 제거하기

list.clear();
System.out.println(list.size());
// 출력결과 : 0

특정 위치에 요소 추가하기

list.add(0, "aaa");
System.out.println(list);
// 출력결과 : [aaa]

리스트에 특정요소가 있는지 여부

System.out.println(list.contains("aaa"));	
System.out.println(list.contains("Hello"));
// 출력결과 : true / false

리스트에 특정요소가 모두 포함되는지 여부

ArrayList<String> list2 = new ArrayList<String>();
list2.add("aaa");
System.out.println(list.containsAll(list5)); 
		
list2.add("kkk");
System.out.println(list.containsAll(list5)); 
// 출력결과 : true / false

리스트에 특정요소가 몇번째 인덱스인지 반환

list.add("bbb");
list.add("ccc");

System.out.println(list.indexOf("bbb"));
System.out.println(list.indexOf("aaa")); 
System.out.println(list.lastIndexOf("aaa"));

// 출력결과 : 1 / 0 / 0

중복 데이터 허용

list.add("aaa");
list.add("aaa");
list.add("aaa");
System.out.println("요소개수 : " + list.size());

// 출력결과 : 6

리스트가 비어있는지 여부

System.out.println(list.isEmpty());
list.clear();
System.out.println(list.isEmpty());

// 출력결과 : true / false

다른 리스트의 요소들 한번에 추가하기

list.add("aaa");
list.add("bbb");
list.add("ccc");

ArrayList<String> list2 = new ArrayList<String>();
list2.add("sam");
list2.add("robin");
		
list.addAll(list2);
System.out.println(list);
// 출력결과 : [aaa,bbb,ccc,sam,robin]

다른 리스트의 요소와 같은 요소들 모두 제거하기

ArrayList<String> list3 = new ArrayList<String>();
list3.add("bbb");
list3.add("sam");
		
list.removeAll(list3);
System.out.println(list);

// 출력결과 : [aaa,ccc,robin]

다른 리스트의 요소와 같은 요소들 제외하고 모두 제거하기

ArrayList<String> list4 = new ArrayList<String>();
list4.add("aaa");
list4.add("robin");
		
list.retainAll(list4);
System.out.println(list);

// 출력결과 : [aaa,robin]

요소들 순차적으로 얻어오기

  1. for 문 이용하기
	for(int i =0;i<list.size();i++)
	{
		String t = list.get(i);
		System.out.println(t);
	}
  1. 확장 for 문 이용하기
	for(String t : list) {
		System.out.println(t);
	}

List 를 배열로 변환

String[] aaa = new String[list.size()]; 
list.toArray(aaa); 
System.out.println(aaa.toString());
System.out.println(list);
System.out.println(Arrays.toString(aaa));

우선 변환하고자 하는 List 와 크기가 같은 빈 배열을 준비해서, toArray() 메서드를 사용해줍시다. 그러면 배열로 변하게 됩니다. 추가로, 배열의 요솟값을 toString() 처럼 확인하고 싶다면 Arrays.toString(aaa); 로 확인하면 됩니다.

배열을 List 로 변환

String[] b = new String[] { "sam", "robin", "hong" };
List<String> list6 = Arrays.asList(b);

📌 LinkedList

List 인터페이스를 구현한 또 다른 하위 클래스 입니다. 사용방법은 ArrayList 와 동일하나, 성능에 차이가 있습니다. 요소를 추가하거나 삭제할 때는 속도가 느리고, 특정요소값을 얻어올 때는 느리다고 합니다. 즉, 요소의 추가,삭제 기능이 빈번한 프로그램 혹은 로직에서는 ArrayList 자료구조를 사용하는것이 더 효율적이며 추가, 삭제 보다 데이터를 전달받는 경우가 빈번하다면 LinkedList 가 더 효율적일 것입니다. 상황에 따라 적절한 자료구조를 선택하는것이 좋겠습니다. LinkedList 의 기능들은 ArrayList 와 거의 동일하므로 아래 기능정도만 보도록 하겠습니다.

addFirst() 와 addLast()

요소들을 앞쪽에 추가하는 기능과 뒷쪽에 추가할 수 있는 기능입니다. 가볍게 보고 넘어가겠습니다.

LinkedList<String> linkli = new LinkedList<>();

linkli.addFirst("sam");
linkli.addLast("robin");

📌 Vector

ArrayList 와 완전히 같은 기능을 합니다. 다만, Vector 의 경우 동기화 처리가 되어 있습니다. 이부분은 Thread 를 배우고 난 뒤에 다시 한번 언급하도록 하겠습니다.


📌 업캐스팅

ArrayList, LinkedList, Vector 클래스 모두 List 인터페이스를 구현한 클래스 입니다. 즉, List 인터페이스는 위 3개 클래스의 부모가 됩니다. 부모 참조변수로 자식의 객체를 참조할 수 있으므로 다음과 같이 사용할 수 있습니다.

List<String> list = null;
list = new ArrayList<String>(); 
list = new LinkedList<String>();
list = new Vector<String>();

코드가 확장될 여지가 있고, 변경이 될 가능성이 있다면 업캐스팅을 활용하여 코드를 작성하는것이 유지보수하기가 유리해지는 부분도 있음을 알아둡시다.



Set : HashSet , TreeSet , LinkedHashSet

1. 순서와 상관없이 저장됩니다.

2. 인덱스 번호 없습니다.

3. 중복데이터를 허용하지 않습니다.

아래 그림을 잘 숙지합시다. Set 은 수학의 집합의 개념과 유사합니다. 집합의 경우 순서가 상관없으며 데이터의 유무가 중요합니다. Set 또한 마찬가지로 순서와 상관없이 저장되며 그렇기에 인덱스 번호도 없습니다. 또한 Set 은 중복데이터를 허용하지 않습니다.

우리가 흔히 볼수 있는 Set 중에는 블루투스와 관련된 것도 있습니다. 블루투스를 연결하고자 할때, 블루투스 리스트업이 화면에 표시됩니다. 이때는 블루투스 연결 가능 기기들의 리스트가 표시되는데 이 리스트는 중복이 없으며 순서도 상관없습니다. 즉, 이 리스트는 Set 이 활용된 예 입니다. 이러한 Set 에는 HashSet , TreeSet , LinkedHashSet 이 있습니다. 먼저 HashSet 부터 알아봅시다.


📌 HashSet

Set 중에서 성능이 가장 우수하다고 평가를 받는 Set 입니다. 앞서 배웠던 ArrayList 와 기능에서는 비슷하기에 필요한 부분만 알아봅시다.

// 공통 코드 
HashSet<String> set = new HashSet<String>();

요소추가, 요소개수, 요소값 확인

set.add(new String("aaa"));
set.add("bbb");
set.add("ccc");
set.add("ddd");
set.add("eee");

System.out.println(set.toString());

// 출력결과 : [aaa, ccc, bbb, eee, ddd]

add() 메서드를 통해 각 문자열 데이터를 저장시켰습니다. 문자열 데이터를 저장시킬 수 있는 이유는 앞에 있는 공통코드를 보면 알 수 있습니다. 제네릭 타입이 String 이기에 문자열을 저장할 수 있는거죠. 또한 출력결과에서 볼 수 있듯, Set에 저장된 순서는 유지되지 않음을 알 수 있습니다.

그러면 혹시 중복된 데이터들은 어떻게 처리할까요? ArrayList 에서는 중복을 허용하기 때문에 중복된 데이터도 그대로 리스트에 저장시킬 수 있었습니다. 다만 Set 에서는 중복을 허용하지 않기 때문에 데이터에 추가되지 않습니다.

요소값 얻어오기

Set 에서 요소값을 얻어오는 방법에는 3가지가 있습니다. 다만, 앞서 List 에서 사용했던 for 문의 경우 이용이 불가합니다. 그 이유는 for 문을 활용하기 위해서는 인덱스를 이용하여 각 인덱스에 맞는 데이터를 불러오는 작업이 for 문의 주 역할인데, Set 자료구조에는 인덱스의 개념이 없기 때문입니다. 그래서 다음 3가지의 방법으로 요소값을 얻어 옵니다.

  1. 확장된 for 문
for(String s : set) {
	System.out.println(s);
}
// 출력결과 : aaa / ccc / bbb / eee / ddd

앞서 배웠던 확장 for 문을 활용할 수 있습니다. 확장 for 문의 경우, 요소값을 인덱스와 상관없이 하나씩 받아 올 수 있기 때문에 인덱스가 없는 Set 에서도 사용이 가능합니다. 출력결과에서 볼 수 있듯, Set 은 저장된 순서가 유지되지 않음을 알 수 있습니다.

  1. iterlator(반복자) 활용!
Iterator<String> datas = set.iterator();
while(datas.hasNext()){
	String s = datas.next();
    System.out.println(s);
}
// 출력결과 : aaa / ccc / bbb / eee / ddd

iterator 는 보통 컬렉션 프레임워크의 값을 뽑아올 때 사용합니다. Set 뿐 아니라 List 와 Map 에서도 사용이 가능합니다. 다만, 인덱스가 없어 get() 을 사용할 수 없는 Set에서 주로 사용합니다.

  1. 배열로 변환
    .toArray() 메서드를 활용하여, set 자료구조를 배열로 변환하여 값을 얻어올 수 있습니다.
String[] aaa = new String[set.size()];
set.toArray(aaa);
System.out.println(aaa[0]);
System.out.println(aaa[1]);
System.out.println(aaa[2]);
// 출력결과 : aaa / ccc / bbb

📌 TreeSet

성능은 HashSet 보다 저평가를 받습니다. 다만, 무작위로 값이 저장되던 HashSet 과 달리 TreeSet 은 값이 오름차순으로 정렬되어 저장되는 특징을 가집니다.

오름차순 정렬

TreeSet<String> set2 = new TreeSet<String>();
set2.add("aaa");
set2.add("eee");
set2.add("ccc");
set2.add("kkk");
set2.add("bbb");
System.out.println(set2);
// 출력결과 : [aaa,bbb,ccc,eee,kkk]

📌 LinkedHashSet

저장된 순서와 무관하게 값을 가지던 Set 과 달리 LinkedHashSet 은 List 의 특징인 저장된 순서를 지켜줍니다. 다만 성능은 위 2가지 보다는 떨어집니다.

값 출력 확인

LinkedHashSet<String> set3 = new LinkedHashSet<String>();
set3.add(new String("aaa"));
set3.add("bbb");
set3.add("ccc");
set3.add("ddd");
set3.add("eee");
System.out.println(set3);
// 출력결과 : [aaa,bbb,ccc,ddd,eee]

📌 사용자 정의 클래스와 Set

앞선 예제들에서는 Set 의 요소로써 String 객체들을 활용해보았습니다. 그렇다면 내가 직접 만든 클래스의 객체들도 요소로 사용할수 있을것 같네요. 한번 활용해봅시다. 그리고 그 객체들의 중복체크는 어떻게 이루어지는지도 같이 확인해도록 합시다.

중복체크 기준

---------------- Main.java
HashSet<Person> people = new HashSet<Person>();
people.add(new Person("sam",20));
people.add(new Person("sam",20));

System.out.println(people.size());

---------------- Person.java
class Person {
	String name;
	int age;

	public Person(String name, int age) {
		this.name = name;
		this.age =age;
	}
}

사람의 시각에서 본다면 이름이 sam 이고 나이가 20살인 동일인물의 정보가 중복저장된것처럼 보입니다. 다만, 여기서는 서로 다른 객체로 존재하기 때문에 중복이라고 보지 않고 각기 다른 객체로 판단됩니다. 즉, 우리가 설정했던 sam 과 20의 데이터는 중요하지 않고 객체의 주솟값이 동일한지 아닌지로 중복을 판정하게 됩니다.

조금 더 자세히 보면, 내부적으로 중복된 값인지를 판단할 때, hashCode() 를 호출하여 리턴된 해시값과 equals() 메서드를 통해 중복을 판별합니다. 예를 들어 A 라는 객체가 set 에 저장되어 있고, B 라는 객체를 추가하고자 할때 A와 B의 중복을 판정하고자 한다면 B 객체의 hashCode() 메서드를 호출한 다음 리턴된 해시값을 가지고 equals() 메서드를 이용하여 A 객체의 해시코드와 비교합니다. 그래서 동일하다면 중복인것이고 아니라면 중복된게 아닌거죠. 위 예제에서도 new 연산자를 통해 서로 다른 객체를 만들어 주었기 때문에 중복이 아닌것입니다.

그렇다면 사용자 정의 클래스에서 주소값이 아닌 우리가 넣어준 값을 기준으로 비교하고 싶다면 어떤 방식을 이용해야할까요? String 클래스를 떠올리면 좋습니다. String 클래스의 경우 == 연산자로는 비교할 수 없습니다.(자동 new 연산자는 생각하지 않겠습니다.) 그래서 보통 equals() 를 통해 문자열의 값을 비교하는데요, 이는 String 클래스 내부에서 equals() 메서드가 오버라이드 되어있기에 값의 비교가 가능합니다. 원래 Object 클래스에서 equals() 메서드는 객체의 주솟값을 비교하도록 설계되어 있는데, 이를 String 클래스에서 재정의 한것입니다.

이와 마찬가지로 우리도 equals() 와 hashCode() 를 Person 클래스 내부에서 재정의 하여 사용하면 값을 통한 비교가 가능해집니다. 먼저 hashCode() 메서드의 재정의를 통해 나이가 같은지 확인합니다. 그리고 equals() 메서드를 통해 이름이 같은지 확인하고 같다면 중복처리가 가능해집니다.

class Person{
	String name;
	int age;
	
	@Override
	public int hashCode() {
		return this.age; 
	}
	
	@Override
	public boolean equals(Object obj) {
		Person p = (Person)obj;
		return this.name.equals(p.name);
		
	}
	public Person(String name, int age) {
		this.name = name;
		this.age =age;
	}
}


Map : HashMap , TreeMap , LinkedHashMap , HashTable

1. 순서와 상관없이 저장됩니다.

2. 인덱스 번호 없습니다.

3. 중복데이터를 허용하지 않습니다.

아래 그림을 잘 숙지합시다. Set 은 수학의 집합의 개념과 유사합니다. 집합의 경우 순서가 상관없으며 데이터의 유무가 중요합니다. Set 또한 마찬가지로 순서와 상관없이 저장되며 그렇기에 인덱스 번호도 없습니다. 또한 Set 은 중복데이터를 허용하지 않습니다.

Map 자료구조는 key - value 쌍으로 데이터를 저장하는 방식입니다. Map 역시 인터페이스 이기 때문에 바로 객체생성은 불가하고, 이를 구현한 하위 클래스의 객체 생성을 통해 활용해주어야 합니다.


📌 HashMap

가장 성능이 좋은 Map 입니다.

// 공통코드
HashMap<String,String> map = new HashMap<>();

요소추가(풋~), 삭제, 개수

map.put("name", "sam");
map.put("id", "melon");
map.put("pass", "1234");
map.put("address","seoul");

map.remove("address");

System.out.println(map.size());
// 출력결과 : 3

put() 메서드를 통해 키 값과 밸류 값을 전달해주어 데이터를 저장시킵니다. 또한 remove() 메서드에 파라미터로 키값을 전달해주면 키값과 데이터의 삭제가 가능합니다. 그리고 size() 메서드를 통해 요소의 개수를 얻어올 수 있습니다.

key 로 value 얻어오기

value 값은 get() 메서드를 통해 값을 얻어올 수 있습니다. index 값을 파라미터로 전달해서 get() 을 활용하던 List 와 달리 Map 은 파라미터로 키 값을 전달해줍니다. 그러면 키 값와 쌍으로 연결되어 있는 value 값을 얻어올 수 있습니다.

System.out.println(map.get("name"));
System.out.println(map.get("id"));
  • 키값의 중복과 데이터의 중복

다음 두 코드를 봅시다.

map.put("kkk","sam"); -- 1
map.put("kkk","hong"); -- 2

1번 코드는 sam 이라는 데이터를 kkk 키값으로 저장했습니다. 기존에 sam 이라는 데이터는 있지만, 키값이 다르기 때문에 다른 데이터로 판단합니다. 다만, 2번의 경우에는 키값이 동일하나 데이터의 값이 다른 경우 입니다. 이 경우에는 키값이 동일하므로 중복이라고 판단하여 기존의 값에 덮어씌워 지게 됩니다.

순서대로 value 값 얻어오기

앞선 List 나 Set 과 다르게 값을 얻어오는 방법이 한정적입니다. 먼저 인덱스 번호가 없기 때문에 for 문을 이용한 방법은 사용할 수 없습니다. 또한 확장 for 문도 불가합니다. Map 에서는 value 값을 얻어올 때 key 값에 접근해서 그에 맞는 value 값을 찾아야 하는데, 확장 for 문은 내부적으로 key 값에 접근할 수 있는 방법이 없다고 합니다. 그래서 다음과 같은 방법을 이용해야 합니다.

  1. Key 값을 Set 객체로 얻어와 반복문 활용
    먼저 key 값을 keySet() 메서드를 사용해서 set 객체로 넣어줍시다.
    `Set keys = map.keySet();
  • key 값을 가진 Set 컬렉션 객체를 반복문으로 접근
for(String key : keys) {
	System.out.println(map.get(key));
}
  • key 값을 가진 Set 컬렉션 객체를 iterator 로 접근
Iterator<String> datas = keys.iterator();
while(datas.hasNext()) {
	String k = datas.next();
    System.out.println(k);
}
  1. Map 객체를 Set 객체로 변환하여 접근
    Map 객체를 Set 객체로 변환할 수 있을까요? Map 객체에는 key 값과 value 값이 쌍으로 들어있는데 어떻게 Set 객체로 변환할 수 있을까요? Entry 인터페이스와 entrySet() 메서드를 통해 할 수 있습니다. 설명 보다 코드를 봅시다.
Set<Entry<String,String>> entries = map.entrySet();

Entry<String,String> 제네릭 타입을 가진 Set 클래스 입니다. 참조변수 entries 에 map.entrySet() 의 리턴값을 담아주는 코드 입니다.

for(Entry<String,String> e : entries) {
	System.out.println(e.getKey() + " : " + e.getValue());
}
// 출력결과
pass : 1234
name : sam
kkk : hong
id : CHA

확장 for 문을 이용하여 Set 컬렉션 entries 의 요솟값들(Entry<String,String>) 에 접근이 가능합니다. 그래서 getKey() 와 getValue() 메서드를 통해 값을 얻어올 수 있습니다.


📌 TreeMap

TreeSet 과 비슷한 특징을 가집니다. TreeMap 은 키값을 오름차순으로 정렬하며 성능은 중간정도의 성능을 보입니다.

TreeMap<String,String> map = new TreeMap<>();
map.put("name", "sam"); // (식별자, 값)
map.put("id", "melon");
map.put("pass", "1234");
System.out.println(map);
// 출력결과 : {id=melon, name=sam, pass=1234}

📌 LinkedHashMap

LinkedHashSet 과 비슷한 특징을 가집니다. LinkedHashMap 은 저장된 순서대로 저장이 가능합니다만 성능은 제일 안좋습니다.

LinkedHashMap<String,String> map = new LinkedHashMap<>(); 
map.put("name", "sam"); 
map.put("id", "melon");
map.put("pass", "1234");
System.out.println(map);
// 출력결과 : {name=sam, id=CHA, pass=1234}

📌 HashTable

HashTable 의 특징은 동기화처리가 되어있다는 점입니다. 이는 Thread 를 배운 뒤 다시 언급합시다.


📌 key 값은 String 뿐이 아니다!

앞서 봤던 예제들에서는 key 값을 String 으로만 처리했습니다. 물론 당연하게도 정수 숫자로도 가능합니다. 다만, 정수숫자의 경우 인덱스와 개념이 비슷하기 때문에 그냥 List 를 사용하는편이 나을것 같습니다. 또한 사용자 정의 클래스를 key 값으로 사용하는것도 가능합니다. 다만 사용이 가능하다일뿐 key 값을 사용할 이유가 없어질것 같으니 알아만 둡시다.


📌 Collections 클래스의 유용한 static 기능 메소드

Collections.sort();

ArrayList<String> datas = new ArrayList<>();
datas.add("nice");
datas.add("world");
datas.add("ANDROID");
datas.add("pI");
datas.add("with");

System.out.println(datas);
Collections.sort(datas);
System.out.println(datas);

// 출력결과 
[nice, world, ANDROID, pI, with]
[ANDROID, nice, pI, with, world]

Collections.sort() 를 이용하면 데이터를 정렬할 수 있습니다. 이는 실제 값이 정렬이 되는것이며 오름차순으로 정렬됩니다.

Collections.shuffle();

ArrayList<String> datas = new ArrayList<>();
datas.add("nice");
datas.add("world");
datas.add("ANDROID");
datas.add("pI");
datas.add("with");

System.out.println(datas);
Collections.shuffle(datas);
System.out.println(datas);

// 출력결과 
[nice, world, ANDROID, pI, with]
[world, with, nice, ANDROID, pI]

Collections.shuffle() 를 이용하면 데이터를 무작위로 배치할 수 있습니다. 이는 마찬가지로 실제 값이 정렬이 되는것이며 실행시 마다 값이 바뀝니다.

profile
Developer

0개의 댓글