step 3까지 결과

package org.tesk;

public class Calculator {
    AddOperation addOperation;
    SubstractOperation substractOperation;
    MultiplyOperation multiplyOperation;
    DivideOperation divideOperation;

    public double calculate(String operator, int firstNumber, int secondNumber){
        double answer = 0;
        char char_operator = operator.charAt(0);

        //연산 수행
        if (char_operator == '+') {
            addOperation = new AddOperation(firstNumber, secondNumber);
            answer = addOperation.operate();
        } else if (char_operator == '-') {
            substractOperation = new SubstractOperation(firstNumber, secondNumber);
            answer = substractOperation.operate();
        } else if (char_operator == '*') {
            multiplyOperation = new MultiplyOperation(firstNumber, secondNumber);
            answer = multiplyOperation.operate();
        } else if (char_operator == '/') {
            divideOperation = new DivideOperation(firstNumber, secondNumber);
            answer = divideOperation.operate();
        } else if (char_operator == '%') {
            answer = (double)firstNumber % secondNumber;
        }

        return answer;
    }
}
package org.tesk;

public class AddOperation {
    private int firstNumber;
    private int secondNumber;

    public AddOperation(int firstNumber, int secondNumber){
        this.firstNumber = firstNumber;
        this.secondNumber = secondNumber;
    }

    public double operate(){
        double answer = 0;
        answer = (double)firstNumber + secondNumber;
        return answer;
    }
}

 

나머지  SubstractOperation, MultiplyOperation, DivideOperation 연산 클래스들도 동일

 

"Calculator 클래스와 포함관계를 맺고 생성자를 통해 각각의 연산 클래스 타입의 필드에 객체를 주입합니다" 라는 조건에 이게 부합하는지 고민이 됐다 그래도 일단 위와 같이 구현함!

 


Calculator 클래스와 포함관계를 맺고 생성자를 통해 각각의 연산 클래스 타입의 필드에 객체를 주입 -> 과제를 풀고 답지를 보니 저 의미가 아니였다!!

Calculator클래스 내부에 필드로 가지고 있는 연산자 클래스들을 생성자 주입을 통해서 넣은 다음에, 연산은 생성자 주입을 통해서 넣은 필드들의 메서드를 통해서 수행하라는 뜻이었다! 

피연산자 값은 그냥 메서드로 전달하는 것이었음.,,ㅎㅎ

문제에서 직관적으로 해설해 주셨는데 왜 피연산자 값들을 생성자 주입을 통해서 하라고 이해했는지 😅

앞선 setp이랑 헷갈린 것 같다...

앞으로는 문제를 더 주의깊게 봐야할 것 같다 😳

 

public class Calculator {

    private final AddOperation addOperation;
    private final SubstractOperation substractOperation;
    private final MultiplyOperation multiplyOperation;
    private final DivideOperation divideOperation;

    public Calculator(AddOperation addOperation, SubstractOperation substractOperation, 
                      MultiplyOperation multiplyOperation, DivideOperation divideOperation) {
        this.addOperation = addOperation;
        this.substractOperation = substractOperation;
        this.multiplyOperation = multiplyOperation;
        this.divideOperation = divideOperation;
    }

    public double calculate(String operator, int firstNumber, int secondNumber) {
        double answer = 0;

        if(operator.equals("+")){
            answer = addOperation.operate(firstNumber, secondNumber);
        }else if(operator.equals("-")){
            answer = substractOperation.operate(firstNumber, secondNumber);
        }else if(operator.equals("*")){
            answer = multiplyOperation.operate(firstNumber, secondNumber);
        }else if(operator.equals("/")) {
            answer = divideOperation.operate(firstNumber, secondNumber);
        }
        return answer;
    }

}
public class AddOperation {
    public double operate(int firstNumber, int secondNumber){
        return firstNumber + secondNumber;
    }
}

 

 


step 4까지 결과

 

package org.tesk;

public class Main {
    public static void main(String[] args) {
        AddOperation addOperation = new AddOperation();
        Calculator calculator = new Calculator(addOperation);
        System.out.println(calculator.calculate(2, 3));
    }
}

 

package org.tesk;

public abstract class AbstractOperation {
    public abstract double operate(int firstNumber, int secondNumber);
}

 

package org.tesk;

public class AddOperation extends AbstractOperation{

