[Java] String, 배열, 복사, 컬렉션

CountryGirl·2023년 5월 24일
0

Java

목록 보기
3/19
post-thumbnail

작심삼일
오늘만 지나면 작심삼일 이겨내는거야!!!!

📌 String

((( 번 외 )))

기본형 변수vs참조형 변수
소문자로 시작함vs대문자로 시작함
값 자체를 저장vs별도의 공간에 값을 저장한 후 그 주소를 저장함

💪🏻 String 기능 활용

length

: String의 길이를 알 수 있는 메서드

String str = "ABCD";

int strLength = str.length();
System.out.println(strLength);		//  OUTPUT: 4

charAt(int index)

: String으로 저장된 문자열 중에서 한 글자만 char로 바꾸어주는 메서드
: ( ) 소괄호 안에 index를 넣어주면 그 해당 index의 문자를 알 수 있다.

String str = "ABCD";

char strChar = str.charAt(1);
System.out.println(strChar); 		//  OUTPUT: B

substring(int fromidx, int toidx)

: 슬라이싱(잘라주는) 메서드

String str = "ABCD";

String strSub = str.substring(0, 3);
System.out.println(strSub); 		//  OUTPUT: ABC

🚨 주의 🚨
'substring(0, 3)이면 D까지 나와야하는거 아냐?' 라고 생각하기 쉽다.
0부터 3개만 자른다고 생각하면 이해하기 편하다. 0부터 3개니까 0, 1, 2번째이다.

equals(String str)

: 문자열이 같은지 비교해주는 메서드
: 비교하는 메서드이므로 결과값으로 True / False 가 나온다.

String newStr1 = "ABCD";
String newStr2 = "AVCD";

boolean strEqual1 = newStr1.equals(str);
boolean strEqual2 = newStr2.equals(str);

System.out.println(strEqual1);		//  OUTPUT: true
System.out.println(strEqual2);		//  OUTPUT: false

toCharArray()

: 문자열(String)을 문자배열(char Array)로 바꾸어주는 메서드

String str = "ABCD";

char[] strCharArray = str.toCharArray();
System.out.println(strCharArray.getClass());	//  OUTPUT: class [C
System.out.println(strCharArray);				//  OUTPUT: ABCD

char[] ➡️ String

: 문자배열(char Array)을 문자열(String)로 바꾸어주는 방법
: 따로 메서드는 없으나 쉽게 바꿀 수 있다

char[] charArray = {'A', 'B', 'C', 'D', 'F'};

String charArrayString = new String(charArray);
System.out.println(charArrayString.getClass()); 	//  OUTPUT: class java.lang.String
System.out.println(charArrayString);				//  OUTPUT: ABCDF

메서드 없이 String charArrayString = new String(charArray);를 하면 쉽게 바꿀 수 있다


📌 배열

int 와 같은 기본형 변수는 1개의 값만 변수에 저장할 수 있다면 int[]와 같은 배열형 변수는 여러개를 변수에 저장할 수 있다

  • 한 번에 많은 양의 데이터를 다루거나 계산할 때 사용한다.
  • 선언방법은 2가지가 있다
    1. 타입[ ] 변수; -> int[] intArray;
    2. 타입 변수[ ]; -> int intArray[];

순회 : 배열의 값을 하나씩 뽑아서 조회한다.

💪🏻 자료형에 따른 배열

  • int[] intArray; : 정수 배열
  • long[] longArray;
  • double[] doubleArray; : 실수 배열
  • char[] charArray; : 문자 배열
  • String[] StringArray; : 문자열 배열

  • int intArray[]; : 정수 배열
  • long longArray[];
  • double doubleArray[]; : 실수 배열
  • char charArray[]; : 문자 배열
  • String StringArray[]; : 문자열 배열

참조형 변수들처럼 `new`명령어를 통해서 생성을 한다. 생성될 때 각 타입별 초기값으로 초기화가 되어 채워진다.

초기값

  • int : 0
  • Boolean : false
  • String : null
