[Java] Chapter2-2. 자주 쓰는 자료형
Chapter2-2. 자주 쓰는 자료형
자주 쓰이는 자료형
int, long, double, boolen, char, String, StringBuffer, List, Map, Set
원시(primitive) 자료형
int, long, double, float, boolean, char
이 있고,
new 키워드로 그 값을 생성할 수 없다. 오직 리터럴로만 값을 세팅할 수 있다.
원시 자료형의 Wrapper 클래스
int, long, double, float, boolean, char
등의 원시 자료형은 다음처럼 각각에 대응하는 Wrapper 클래스들이 존재한다.
| 원시자료형 | Wrapper 클래스 |
| --- | --- |
| int | Integer |
| long | Long |
| double | Double |
| float | Float |
| boolean | Boolean |
| char | Char |
앞으로 공부할 ArrayList, HashMap, HashSet 등은 데이터 저장시 원시 자료형 대신 그에 대응하는 Wrapper 클래스들을 사용해야 한다. 원시 자료형 대신 Wrapper 클래스를 사용하면 값 대신 객체를 주고 받을 수 있어 코드를 객체 중심적으로 작성하는데 유리하다. 또한 멀티스레딩 환경에서 동기화를 지원하기 위해서는 Wrapper 클래스가 반드시 필요하다.
String
문자열 표현 방법
String a = "Happy Java"; # 리터럴 표기
String a = new String("Happy Java"); # 객체 생성
❓ 리터럴 표기
String a = "happy java"
와String a = new String("happy java")
는 같은 값을 갖게 되지만 완전히 동일하지는 않다. 첫번째 방식을 리터럴(literal) 표기라고 하는데 객체 생성없이 고정된 값을 그대로 대입하는 방법을 말한다. 위 예에서 리터럴 표기법은 “happy java” 라는 문자열을 intern pool 이라는 곳에 저장하고 다음에 다시 동일한 문자열이 선언될때는 cache 된 문자열을 리턴한다. 두번째 방식은 항상 새로운 String 객체를 만든다.
String 메서드
1) equals()
두 개의 문자열이 동일한지 비교하여 결과를 리턴한다.
String a = "hello";
String b = new String("hello");
System.out.println(a.equals(b)); // true
System.out.println(a == b); // false
나머지 함수들은 ⇒ https://wikidocs.net/205 참고!
StringBuffer
StringBuffer는 문자열을 추가하거나 변경 할 때 주로 사용하는 자료형이다.
StringBuffer 메서드
1) append()
StringBuffer sb = new StringBuffer(); // StringBuffer 객체 sb 생성
sb.append("hello");
sb.append(" ");
sb.append("jump to java");
String result = sb.toString(); // String 자료형으로 변경
System.out.println(result);
//"hello jump to java"
String result = "";
result += "hello";
result += " ";
result += "jump to java";
System.out.println(result);
//"hello jump to java"
2) insert()
StringBuffer sb = new StringBuffer();
sb.append("jump to java");
sb.insert(0, "hello ");
System.out.println(sb.toString());
//"hello jump to java"
3) substring()
StringBuffer sb = new StringBuffer();
sb.append("Hello jump to java");
System.out.println(sb.substring(0, 4));
//"Hell"
❓ String 자료형은 한번 값이 생성되면 그 값을 변경할 수가 없다. 이렇게 값을 변경할 수 없는 것을 immutable 하다고 한다. trim, toUpperCase 등의 메소드를 보면 문자열이 변경되는 것 처럼 생각 될 수도 있지만 해당 메소드 수행 시 또 다른 String 객체를 생성하여 리턴할 뿐이다. 하지만 StringBuffer는 이와 반대로 값을 변경할 수 있다(mutable 하다). 즉 한번 생성된 값을 언제든지 수정할 수 있다.
❓ 무조건 StringBuffer를 사용하는 것이 좋을까?
그건 상황에 따라 다르다. StringBuffer 자료형은 String 자료형보다 무거운 편에 속한다.new StringBuffer()
로 객체를 생성하는 것은 일반 String을 사용하는 것보다 메모리 사용량도 많고 속도도 느리다. 따라서 문자열 추가나 변경등의 작업이 많을 경우에는 StringBuffer를, 문자열 변경 작업이 거의 없는 경우에는 그냥 String을 사용하는 것이 유리하다.
Array
배열이란 자료형의 종류가 아닌 자료형의 집합을 의미한다.
-
배열의 크기는 고정되어 있다.
String[] weeks = new String[7];
- 배열의 길이는
arr.length
을 사용한다. -
Arrays와 자주 쓰이는 메소드들은 알아두자!
Arrays.asList(arr), Arrays.toString(), Sort(arr), Sort(arr, comparator) 등
List (Interface) - ArrayList
리스트는 배열과 비슷한 자바의 자료형이고, 배열의 가장 큰 차이는 크기가 정해져 있지 않고 동적으로 변한다는 점이다.
✅ List 자료형
List 자료형에는 ArrayList, Vector, LinkedList 등의 List 인터페이스를 구현한 자료형이 있다. 여기서 말하는 List 자료형은 인터페이스인데 인터페이스에 대해서는 뒤에서 자세히 다루도록 한다.
ArrayList
// 생성 및 기본 메소드
import java.util.ArrayList;
public class Sample {
public static void main(String[] args) {
**ArrayList pitches = new ArrayList(); //ArrayList 생성**
pitches.**add**("138"); // 원소 추가하는 메소드
pitches.**add**("129");
pitches.**add**("142");
System.out.println(pitches.**get**(1)); // 특정 인덱스의 값 가져오는 메소드
System.out.println(pitches.**size**()); // ArrayList의 길이를 리턴하는 메소드
System.out.println(pitches.**contains**("142")); // 리스트안에 해당 항목의 유무 판별
System.out.println(pitches.**remove**("129")); // 객체를 삭제하고 성공시 true, 실패시 false 리턴
System.out.println(pitches.**remove**(0)); // 해당 인덱스의 항목을 삭제하고, 삭제한 항목을 리턴
}
}
ArrayList와 자주 쓰이는 메소드
1) asList
ArrayList 생성 시, 이미 데이터가 존재할 경우에 java.util.Arrays 클래스의 asList 메소드를 사용하면 이미 존재하는 문자열 배열로 ArrayList를 생성할 수 있다.
import java.util.ArrayList;
***import java.util.Arrays;***
public class Sample {
public static void main(String[] args) {
String[] data = {"138", "129", "142"}; // 이미 투구수 데이터 배열이 있다.
ArrayList<String> pitches = new ArrayList<>(***Arrays.asList(data)***);
ArrayList<String> pitches_1 = new ArrayList<>(***Arrays.asList("138", "129", "142")***);
System.out.println(pitches); // [138, 129, 142] 출력
}
}
2) String.join()
//ArrayList 객체를 join하는 경우
ArrayList<String> pitches = new ArrayList<>(Arrays.asList("138", "129", "142"));
String result = String.**join**(",", pitches);
// 문자열 배열을 join하는 경우
String[] pitches = new String[]{"138", "129", "142"};
String result = String.**join**(",", pitches);
3) List.sort()
import java.util.ArrayList;
import java.util.Arrays;
***import java.util.Comparator;***
public class Sample {
public static void main(String[] args) {
ArrayList<String> pitches = new ArrayList<>(Arrays.asList("138", "129", "142"));
***pitches.sort(Comparator.naturalOrder());*** // 오름차순으로 정렬
System.out.println(pitches); // [129, 138, 142] 출력
}
}
Map (Interface) - HashMap
맵(Map)은 Key와 Value를 한 쌍으로 갖는 자료형이다. Associative array, Hash라고도 불리며, 맵은 사전(dictionary)과 비슷하다. Map은 리스트나 배열처럼 순차적으로(sequential) 해당 요소 값을 구하지 않고 key를 통해 value를 얻는다.
✅ Map 역시 List와 마찬가지로 인터페이스이다. Map 인터페이스를 구현한 Map자료형에는 HashMap, LinkedHashMap, TreeMap등이 있다. 인터페이스에 대해서는 객체지향 챕터에서 자세하게 다룰 것이다.
HashMap
//생성 및 기본 메소드
***import java.util.HashMap;***
public class Sample {
public static void main(String[] args) {
HashMap<**String, String**> map = new HashMap<>(); // 제네릭스 이용
map.**put**("people", "사람"); // map에 항목 추가
map.**put**("baseball", "야구");
System.out.println(map.**get**("people")); // key에 대한 value 리턴, 없으면 null
System.out.println(map.**containsKey**("people")); // 맵(Map)에 해당 키(key)가 있다면 true, 없다면 false
System.out.println(map.**remove**("people")); // 맵(Map)의 항목을 삭제 후, 그 value 값을 리턴
System.out.println(map.**size**()); // Map의 갯수를 리턴
System.out.println(map.**keySet**()); // 맵(Map)의 모든 Key를 모아서 리턴(set)
}
}
✅ LinkedHashMap과 TreeMap
Map의 가장 큰 특징은 순서에 의존하지 않고 key로 value를 가져오는데 있다. 하지만 가끔은 Map에 입력된 순서대로 데이터를 가져오고 싶은 경우도 있고 때로는 입력된 key에 의해 소트된 데이터를 가져오고 싶을 수도 있을 것이다. 이런경우에는 LinkedHashMap과 TreeMap을 사용하는 것이 유리하다.
- LinkedHashMap은 입력된 순서대로 데이터를 저장하는 특징을 가지고 있다.
- TreeMap은 입력된 key의 오름차순 순서로 데이터를 저장하는 특징을 가지고 있다.
Set (Interface) - HashSet
집합(Set) 자료형은 집합과 관련된 것을 쉽게 처리하기 위해 만든 자료형이다.
- 중복을 허용하지 않는다.
- 순서가 없다(Unordered).
✅ Set 자료형
Set 자료형에는 HashSet, TreeSet, LinkedHashSet 등의 Set 인터페이스를 구현한 자료형이 있다. 여기서 말하는 Set 자료형은 인터페이스인데 인터페이스에 대해서는 뒤에서 자세히 다루도록 한다.
HashSet
import java.util.Arrays;
***import java.util.HashSet;***
public class Sample {
public static void main(String[] args) {
**HashSet**<String> set = new **HashSet**<>();
set.**add**("Jump"); //값을 추가
set.**add**("To");
set.**add**("Java");
set.**addAll**(Arrays.asList("To", "Java")); //여러 개의 값을 한꺼번에 추가
set.**remove**("To"); //특정 값을 제거
}
}
교집합, 합집합, 차집합
import java.util.Arrays;
**import java.util.HashSet;**
public class Sample {
public static void main(String[] args) {
HashSet<Integer> s1 = new HashSet<>(Arrays.asList(1, 2, 3, 4, 5, 6));
HashSet<Integer> s2 = new HashSet<>(Arrays.asList(4, 5, 6, 7, 8, 9));
HashSet<Integer> **intersection** = new HashSet<>(s1); // s1으로 intersection 생성
**intersection**.**retainAll**(s2); // 교집합 수행
System.out.println(intersection); // [4, 5, 6] 출력
HashSet<Integer> **union** = new HashSet<>(s1); // s1으로 union 생성
**union.addAll(s2);** // 합집합 수행
System.out.println(union); // [1, 2, 3, 4, 5, 6, 7, 8, 9] 출력
HashSet<Integer> **substract** = new HashSet<>(s1); // s1으로 substract 생성
**substract.removeAll(s2);** // 차집합 수행
System.out.println(substract); // [1, 2, 3] 출력
}
}
✅ TreeSet과 LinkedHashSet
Set 자료형은 순서가 없다는 특징이 있다. 하지만 가끔은 Set에 입력된 순서대로 데이터를 가져오고 싶은 경우도 있고 때로는 오름차순으로 정렬된 데이터를 가져오고 싶을 수도 있을 것이다. 이런경우에는 TreeSet과 LinkedHashSet을 사용한다.
- TreeSet - 오름차순으로 값을 정렬하여 저장하는 특징이 있다.
- LinkedHashSet - 입력한 순서대로 값을 정렬하여 저장하는 특징이 있다.
제네릭스 (Generics)
자바는 J2SE 5.0 버전 이후부터
ArrayList<**String**> pitches = new ArrayList<String>();
ArrayList<**String**> pitches = new ArrayList<>(); // 선호되는 방식
처럼 객체를 포함하는 자료형도 어떤 객체를 포함하는지에 대해서 명확하게 표현할 것을 권고하고 있다.
// 사용하지 않는 경우
ArrayList pitches = new ArrayList();
aList.add("138");
aList.add("129");
String one = (String) pitches.get(0);
String two = (String) pitches.get(1);
// 사용하는 경우
ArrayList<**String**> pitches = new ArrayList<>();
aList.add("138");
aList.add("129");
String one = pitches.get(0); // 형 변환이 필요없다.
String two = pitches.get(1); // 형 변환이 필요없다.
댓글남기기