    @Override
    public double operate(int firstNumber, int secondNumber) {
        return (double)firstNumber + secondNumber;
    }

}

 

package org.tesk;

public class Calculator{

    AbstractOperation operation;

    public Calculator(AbstractOperation operation){
        this.operation = operation;
    }

    public double calculate(int firstNumber, int secondNumber){
        return operation.operate(firstNumber, secondNumber);
    }
}

 

calculate 메서드에서는 더 이상 연산자 타입을 받아 구분할 필요 없이 주입 받은 연산 클래스의 operate 메서드를 통해 바로 연산을 수행

이라고 했기 때문에 main에서 연산자 클래스를 생성해서 Calculator클래스에 생성자 주입을 한 다음 calculate메서드에서 실행하도록 했다! Step4는 답지랑 똑같이 잘 풀었다! ^_^

package week02.collection;

import java.util.*;

public class Col1 {
    public static void main(String[] args) {
        ArrayList<String> arrayList = new ArrayList<String>();
        Set<String> set = new LinkedHashSet<String>();
        Map<Integer, String> map = new LinkedHashMap<>();

        Scanner sc = new Scanner(System.in);
        String dataStructure = sc.nextLine();
        String title = sc.nextLine();
        int idx = 1;
        int mapIdx = 1;

        switch (dataStructure) {
            case "List":
                while(true){
                    String recipe = sc.nextLine();
                    if (recipe.equals("끝")){
                        break;
                    }
                    arrayList.add(recipe);
                }

                System.out.println("[" + dataStructure + "로 저장된 " + title + "]");
                for (String i : arrayList) {
                    System.out.println(idx + ". " + i);
                    idx++;
                }
                break;

            case "Set":
                while(true){
                    String recipe = sc.nextLine();
                    if (recipe.equals("끝")){
                        break;
                    }
                    set.add(recipe);
                }

                System.out.println("[" + dataStructure + "로 저장된 " + title + "]");
                for (String i : set) {
                    System.out.println(idx + ". " + i);
                    idx++;
                }
                break;

            case "Map":
                while(true){
                    String recipe = sc.nextLine();
                    if (recipe.equals("끝")){
                        break;
                    }
                    map.put(mapIdx++, recipe);
                }

                System.out.println("[" + dataStructure + "로 저장된 " + title + "]");
                for (String i : map.values()) {
                    System.out.println(idx + ". " + i);
                    idx++;
                }
                break;
        }

    }
}

 

각각의 자료구조에 순서가 보장되어 있어야 하는 것 같아서 LinkedHashSet, LinkedHashMap을 사용했다.

 

Iterator

set과 같은 인덱스가 없는 자료구조에서 순환하기 위해서 사용

혹은 향상된 for문에서 할 수 없는 컬랙션의 수정이나 삭제를 하기 위해서 사용

  •  for-each문으로 자료구조를 돌다가 값을 수정, 삭제해야 해서 수정, 삭제를 수행 -> ConcurrentModificationException이 발생
public class IteratorExample {
    public static void main(String[] args) {
        // ArrayList 생성 및 초기화
        ArrayList<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");
        list.add("Banana");

        System.out.println("원본 리스트: " + list);

        // Iterator 생성
        Iterator<String> iterator = list.iterator();

        // 순회하면서 "Banana" 제거
        while (iterator.hasNext()) {
            String element = iterator.next();
            if (element.equals("Banana")) {
                iterator.remove(); // 안전하게 요소 제거
            }
        }

        System.out.println("Banana 제거 후 리스트: " + list);
    }
}
public class Main
{
    public static void main(String[] args)
    {
        // 컬렉션 생성
        ArrayList<String> list = new ArrayList<>();
        list.add("A");
        list.add("B");
        list.add("C");
        list.add("D");
        list.add("E");
        list.add("F");
        System.out.println("while문 지나기 전 리스트에 들어있던 값 : " + list);

        //'+' 붙이기
        ListIterator<String> listIterator = list.listIterator();
        while(listIterator.hasNext())
        {
            Object element = listIterator.next();
            listIterator.set(element + "+");
        }
        System.out.println("while문 지난 후 수정된 결과 : " + list);

    }

}
public class ListIteratorExample {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("Apple");
        list.add("Banana");
        list.add("Cherry");
        list.add("Date");

        // ListIterator를 끝에서 시작
        ListIterator<String> iterator = list.listIterator(list.size());
        System.out.println("역방향 조회:");