int[] intArray = new int[3]; 			// {0, 0, 0}
boolean[] boolArray = new boolean[3]; 	// {false, false, false}
String[] stringArray = new String[3]; 	// {"", "", ""}

  • fill : 배열을 모두 같은 값으로 초기화
Arrays.fill(intArray2, 1);
System.out.println(Arrays.toString(intArray2));		// OUTPUT : [1, 1, 1, 1, 1]

💪🏻 2차원 배열

2차원 배열 선언

  • int[][] array
  • int array[][]
  • int[] array[]

2차원 배열 생성

  • int[][] array = new int[][];

2차원 배열 초기화

  • 중괄호 사용해 초기화
    int[][] array = {{1, 2, 3}, {4, 5, 6}};
  • 반복문을 통해 초기화
// 방법 1
int[][] array = {
        {10, 20},
        {10, 20, 30, 40},
        {10}
};

// 방법 2
int[][] array = new int[3][];

array[0] = new int[2];
array[1] = new int[4];
array[2] = new int[1];

2차원 배열을 생성할 때 열의 길이를 생략할 수 있다.
행마다 가변적으로 각각 다른 길이의 행을 지정할 수 있다.


📌 복사

💪🏻 얕은 복사

  • 배열 변수간에 대입 연산자 = 를 사용해서 복사를 하게 되면 주소값만 복사된다
    ➡️ 주소값만 복사되고 실제값은 1개로 유지되는 것
  • 주소값만 복사 ? 변수명은 서로 다르지만 같은 값을 보고 있다
    arr2 값을 바꾸면 arr1에도 영향이 간다. 같은 값을 바라보고 있기 때문에
int[] a = {1, 2, 3, 4};
int[] b = a;

b[0] = 3;

System.out.println("a[0] : " + a[0]);		// OUTPUT : a[0] : 3
System.out.println("b[0] : " + b[0]);		// OUTPUT : b[0] : 3

그러므로 배열 a의 값도 바뀐 것을 확인할 수 있다!

💪🏻 깊은 복사

  • 앝은 복사처럼 가짜 복사가 아니라 진짜 새로운 배열을 만들고 싶을 때
  • 실제 값을 가지고 있는 배열의 기본형 값을 꺼내서 복사
  • 방법
    1. 반복문 for 문을 통해서 하나씩 꺼내서 복사해주는 방법
    2. 메서드 사용하는 방법
  1. for 문을 이용한 방법

    int[] a = {1, 2, 3, 4};
    int[] b = new int[a.length];
    
    for (int i = 0; i < a.length; i++) {
        b[i] = a[i];
    }
    
    b[0] = 3;
    
    System.out.println("a[0] : " + a[0]);		// OUTPUT : a[0] : 1
    System.out.println("b[0] : " + b[0]);		// OUTPUT : b[0] : 3

    주소값이랑 상관없이 b라는 배열은 a가 가지고 있는 요소들로 이루어진 새로운 별도의 배열이 생성된다.


  1. 메서드를 사용한 방법
  • clone() : 복사하는 메서드
    🚨 하지만 2차원 이상 배열에서는 얕은 복사로 동작한다

    int[] a = {1, 2, 3, 4};
    int[] b = a.clone();
    
    b[0] = 3;
    
    System.out.println("a[0] : " + a[0]);		// OUTPUT : a[0] : 1
    System.out.println("b[0] : " + b[0]);		// OUTPUT : b[0] : 3
  • Arrays.copyOf()
    : Arrays.copyOf(원본 배열, 원본 배열에서 복사하고 싶은 요소들의 길이)

    int[] a = {1, 2, 3, 4};
    int[] b = Arrays.copyOf(a, a.length);
    
    b[0] = 3;
    
    System.out.println("a[0] : " + a[0]);		// OUTPUT : a[0] : 1
    System.out.println("b[0] : " + b[0]);		// OUTPUT : b[0] : 3

📌 컬렉션

컬렉션 기능: 크기 자동조정, 추가, 수정, 삭제, 반복, 순회, 필터, 포함 확인 등..

