: 문자열 리터럴(값)이 동일하다면 String 객체를 공유하게 되어 있다.
String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true (리터럴 풀에서 공유됨)
비교기준(String).equals(String s) : boolean
.substring(int beginIndex) : String

.substring(int beginIndex, int endIndex) : String
🚫 주의 : beginIndex 부터 endIndex - 1 까지 반환

.replace(char oldChar, char newChar) : String

.split("나누는 기준") : String[]
⭕ String타입을 charAt을 쓰지않고 원소 하나씩 분리하는 방법 = .split("")
String arr = "abbabbacc";
String[] arr1 = arr.split("b");
System.out.println(Arrays.toString(arr1)); //결과 : [a, , a, , acc]
String[] arr2 = arr.split("");
System.out.println(Arrays.toString(arr2)); //결과 : [a, b, b, a, b, b, a, c, c]
✅ 특정 문자열이 시작하는 첫 인덱스를 반환하고 없으면 -1 반환
✅ 매개변수 int ch는 아스키코드다
indexOf( ) : int
Integer.parseInt(String s) : int
Double.parseDouble(String s) : double
Boolean.parseBoolean(String s) : boolean
Long.parseLong(String s) : long
String.valueOf(char, bloolean, int, float, double, char[]) : String
String greet= "안녕하세요";
greet.valueOf(...) //이것도 가능하지만 이렇게 쓸 일이 거의 없음..
//String.valueOf()
greet = String.valueOf(..) //이렇게 다른 자료형을 문자열로 변환하여 return 값 받는 경우가 많아섭
1. String.valueOf(char ch 또는 char[] chArray) : String
2. Character.toString(char ch) : String
3. ""
🚫 Character.toString(char ch)
: char[]은 안되기 때문에 길이가 1개인 String만 반환하는 격이다.
// ""이용하기
##특수문자도 공백도 포함됨
1. .charAt(int index) : char
2. .toCharArray() : char[]
⭕ String을 String[]로 하고 싶다면 .split("")을 사용하는게 나음
1. 반복문 사용 // int[] 이거면 int에 접근하기 때문에 가능한건
2. Arrays.toString()
✅ 둘 다 참조 자료형이다
참조 자료형은 실제 데이터가 힙(heap) 에 저장되고, 변수는 그 데이터를 참조하는 주소(참조값) 를 가지고 있어.
System.out.println(str);
이런 식으로 String을 출력하면, 내부적으로 str.toString()이 호출돔.
그런데 String 클래스는 Object 클래스의 toString()을 오버라이딩 해서, 사람이 읽을 수 있는 문자열을 반환하게 만들어져 있다.
String str = "hello";
System.out.println(str); // 결과: hello
→ 내부적으로 str.toString() 호출
→ String 클래스의 오버라이딩된 toString()이 실행
→ 실제 문자열이 출력됨
반면, 배열은 객체이긴 하지만 toString()을 오버라이딩하지 않았기 때문에, Object 클래스의 기본 toString()이 호출된다.
Object의 기본 toString()은 → 클래스명 + "@" + 해시코드(16진수)
int[] arr = {1, 2, 3};
System.out.println(arr);
// 결과: [I@15db9742 같은 이상한 값이 출력됨
→ arr.toString() 호출
→ 배열 클래스는 Object의 기본 toString을 사용
→ 그래서 이상한 "주소 비슷한" 해시값이 나옴
for (int i : arr) {
System.out.print(i + " ");
}
import java.util.Arrays;
System.out.println(Arrays.toString(arr));
// 결과: [1, 2, 3]
🔍 요약
자료형 toString 오버라이딩 여부 출력 결과
String ✅ (오버라이딩함) 문자열 자체 출력
Array ❌ (기본 toString 사용) 클래스명@해시코드 출력
자바의 오토박싱, 언박싱, 그리고 객체의 toString() 동작 방식때문에
Integer[] 배열도 for문으로 돌리면 각 요소가 Integer 객체고, System.out.print()는 그 객체의 toString()을 호출해서 출력함.
✳️ Integer는 참조형, 그런데 왜 출력 잘되는가?
Integer[] nums = {1, 2, 3};
for (Integer num : nums) {
System.out.print(num + " ");
}
➡ 여기서 중요한 건 num은 Integer 객체지만
System.out.print(num)을 하면 자바가 내부적으로 이렇게 동작함:
🔁 내부 동작
System.out.print(num);
// 실제로는 -> System.out.print(num.toString());
즉, Integer 클래스는 toString()을 오버라이딩해서 숫자를 문자열로 반환하도록 구현되어 있음!
🧠 참고: Integer.toString() 오버라이딩 확인
Integer 클래스 내부 일부:
public String toString() {
return String.valueOf(value);
}
→ value는 내부에 저장된 int 값이야
→ 그래서 "1", "2", "3" 이렇게 나오는 거지!
int[] arr = {1, 2, 3};
System.out.println(arr);
// => [I@15db9742 (이상한 주소)
Integer[] boxedArr = {1, 2, 3};
System.out.println(boxedArr);
// => [Ljava.lang.Integer;@1b6d3586 (이것도 이상함)
for (int n : arr) System.out.print(n); // 123
for (Integer n : boxedArr) System.out.print(n); // 123 ✅
→ 둘 다 반복문 쓰면 잘 출력되는데
→ 그 이유는: 값 자체를 출력하니까 toString()이 동작함
클래스 toString() 오버라이딩 여부 출력 예시
String ✅ 있음 "hello"
Integer ✅ 있음 "42"
Double, Float, Long 등 ✅ 있음 "3.14", "100L"
ArrayList ✅ 있음 "[1, 2, 3]"
HashMap ✅ 있음 "{key=value}"
LocalDate, LocalDateTime ✅ 있음 "2025-04-17" 등
정수 : 0 , boolean: , 참조: null, 실수:
: 배열은 참조자료형이라서 대입을 하면 주소값이 복사된다.
int[] arr1 = {1,2,3,4};
int[] answer = {0};
answer = arr1
주소값이 복사되면 arr1과 answer은 같은 객체를 가르키는 것이기때문에 arr1을 수정하면 answer도 수정하게 된다.
1) 변경하고자 하는 길이를 가진 새로운 객체 만들기
2) for문 사용하여 내용 복사
for문 써서
Arrays.copyOf(복사할 배열, 배열길이)
int[] a1 = new int[]{1,2,3}
int[] a2 = Arrrays.copyof(a1, a1.length)
int[][] arr = {{3,4}, {2,3}, {3,5}}
: 경험상 Array.sort()를 사용하게 되면 안정정렬과 불안정정렬로 나눠지는데 안정정렬로 하게 되면 같은값일때 인덱스가 유지된다. 그래서 인덱스가 필요한 경우 int[] -> integer[]
https://zkvn1103.tistory.com/13
int[] arr = {1,2,3,4,5};
// int[] -> Integer[]
Integer[] arr2 = Arrays.stream(arr).boxed().toArray(new IntFunction<Integer[]>() {
@Override
public Integer[] apply(int value) {
return new Integer[value];
}
});
System.out.println(Arrays.toString(arr2));
// Integer[] -> int[]
int[] arr3 = Arrays.stream(arr2).mapToInt(i->i).toArray();
System.out.println(Arrays.toString(arr3));
int ↔ Integer : 박싱/언박싱으로 자동 변환 가능
int[] ↔ Integer[] : 자동 변환 ❌ (직접 변환해야 함)