        while (iterator.hasPrevious()) { // 이전 요소가 있을 때까지
            String element = iterator.previous(); // 이전 요소 가져오기
            System.out.println(element);
        }
    }
}

Array

정적 배열, 선언시에 크기를 지정해 줘야 함

리스트보다 삽입, 삭제가 느리지만 조회가 빠름

  • 생성 : int[] intArray = new int[3]; / int[] array = {1,2,3,4};
  • 길이 : intArray2.length
  • 동일한 값으로 넣기 : Arrays.fill(intArray, 1);
public class Arr01 {
    public static void main(String[] args) {
        //배열 생성
        int[] intArray = new int[3]; //{0,0,0}
        int[] array = {1,2,3,4};
        boolean[] boolArray = new boolean[3]; //{false, false, false}
        String[] stringArray = new String[3]; //{"", "", ""}

        //배열 선언 먼저 -> 나중에 초기화
        int[] intArray2;
        intArray2 = new int[3]; // {0,0,0}

        //순회
        //1. 단건 조회
        System.out.println(intArray[1]);
        System.out.println("-------");

        //2. 다건 조회
        for (int i = 0; i < intArray2.length; i++){
            System.out.println(intArray2[i]);
        }

        System.out.println("-------");
        //배열의 주소를 모두 같은 값으로 초기화
        Arrays.fill(intArray, 1);
        for (int item : intArray){
            System.out.println(item);
        }
        
    }
}

 

2차원 배열

public class Arr02 {
    public static void main(String[] args) {
        int[][] array = new int[2][3]; // 최초 선언

        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                array[i][j] = 0;  // i, j 는 위 노란색 네모박스 안에있는 숫자를 의미하며 인덱스 라고 부릅니다.
            }
        }
    }
}

 

List

조회가 배열보다 느리지만 삽입, 삭제가 빠름

순서가 있고 , 중복 가능

 

ArrayList

LinkedList 보다 조회 속도는 빠르지만 중간에 값을 삽입, 삭제하는 속도는 느림

정적인 배열

  • ArrayList<Integer> intList = new ArrayList<Integer>();
  • add
  • get
  • set
  • remove
  • toString
  • clear
// ArrayList 
import java.util.ArrayList;

public class Main {

	public static void main(String[] args) {
		ArrayList<Integer> intList = new ArrayList<Integer>(); // 선언 및 생성
		
		intList.add(1);
		intList.add(2);
		intList.add(3);
		
		System.out.println(intList.get(0)); // 1 출력
		System.out.println(intList.get(1)); // 2 출력
		System.out.println(intList.get(2)); // 3 출력
		System.out.println(intList.toString()); // [1,2,3] 출력
		
		intList.set(1, 10); // 1번순번의 값을 10으로 수정합니다.
		System.out.println(intList.get(1)); // 10 출력
		
		
		intList.remove(1); // 1번순번의 값을 삭제합니다.
		System.out.println(intList.toString()); // [1,3] 출력
		
		intList.clear(); // 전체 값을 삭제합니다.
		System.out.println(intList.toString()); // [] 출력
	}
}

 

LinkedList

ArrayList 보다 조회 속도는 느리지만 중간에 값을 삽입, 삭제하는 속도는 빠름

동적인 배열

import java.util.LinkedList;

public class Main {

	public static void main(String[] args) {
		LinkedList<Integer> linkedList = new LinkedList<>(); // 선언 및 생성

		linkedList.add(1);
		linkedList.add(2);
		linkedList.add(3);

		System.out.println(linkedList.get(0)); // 1 출력
		System.out.println(linkedList.get(1)); // 2 출력
		System.out.println(linkedList.get(2)); // 3 출력
		System.out.println(linkedList.toString()); // [1,2,3] 출력 (속도 느림)

		linkedList.add(2, 4); // 2번 순번에 4 값을 추가합니다.
		System.out.println(linkedList); // [1,2,4,3] 출력

		linkedList.set(1, 10); // 1번순번의 값을 10으로 수정합니다.
		System.out.println(linkedList.get(1)); // 10 출력

		linkedList.remove(1); // 1번순번의 값을 삭제합니다.
		System.out.println(linkedList); // [1,4,3] 출력

		linkedList.clear(); // 전체 값을 삭제합니다.
		System.out.println(linkedList); // [] 출력
	}
}

 

Stack