컬렉션 종류

  • List : 순서가 있는 데이터의 집합 (데이터 중복 허용) - 배열과 비슷
  • Stack : 수직으로 쌓은 데이터의 집합 / First In Last Out
  • Set : 순서가 없는 데이터의 집합 (데이터 중복 허용 안함) = 순서없고 중복없는 배열
  • Queue : 빨대처럼 한쪽에서 데이터를 넣고 반대쪽에서 데이터를 뺄 수 있는 집합 / First In First Out
  • Map: 순서가 없는 (Key, Value) 쌍으로 이루어진 데이터의 집합 (Key값 중복 허용 안함)

<> 안에 데이터 타입(type)을 넣는다. 하지만 그냥 int가 아닌 Wapper classInteger로 넣어주어야 한다.

💪🏻 List

: Array : 정적 배열
: List (ArrayList) : 동적 배열 ➡️ 크기가 가변적으로 늘어난다

ArrayList

처음에 길이를 몰라도 만들 수 있다. (Array는 최초 길이를 알아야한다.)

생성 시점에 작은 연속된 공간을 요청해서 참조형 변수들을 담아놓는다.
값이 추가될 때 더 큰 공간이 필요하면 더 큰 공간을 받아서 저장하니깐 상관없다!!!!

  • 선언
ArrayList<Integer> intList = new ArrayList<Integer>();

동적배열이기 때문에 값을 언제든지 추가할 수 있다.

  • 메서드

    • add(element), add(index, element): 값을 추가한다.
    • get(index) : 값을 읽어준다.
    • set(index, element): 값을 바꿔준다.
    • remove(index) : 값이 삭제되고 앞으로 밀린다.
    • clear() : List 안에 전체 값이 삭제된다.
  • toString() : 우리가 볼 수 있는 배열 모양으로 바꿔준다.

ArrayList<Integer> intList = new ArrayList<Integer>();

intList.add(15);
intList.add(27);
intList.add(33);
System.out.println(intList); 					// OUTPUT : [15, 27, 33]

intList.add(1, 88);
System.out.println(intList);					// OUTPUT : [15, 88, 27, 33]

intList.set(0, 99);
System.out.println(intList.get(0));				// OUTPUT : 99

intList.remove(2); // 27
System.out.println(intList.get(2));				// OUTPUT : 33
System.out.println("clear 전 : " + intList);		// OUTPUT : clear 전 : [99, 88, 33]
intList.clear();
System.out.println("clear 후 : " + intList);		// OUTPUT : clear 후 : []

LinkedList

: 메모리에 남는 공간을 요청해서 여기 저기 나누어서 실제 값을 담아놓고, 실제 값이 있는 주소값으로 목록을 구성하고 저장하는 자료구조

기본적 기능은 ArrayList와 비슷하다
LinkedList는 값을 여기저기 나누어 담았기 때문에 조회하는 속도가 느리다. 하지만 값을 추가하거나, 삭제할 때는 빠르다.

  • 선언
LinkedList<Integer> linkedList = new LinkedList<Integer>();
  • 메서드
    : ArrayList와 같다
LinkedList<Integer> linkedList = new LinkedList<Integer>();

linkedList.add(32);
linkedList.add(12);
linkedList.add(90);

System.out.println(linkedList.get(0));				// OUTPUT : 32
System.out.println(linkedList.get(1));				// OUTPUT : 12
System.out.println(linkedList.get(2));				// OUTPUT : 90

linkedList.remove(1); // 12
System.out.println("clear 전 : " + linkedList);		// OUTPUT : clear 전 : [32, 90]

linkedList.clear();
System.out.println("clear 전 : " + linkedList);		// OUTPUT : clear 후 : []

💪🏻 Stack

: 수직으로 값을 쌓아놓고, 넣었다가 뺀다. (FILO : First In Last Out)
: 최근 저장된 데이터를 나열하고 싶거나, 데이터의 중복 처리를 막고 싶을 때 사용

  • 선언
Stack<Integer> intStack = new Stack<Integer>();
  • 메서드
    • push() : 값을 넣는다.
    • peek() : 제일 위에 있는 애를 조회한다.
    • pop() : 맨 상단에 있는 것만 위로 빼준다 -> Stack 에서 빠진다
    • size() : 사이즈(길이)를 알려준다.