Arrays.sort(int[], char[], String[] ,,,,)
기본자료형 오름차순
Arrays.sort(배열)
기본자료형 내림차순
// int[] 안됨 , String[] 됨
int[] arr2 = {1, 3, 2};
Arrays.sort(arr2, Comparator.reverseOrder()); // 에러
String[] arr = {"banana", "apple", "cherry"};
Arrays.sort(arr, Comparator.reverseOrder());
Arrays.sort(T[] a, Comparator<? super T> c)
Comparator 배열의 타입이 객체여야 함 그래서 기본자료형은 안됨
🤔 그럼 Comparator.reverseOrder()랑 Collections.reverseOrder()는 뭐가 달라?
사실상 거의 같음. 내부적으로 Collections.reverseOrder()는 Comparator.reverseOrder()를 리턴해주는 식으로 구현되어 있어. 요즘은 Comparator.reverseOrder()를 더 많이 쓰는 추세야.
int[] primitiveArr = {3, 1, 2};
Integer[] arr = Arrays.stream(primitiveArr).boxed().toArray(Integer[]::new);
Arrays.sort(arr, Comparator.reverseOrder());
Arrays.stream(primitiveArr) // 1단계: int[] → IntStream
.boxed() // 2단계: IntStream → Stream
.toArray(Integer[]::new); // 3단계: Stream → Integer[]
int[] arr = new int[] { 2, 5, 1, 4, 3 };
// 기본자료형 오름차순 정렬
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
// 기본자료형 내림차순 정렬
// Comparator.reverseOrder()안됨 (문자열은 됨)
// Arrays.sort(arr, Comparator.reverseOrder());
String[] names = {"최길동", "박길동", "홍길동", "김길동"};
Arrays.sort(names);
System.out.println("문자열 오름차순-----------------");
System.out.println(Arrays.toString(names));
System.out.println("문자열 내림차순-----------------");
Arrays.sort(names, Collections.reverseOrder());
System.out.println(Arrays.toString(names));
// 기본자료형을 내림차순으로 정렬하기 위해 int -> Integer로 변환
Integer[] arr2 = Arrays.stream(arr).boxed().toArray(Integer[]::new);
System.out.println("정수 내림차순--------------------");
Arrays.sort(arr2, Collections.reverseOrder());
System.out.println(Arrays.toString(arr2));
// 정렬알고리즘 응용
// Map 배열을 정렬해서 출력
Map<String, Object> map = new HashMap<>();
map.put("name", "박길동");
map.put("score", 60);
Map<String, Object> map2 = new HashMap<>();
map2.put("name", "김길동");
map2.put("score", 80);
Map<String, Object> map3 = new HashMap<>();
map3.put("name", "이길동");
map3.put("score", 100);
Map<String, Object> map4 = new HashMap<>();
map4.put("name", "최길동");
map4.put("score", 70);
List<Map> list = new ArrayList<>();
list.add(map);
list.add(map2);
list.add(map3);
list.add(map4);
Collections.sort(list, new Comparator<Map>() {
@Override
public int compare(Map o1, Map o2) {
// return (int)o2.get("score") - (int)o1.get("score"); // 내림차순
return (int) o1.get("score") - (int) o2.get("score"); // 오름차순
}
});
list.stream().forEach(m -> System.out.println(m));