lifo, 최근 저장된 데이터를 나열하고 싶거나 데이터의 중복 처리를 막고 싶을 때 사용

  • push
  • peek
  • pop
  • size
// Stack 
import java.util.Stack;

public class Main {

	public static void main(String[] args) {
		Stack<Integer> intStack = new Stack<Integer>(); // 선언 및 생성
		
		intStack.push(1);
		intStack.push(2);
		intStack.push(3);

		while (!intStack.isEmpty()) { // 다 지워질때까지 출력
		    System.out.println(intStack.pop()); // 3,2,1 출력
		}

		// 다시 추가
		intStack.push(1);
		intStack.push(2);
		intStack.push(3);
		
		// peek()
		System.out.println(intStack.peek()); // 3 출력
		System.out.println(intStack.size()); // 3 출력 (peek() 할때 삭제 안됬음)
		
		// pop()
		System.out.println(intStack.pop()); // 3 출력
		System.out.println(intStack.size()); // 2 출력 (pop() 할때 삭제 됬음)		
		
		System.out.println(intStack.pop()); // 2 출력
		System.out.println(intStack.size()); // 1 출력 (pop() 할때 삭제 됬음)		

		while (!intStack.isEmpty()) { // 다 지워질때까지 출력
		    System.out.println(intStack.pop()); // 1 출력 (마지막 남은거 하나)
		}
	}
}

 

Queue

fifo, 먼저 들어간 순서대로 값을 조회

  • add
  • poll
  • peek
// Queue 
// (사용하기 위해선 java.util.LinkedList; 와 import java.util.Queue; 를 추가해야합니다.)
import java.util.LinkedList;
import java.util.Queue;

public class Main {

	public static void main(String[] args) {
		Queue<Integer> intQueue = new LinkedList<>(); // 선언 및 생성

		intQueue.add(1);
		intQueue.add(2);
		intQueue.add(3);

		while (!intQueue.isEmpty()) { // 다 지워질때까지 출력
			System.out.println(intQueue.poll()); // 1,2,3 출력
		}

		// 다시 추가
		intQueue.add(1);
		intQueue.add(2);
		intQueue.add(3);

		// peek()
		System.out.println(intQueue.peek()); // 1 출력 (맨먼저 들어간값이 1 이라서)
		System.out.println(intQueue.size()); // 3 출력 (peek() 할때 삭제 안됬음)

		// poll()
		System.out.println(intQueue.poll()); // 1 출력
		System.out.println(intQueue.size()); // 2 출력 (poll() 할때 삭제 됬음)

		System.out.println(intQueue.poll()); // 2 출력
		System.out.println(intQueue.size()); // 1 출력 (poll() 할때 삭제 됬음)

		while (!intQueue.isEmpty()) { // 다 지워질때까지 출력
			System.out.println(intQueue.poll()); // 3 출력 (마지막 남은거 하나)
		}
	}
}

 

Set

중복허용x, 순서 x

Set는 생성자가 없는 인터페이스 이므로 생성자가 존재하는 HashSet을 이용하여 생성

  • HashSet : 가장 빠르며 순서를 전혀 예측할 수 없음
  • TreeSet : 정렬된 순서대로 보관하며 정렬 방법을 지정할 수 있음
  • LinkedHashSet : 추가된 순서, 또는 가장 최근에 접근한 순서대로 접근 가능

즉, 보통 HashSet 을 쓰는데 순서 보장이 필요하면 LinkedHashSet 을 주로 사용

  • add
  • contain : intSet.contains(2)
  • remove
// Set 
// (사용하기 위해선 import java.util.Set; 와 java.util.HashSet; 를 추가해야합니다.)
import java.util.HashSet;
import java.util.Set;

public class Main {

	public static void main(String[] args) {
		Set<Integer> intSet = new HashSet<Integer>(); // 선언 및 생성

		intSet.add(1);
		intSet.add(2);
		intSet.add(3);
		intSet.add(3); // 중복된 값은 덮어씁니다.
		intSet.add(3); // 중복된 값은 덮어씁니다.

		for (Integer value : intSet) {
			System.out.println(value); // 1,2,3 출력
		}

		// contains()
		System.out.println(intSet.contains(2)); // true 출력
		System.out.println(intSet.contains(4)); // false 출력

		// remove()
		intSet.remove(3); // 3 삭제

		for (Integer value : intSet) {
			System.out.println(value); // 1,2 출력
		}
	}
}

 