isEmpty() : 비어있으면 True, 비어있지 않으면 False

Stack<Integer> intStack = new Stack<Integer>();

intStack.push(10);
intStack.push(34);
intStack.push(22);
intStack.push(66);

// 다 지워질 때 까지 출력
while (!intStack.isEmpty()){
	System.out.println("pop : " + intStack.pop()); 		// OUTPUT : pop : 66
}														// OUTPUT : pop : 22
														// OUTPUT : pop : 34
														// OUTPUT : pop : 10
System.out.println("Empty : " + intStack);				// OUTPUT : Empty : []

intStack.push(10);
intStack.push(34);
intStack.push(22);
intStack.push(66);

System.out.println("peek : " + intStack.peek());		// OUTPUT : peek : 66
System.out.println("size : " + intStack.size());		// OUTPUT : size : 4

💪🏻 Set

: 순서 없고, 중복 없음
* 순서가 보장되지 앟는 대신 중복을 허용하지 않도록 하는 프로그램에서 사용할 수 있는 자료구조

👩🏻‍💻 : 이런 요구사항에 맞는 자료 구조가 머리속에서 생각이 나야한다 💡

Set 그냥 쓸 수도 있다. 그러나 HashSet, TreeSet 등오로 응용해서 같이 사용 가능

  • HashSet : 생성자가 존재한다.
  • TreeSet

생성자가 없는 껍데기라서 바로 생성할 수 없다.

  • 선언
Set<Integer> intSet = new HashSet<>();
  • 메서드
    • add(element) : 값을 추가한다.
    • contains(element) : 값을 포함하고 있는지 포함하고 있지 않은지 True / False 결과를 낸다
    • remove(element) : 집합이므로 index 값이 아닌 안에 속한 요소를 바로 제거한다. 속하지 않으면 아무일도 일어나지 않는다.
    • clear() : 전체를 삭제한다.
Set<Integer> intSet = new HashSet<>();

intSet.add(12);
intSet.add(51);
intSet.add(9);
intSet.add(12);
intSet.add(9);

for (Integer value : intSet){
	System.out.println(value); 					// OUTPUT : 51
}												// OUTPUT : 9
												// OUTPUT : 12
System.out.println(intSet.contains(12));		// OUTPUT : true
System.out.println(intSet.contains(2));			// OUTPUT : false

intSet.remove(12);
System.out.println(intSet);						// OUTPUT : [51, 9]
        
intSet.clear();
System.out.println(intSet);						// OUTPUT : []

💪🏻 Queue

: 처음 들어간 데이터가 제일 먼저 나온다.
: 생성자가 없는 인터페이스
: 생성자가 없기때문에 new 키워드로 만들 수 없다.

  • 선언
Queue<Integer> intQueue = new LinkedList<>();
  • 메서드
    • add(element) : 값을 넣어준다.
    • peek() : 값을 조회한다.
    • poll() : 값을 빼준다. -> Stack 의 pop
    • size() : 사이즈(길이)를 알려준다.
Queue<Integer> intQueue = new LinkedList<>();

intQueue.add(87);
intQueue.add(56);
intQueue.add(100);

while (!intQueue.isEmpty()) {
	System.out.println("poll : " + intQueue.poll());		// OUTPUT : poll : 87
}															// OUTPUT : poll : 56
															// OUTPUT : poll : 100
System.out.println("Empty : " + intQueue);					// OUTPUT : Empty : []

intQueue.add(87);
intQueue.add(56);
intQueue.add(6);
intQueue.add(100);

System.out.println("peak : " + intQueue.peek()); 			// OUTPUT : peek : 87
System.out.println("size : " + intQueue.size());			// OUTPUT : size : 4

💪🏻 Map

:(key, value) - PAIR
:key라는 값으로 unique하게 보장돼야한다
: HashMap, TreeMap

  • 메서드
    • put(key, value) : 값을 추가한다.
    • keySet() : key만 빼서 배열로 만든거 -> 키가 중복되면 중복된 key는 생략해버리고 unique한 키만 나온다 / 마지막꺼로 덮어쓰기된다.
    • values() : 모든 value를 배열로 만든거
    • get(key) : key에 해당되는 value 값을 가져온다.