Map

key-value, key는 중복 허용 x, 중복이면 덮어씀

  • HashMap : 중복을 허용하지 않고 순서를 보장하지 않음, 키와 값으로 null이 허용
  • TreeMap : key 값을 기준으로 정렬 다만, 저장 시 정렬(오름차순)을 하기 때문에 저장시간이 다소 오래 걸림
  • put
  • get
  • keySet
  • values
  • remove
// Map 
// (사용하기 위해선 import java.util.Map; 를 추가해야합니다.)
import java.util.Map;

public class Main {

	public static void main(String[] args) {
		Map<String, Integer> intMap = new HashMap<>(); // 선언 및 생성

		//          키 , 값
		intMap.put("일", 11);
		intMap.put("이", 12);
		intMap.put("삼", 13);
		intMap.put("삼", 14); // 중복 Key값은 덮어씁니다.
		intMap.put("삼", 15); // 중복 Key값은 덮어씁니다.

		// key 값 전체 출력
		for (String key : intMap.keySet()) {
			System.out.println(key); // 일,이,삼 출력
		}

		// value 값 전체 출력
		for (Integer key : intMap.values()) {
			System.out.println(key); // 11,12,15 출력
		}

		// get()
		System.out.println(intMap.get("삼")); // 15 출력
	}
}

자동 형변환

여러 타입의 변수 여러 개를 연산했을 때, 결과값은 가장 큰 타입의 피연산자 타입으로 변환됨!

float + double => double

public class W02 {
    public static void main(String[] args) {
        // 자동 형변환
        int a = 10;
        int b = 329;

        float af = a;
        float bf = b;
        float cf = 35.0f + a;

		// 실수로 나온다!
        System.out.println(af);
        System.out.println(bf);
        System.out.println(cf);
    }
}

 

삼항연산자 & 비트연산자

public class W02 {
    public static void main(String[] args) {
        //삼항연산자
        int x = 1;
        int y = 10;
        boolean z = (x==y) ? true : false;
        System.out.println(z);

        //비트 연산자
        System.out.println(3 << 2); //왼쪽으로 비트 부호 이동시 *2 11 -> 1100
        System.out.println(30 >> 2); //오른쪽으로 비트 부호 이동시 /2 

    }
}

 

switch

  • switch : 코드의 중복이 적지만, 하나의 피연산자에 대해서만 조건을 달게 됨
  • If : 코드의 중복이 많지만, 여러 피연산자에 대해서 조건을 달 수 있음
public class W14 {
    public static void main(String[] args) {
        int month = 8;
        int a = 0;

        switch(month){
            case 1:
                System.out.println("1월 입니다");
                break;
            case 8:
                System.out.println("8월 입니다");
                a = 8;
                break;
            default:
                System.out.println("모릅니다");
                break;
        }

        System.out.println(a);
    }
}

 

향상된 for문

public static void main(String[] args) {
        int[] numbers = {1, 5, 3, 9};

        for(int number : numbers){
            System.out.println(number);
        }
    }

 

 

얕은 복사와 깊은 복사

= 로 하는 복사는 얕은 복사

int[] b = {1, 2,3};

int[] a = b →a는 b배열의 주소를 복사하는 것

a[1] = 5

sout(b[1]); → 5출력

 

깊은 복사

int[] a = b.clone(); //2차원 배열 이상에서는 얕은 복사

혹은

int[] a = Array.copyOf(b, b.length);

 

String

  • Char : '' / 기본 자료형 / 1byte만 사용 
  • String : "" / 참조 자료형 / 널문자를 포함함
  • 선언 : String str = "ABCD";
  • 길이 : str.length();
  • 해당 인덱스 값(char)로 변경 : char strChar = str.charAt(2);
  • 부분 문자열 출력 : String subString = str.substring(0, 3);
  • 동일한 내용의 문자열인지 확인 : newStr.equals(str);
  • char 배열로 변환 : char[] cArr = str.toCharArray();
  • char에서 String으로 : String strArrays = new String(bArr);
public class Arr02 {
    public static void main(String[] args) {
        String str = "ABCD";

        int strLength = str.length();
        System.out.println(strLength);

        char strChar = str.charAt(2);
        System.out.println(strChar);

        //0부터 2까지 출력
        String subString = str.substring(0, 3);
        System.out.println(subString);

        String newStr = "ABCD";
        boolean strEqul = newStr.equals(str);
        System.out.println(strEqul);

        //string을 char배열로 변환
        char[] cArr = str.toCharArray();

        //반대로
        char[] bArr = {'a', 'b', 'c'};
        String strArrays = new String(bArr);
        System.out.println(strArrays);
    }
}

import java.util.Scanner;

public class Main {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String title = scanner.nextLine();
        float star = scanner.nextFloat();
        scanner.nextLine(); //버퍼에 남아있는 \n을 가져와 비움
        float percentage_star = (star / 5.0f) * 100;
        String[] recipe = new String[10];

        for (int i = 0; i < 10; i++){
            recipe[i] = scanner.nextLine();
        }

        System.out.println(recipe[0]);

        System.out.println("[ " + title + " ]");
        System.out.println("별점 : " + (int)star + " (" + percentage_star + "%" + ")");

        int index = 1;
        for (int i = 0; i < 10; i++){
            System.out.println( index++ + ". " + recipe[i]);
        }

    }

}

 

배열

향후 미리 저장할 값들을 선언하는 경우 : 타입[] 변수 = new 타입[길이];

 

문제점 및 해결

scanner.nextFloat(); 이후, 배열의 첫 번째 값이 입력되지 않음

  • nextInt() 같은 메서드는 버퍼에 남아있는 연속된 숫자만 리턴하기 때문에, enter 값인 \n은 버퍼에 남겨둔다
  • 그렇기 때문에 버퍼를 비워주는 작업을 통해서 해결함
float star = scanner.nextFloat();
scanner.nextLine(); //버퍼에 남아있는 \n을 가져와 비움

 

백분율을 구하는 부분에서 형변환 주의 

  • (star / 5.0f) 부분에서 나누는 수를 명시적으로 실수라고 지정해야 정확한 결과값이 나옴

소수점을 표현하는 방식

  • 고정소수점 00.00 → 소수점의 길이나 바이트 수를 미리 제한해 놓은 것
  • 부동소수점 → 부호, 지수, 가수부의 영역만 정해 놓고 곱한 값을 저장해서 표현하는 방식 → 엄청 많은 수 표현 가능
    • 그렇기 때문에 float(4byte)여도 long(8byte)보다 더 큰 수를 표현할 수 있음

char과 String의 차이

  • char(byte)('')
    • 문자 뒤에 널문자(\0)가 없음, 1byte만 사용하기 때문
    • 기본형
  • String("")
    • 문자 뒤에 널문자 존재, 어디가 끝인지 알아야 되기 때문
    • 참조형

문자자료형 : 메모리는 이진수만 기록하므로 문자에 해당하는 유니코드값으로 매칭시켜 저장

 

기본형과 참조형 

  • 기본형 변수 : 원본값이 Stack 영역(정적영역 = 크기가 얼마인지 지정되어 있어야 함)으로 할당된 메모리 영역에 저장
  • 참조형 변수 : 원본값이 heap 영역에(동적영역 = 크기가 가변적임) 저장, heap영역의 원본 주소값을 저장함

 

형변환

  • 작은 타입에서 -> 큰 타입으로 형변환 : 자동으로 됨(up캐스팅)
  • 큰 타입에서 -> 작은 타입 형변환 : 값의 손실이 생김, 개발자가 직접 명시함(down캐스팅) 
public class Main {

    public static void main(String[] args) {
        // 변수 타입별 크기 순서
        // byte(1) -> short(2) -> int(4) -> long(8) -> float(4) -> double(8)

        // (1) byte -> int
        byte byteNumber = 10;
        int intNumber = byteNumber;
        System.out.println(intNumber);

        // (2) char(1byte) -> int(4) 형변환
        char alphabet = 'A';
        intNumber = alphabet; // char -> int로 자동 형변환
        System.out.println(intNumber);

        // (3) int -> double 형 변환
        intNumber = 200;
        double doubleNumber = intNumber;
        System.out.println(doubleNumber);

        // (4) double -> int 형 변환
        // 개발자가 명시적으로 형변환 = downcasting
        double d = 3.5;
        int a  = (int) d;
        System.out.println("강제 형변환 : " + a);

        // 큰 크기 타입으로 자동 형 변환
        int intNum = 10;
        double doubleNum = 5.5;
        double result = intNum + doubleNumber;
        System.out.println(result);

    }

}
  • 작은 크기 타입이 큰 크기의 타입이랑 계산될 때 자동으로 큰 크기의 타입으로 형 변환됨