Map<String, Integer> intMap = new HashMap<>();

intMap.put("일", 12);
intMap.put("이", 134);
intMap.put("삼", 14);
intMap.put("삼", 15);
intMap.put("삼", 16);

for (String key : intMap.keySet()) {
	System.out.println(key);						// OUTPUT : 이
}													// OUTPUT : 일
													// OUTPUT : 삼
for (Integer value : intMap.values()) {	
	System.out.println(value);						// OUTPUT : 134
}													// OUTPUT : 12
													// OUTPUT : 16
System.out.println(intMap.get("삼"));				// OUTPUT : 16

📌 Quiz. 3가지 자료구조로 요리 레시피 메모장 만들기

💁‍♀️ **자료구조 요리 레시피 메모장 만들기**
  • 입력값
    • 저장할 자료구조명을 입력합니다. (List / Set / Map)
    • 내가 좋아하는 요리 제목을 먼저 입력합니다.
    • 이어서 내가 좋아하는 요리 레시피를 한문장씩 입력합니다.
    • 입력을 마쳤으면 마지막에 “끝” 문자를 입력합니다.
  • 출력값
    • 입력이 종료되면 저장한 자료구조 이름과 요리 제목을 괄호로 감싸서 먼저 출력 해줍니다.
    • 이어서, 입력한 모든 문장앞에 번호를 붙여서 입력 순서에 맞게 모두 출력 해줍니다.

ex) 입력 예시

Set
백종원 돼지고기 김치찌개 만들기
돼지고기는 핏물을 빼주세요.
잘익은 김치 한포기를 꺼내서 잘라주세요.
냄비에 들기름 적당히 두르고 김치를 넣고 볶아주세요.
다진마늘 한스푼, 설탕 한스푼 넣어주세요.
종이컵으로 물 8컵 부어서 센불에 끓여주세요.
핏물 뺀 돼지고기를 넣어주세요.
된장 반스푼, 양파 반개, 청양고추 한개를 썰어서 넣어주세요.
간장 두스푼반, 새우젓 두스푼, 고춧가루 두스푼반 넣어주세요.
중불로 줄여서 오래 끓여주세요~!!	
마지막에 파 쏭쏭 썰어서 마무리하면 돼요^^

예시 출력

[ Set 으로 저장된 백종원 돼지고기 김치찌개 만들기 ]
1. 돼지고기는 핏물을 빼주세요.
2. 잘익은 김치 한포기를 꺼내서 잘라주세요.
3. 냄비에 들기름 적당히 두르고 김치를 넣고 볶아주세요.
4. 다진마늘 한스푼, 설탕 한스푼 넣어주세요.
5. 종이컵으로 물 8컵 부어서 센불에 끓여주세요.
6. 핏물 뺀 돼지고기를 넣어주세요.
7. 된장 반스푼, 양파 반개, 청양고추 한개를 썰어서 넣어주세요.
8. 간장 두스푼반, 새우젓 두스푼, 고춧가루 두스푼반 넣어주세요.
9. 중불로 줄여서 오래 끓여주세요~!!	
10. 마지막에 파 쏭쏭 썰어서 마무리하면 돼요^^

😎 내가 푼 코드

사실 야매로 풀었다.....
Set은 순서가 없기 때문에 출력을 할 때 입력한 순이 아니라 마구잡이로 나오게 된다.
그래서 LinkedHashSet를 사용하였다.

import java.util.*;