public class Main {

    public static void main(String[] args) {
        int intNum = 10;

        // 1) 정수로 나누기
        int iResult = intNum / 4;
        // 2) 실수로 나누기
        double dResult = intNum / 4.0;

        System.out.println(iResult + " | " + dResult); // 2 | 2.5
    }

}

JVM

  • 어떤 침대에 깔아도 똑같이 편안하게 해주는 침대 메트리스의 토퍼같은 역할
  • 어떤 운영체제에 상관없이 (리눅스, 윈도우, 맥 .. ) 자바를 실행시킬 수 있게 해주는 자바 가상 머신
  • 가상머신 = 가상의 기기를 만들어 주는 것
  • JVM을 통해 자바의 플랫폼 독립성이 보장되는 것!

 

 Compile

1. 정적 컴파일 과정 : JAVA Compiler(javac) 

  • .java파일 코드를 .class(바이트코드)파일로 변환하는 변환기

.java 코드 : 사람이 이해할 수 있는 코드

.class 코드(바이트 코드) : 운영체제가 이해할 수 있는 코드, jvm에서 실행되기 위한 형태로 변환된 코드

 

2.  동적 컴파일 과정 : interpreter & JIT

  • interpreter : 바이트코드를 한 줄씩 읽어서 실행
  • JIT : 자주 실행되는 코드를 기계어로 변환하여 캐싱, 실행 속도를 향상함

 

메모리 : 운영체제로부터 jvm이 할당받은 데이터를 저장하는 영역

클래스 로더 :바이트 코드를 메모리 영역에 운반

가비지 컬랙터 :메모리에서 안 쓰는 데이터를 제거함

런타임 : 프로그램이 실행중인 상태 

 

자바 개발 도구와 자바 실행 환경

  • JDK(Java Development Kit) : 자바 개발 도구, 자바를 이용해 프로그램을 개발하는데 필요한 도구, 컴파일, 디버거 ,
    • JAVA Compiler(javac) 가능!
    • 디버깅 가능!
    • JRE 가능!
  • JRE(Java Runtime Environment)(jvm포함) : 자바 실행 환경, 자바 API, 클래스 로더 ,,
    • 자바 실행 환경, jvm이므로 바이트코드(.class)파일만 실행 가능함

→ JDK는 JRE를 포함, JRE는 JVM을 포함

import java.util.*;

public class 가위바위보 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        Random random = new Random();
        List<String> words = Arrays.asList("가위", "바위", "보");
        int winCount = 0;

        for (int i = 0; i < 5; i++){
            String user = scanner.nextLine();
            if (!user.equals("가위") && !user.equals("바위") && !user.equals("보")){
                System.out.println("잘못된 입력입니다.");
            }

            String computer = words.get(random.nextInt(words.size()));

            switch (user) {
                case "가위":
                    if (computer.equals("보")){
                        winCount++;
                        System.out.println("승리");
                    } else {
                        System.out.println("패배");
                    }
                    break;

                case "바위":
                    if (computer.equals("가위")){
                        winCount++;
                        System.out.println("승리");
                    } else {
                        System.out.println("패배");
                    }
                    break;

                case "보":
                    if (computer.equals("바위")){
                        winCount++;
                        System.out.println("승리");
                    } else {
                        System.out.println("패배");
                    }
                    break;
            }

        }

        Map<Integer, String> gifts = new HashMap<>();
        gifts.put(0, "꽝");
        gifts.put(1, "초코비인형");
        gifts.put(2, "부리부리맨인형");
        gifts.put(3, "흰둥이인형");
        gifts.put(4, "짱아인형");
        gifts.put(5, "짱구인형");

        System.out.println("총 " + winCount + "회 승리하여 [" + gifts.get(winCount) + "]를 경품으로 획득!");
    }
}

'JAVA' 카테고리의 다른 글

JAVA의 형변환과 자료형타입  (0) 2025.01.01
JVM과 자바 컴파일 과정  (2) 2024.12.31
Lv3. 단어 맞추기 게임  (2) 2024.12.16
Lv2. 스파르타 자판기  (5) 2024.12.14
Lv1. 랜덤 닉네임 생성기  (2) 2024.12.14

+ Recent posts