public class HW02 {
  public static void main(String[] args) {
      Scanner sc = new Scanner(System.in);
      System.out.print("자료구조명을 입력하세요 (List / Set / Map) : ");
      String structureName = sc.nextLine();


      if (Objects.equals(structureName, "List")){
          System.out.print("요리 제목을 입력하세요 : ");
          String title = sc.nextLine();
          System.out.println("∇ 요리 레시피를 입력하세요 ∇");
          String recipe = null;

          ArrayList<String> recipeList = new ArrayList<String>();

          while (!Objects.equals(recipe, "끝")){
              recipe = sc.nextLine();
              recipeList.add(recipe);
          }
          System.out.println("[ " + structureName + " 으로 저장된 " + title + " ]");
          for (int i = 0; i < recipeList.size()-1; i++){
              System.out.println((i+1) + ". " + recipeList.get(i));
          }
      } else if (Objects.equals(structureName, "Set")){
          System.out.print("요리 제목을 입력하세요 : ");
          String title = sc.nextLine();
          System.out.println("∇ 요리 레시피를 입력하세요 ∇");
          String recipe = null;

          Set<String> recipeSet = new LinkedHashSet<>();
          int idx = 1;

          while (!Objects.equals(recipe, "끝")){
              recipe = sc.nextLine();
              recipeSet.add(recipe);
          }
          recipeSet.remove("끝");

          System.out.println("[ " + structureName + " 으로 저장된 " + title + " ]");

          for(String value : recipeSet) {
              System.out.println(idx++ + ". " + value);
          }

      } else if (Objects.equals(structureName, "Map")){
          System.out.print("요리 제목을 입력하세요 : ");
          String title = sc.nextLine();
          System.out.println("∇ 요리 레시피를 입력하세요 ∇");
          String recipe = null;

          Map<Integer, String> recipeMap = new HashMap<>();
          int idx = 1;

          while (!Objects.equals(recipe, "끝")){
              recipe = sc.nextLine();
              recipeMap.put(idx++, recipe);
          }
          System.out.println("[ " + structureName + " 으로 저장된 " + title + " ]");
          for (int i = 1; i < recipeMap.size(); i++){
              System.out.println(i + ". " + recipeMap.get(i));
          }
      } else {
          System.out.println("잘못 입력했습니다.");
      }

  }
}

😎 강의 정답

package week02;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Scanner;

public class Main02 {

	public static void main(String[] args) {

		Scanner sc = new Scanner(System.in);
		String collectionName = sc.next();
		String title = sc.next();

		switch (collectionName) {
			case "List":
				ArrayList<String> strList = new ArrayList<>();
				while (true) {
					// 한줄씩 입력받아서 strList 에 저장
					String text = sc.next();
					if (Objects.equals(text, "끝")) {
						break;
					}
					strList.add(text);
				}

				title = "[ List로 저장된 " + title + " ]";  // [ 제목 ]
				System.out.println(title);
				// strList 한줄씩 출력
				for (int i = 0; i < strList.size(); i++) {
					int number = i + 1;
					System.out.println(number + ". " + strList.get(i));
				}
				break;
			case "Set":
				LinkedHashSet<String> strSet = new LinkedHashSet<>();
				while (true) {
					// 한줄씩 입력받아서 strList 에 저장
					String text = sc.next();
					if (Objects.equals(text, "끝")) {
						break;
					}
					strSet.add(text);
				}

				title = "[ Set 으로 저장된 " + title + " ]";  // [ 제목 ]
				System.out.println(title);

				Iterator iterator = strSet.iterator();
				// strList 한줄씩 출력
				for (int i = 0; i < strSet.size(); i++) {
					int number = i + 1;
					System.out.println(number + ". " + iterator.next());
				}
				break;
			case "Map":
				Map<Integer, String> strMap = new HashMap<>();
				int lineNumber = 1;
				while (true) {
					// 한줄씩 입력받아서 strList 에 저장
					String text = sc.next();
					if (Objects.equals(text, "끝")) {
						break;
					}
					strMap.put(lineNumber++, text);
				}

				title = "[ Map 으로 저장된 " + title + " ]";  // [ 제목 ]
				System.out.println(title);

				// strList 한줄씩 출력
				for (int i = 0; i < strMap.size(); i++) {
					int number = i + 1;
					System.out.println(number + ". " + strMap.get(i + 1));
				}
				break;
			default:
				System.out.println("저장할 수 없는 자료구조 입니다.");
		}
	}
}
profile
💻🌾시골소녀의 엉망징창 개발 성장일지🌾💻 (2023.05.23 ~)

0개의 댓글