기타

[코테 대비] Java로 코딩 테스트 준비하기 - 기본

일 월 2025. 2. 3. 16:51

보통 Python으로 알고리즘을 준비하는데, 사용 가능 언어에 Python이 없는 코테가 있다. Java로 코딩 테스트를 보려고 할 때, 참고하면 좋을 내용을 적어보려고 한다.

빠르게 익히는 것을 목표로 하고 있어 자세한 설명이 없고, 프로그래머스 자바 입문 무료 강의, 중급 무료 강의, 다른 블로그 글을 참고했다.

 

길이가 너무 길어져서 기본 문법과 주요 알고리즘 참고 코드를 나눴다.

https://ilwol-developer.tistory.com/entry/%EC%BD%94%ED%85%8C-%EB%8C%80%EB%B9%84-Java%EB%A1%9C-%EC%BD%94%EB%94%A9%ED%85%8C%EC%8A%A4%ED%8A%B8-%EB%B3%B4%EA%B8%B0-%EC%8B%AC%ED%99%94

 

[코테 대비] Java로 코딩테스트 준비하기 - 심화

기본 문법에 관련된 글은 아래 링크에!https://ilwol-developer.tistory.com/entry/%EC%BD%94%ED%85%8C-%EB%8C%80%EB%B9%84-Java%EB%A1%9C-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8-%EC%A4%80%EB%B9%84%ED%95%98%EA%B8%B0 [코테 대비] Java로

ilwol-developer.tistory.com

 

 

1. 개발환경 구축

코딩 테스트를 보기 전 알고리즘 문제를 풀기 위해 관련 프로그램을 설치한다. 시험에 따라 외부 IDE를 사용할 수 있을 수도 있고, IDE 내의 편리한 기능을 사용할 수 있다.

=> JDK 설치, IDE는 이미 설치되어 있는 VS Code 사용

 

 

2. 기본 문법 학습

2-1. 타입, 식별자, 언어의 특징 파악

어떤 타입이 있는지, 어떻게 명명하는지, 변수에 사용하면 안 되는 문자가 있는지 등을 파악한다.

  • Java는 정적 타입 언어이고, 타입명을 변수 앞에 붙여 선언함
  • 선언과 할당을 분리할 수 있고, ;을 사용해 코드를 구분함
  • 식별자는 하나 이상의 글자로 이루어져야 하며, 첫 번째 글자로 문자, '$', '_'를 사용할 수 있음
  • 식별자를 명명할 때, 숫자는 두 번째 글자부터 쓸 수 있고, '$', '_' 이외의 특수문자는 사용 불가
  • 상수는 대문자로만 구성하고 여러 단어일 경우 '_'로 구분 (관례, upper snake case)
  • 변수는 첫 번째 문자를 소문자로 하고 두 번째 단어부터 첫 글자를 대문자로 사용 (관례, camel case)
// 상수 선언
final double PI;

// 변수 선언
int count;
double average;

// 값 할당
count = 10;
PI = 3.14;

// 값 변경
count = 20;

// 다중 선언
int i = 1, j = 2;

// 다중 할당
String first, second, third;
first = second = third = "다중할당";




// 기본형 타입

// 논리형 : 참/거짓 => true/false (1 byte)
boolean isReal = true;

// 문자형 : 한 글자 표현 (작은 따옴표 이용) => char (2 byte)
char munja = 'c';

// 정수형 : 정수 표현 => int (4 byte), long (8 byte)
int number = 5;
long bigNumber = 3456789L; // 뒤에 소문자 l이나 대문자 L 적어야 함

// 실수형 : 실수 표현 => float (4 byte), double (8 byte)
float num = 32.5f // 뒤에 소문자 f나 대문자 F 적어야 함
double bigNum = 23.34;



// 기본형 타입 형변환

// 암묵적 형변환 : 크기가 작은 타입을 크기가 더 큰 타입으로 바꿀 때
int x = 50000;
long y = x;

// 명시적 형변환 : 크기가 큰 타입을 크기가 작은 타입으로 바꿀 때
long y = 50000;
int y = (int) x;

3-2. 연산자

연산자는 언어마다 비슷한 부분이 많아, 주언어와 다른 부분만 짚고 넘어가는 편

  • [부호] +, -
  • [단항 연산자 (부호 제외)] ++, --, !, ~
  • [산술 연산자] +, -, *, /, %
  • [비교 연산자] ==, !=, <, <=, >, >=
  • [시프트 연산자] >>, <<
  • [비트 연산자] &, |, ~
  • [논리 연산자] &&, ||, ^, !
  • [대입 연산자] =, *=, /=, %=, +=, -=
// 나눗셈 연산에서 유의할 점
System.out.println(1/2); // 타입 : double, 결괏값 : 0
System.out.println(1/2.0); // 타입 : double, 결괏값 : 0.5
System.out.println(1.0/2.0); // 타입 : double, 결괏값 : 0.5
System.out.println(1.0/2); // 타입 : double, 결괏값 : 0.5
System.out.println((double) 1/2); // 타입 : double, 결괏값 : 0.5

3-3. 삼항 연산자

(조건식) ? (참일 때의 값이나 식) : (거짓일 때의 값이나 식)

3-4. 조건문, 반복문

조건문, 반복문도 언어마다 비슷한 부분이 많아, 주언어와 다른 부분만 짚고 넘어가는 편

// if문 - 작성한 순서대로 조건을 탐색함 (else if와, else는 필수 아님)
if (조건식) {
    실행문;
} else if (조건식) {
    실행문;
} else {
    실행문;
}


// switch문

    switch(변수){
        case 값1 : 
            실행문; 
            break;
        case 값2 : 
            실행문; 
            break;  
        default;    
    }

// while문

while(조건문){
    실행문; 
}

// do-while문 - 무조건 한 번은 실행됨

do{
    실행문;
} while(조건문);



// for문

for (초기화식; 조건식; 증감식) {
    실행문;
}



// for each문

int[] iarr = {10, 9, 8};

for (int value: iarr) {
    System.out.println(value);
}

3-5. 배열

// 1차원 배열 생성
int[] array1 = new int[4];
int[] array2 = new int[]{1, 2, 3, 4, 5}; // 선언과 동시에 초기화

// 값 저장
array1[0] = 1;

// 배열의 길이
array2.length;

// 2차원 배열 생성
int[][] array3 = new int[3][4];
int[] array4 = new int[]{{1}, {2, 3}, {4, 5}}; // 선언과 동시에 초기화
int[][] array5 = new int[3][]; // 가변 크기의 2차원 배열 생성

// 배열 자르기
int[] arr = {0, 1, 2, 3, 4, 5};   
int position = 3;         

int[] arr1 = Arrays.copyOfRange(arr, 0, position);        
int[] arr2 = Arrays.copyOfRange(arr, position, arr.length);


// 배열의 합
import java.util.Arrays;

public class ArraySum {
    public static void main(String[] args) {
        int[] arr = { 1, 2, 3, 4, 5 };
        int sum = Arrays.stream(arr).sum();
        System.out.println(sum);
    }
}



// 배열의 평균
import java.util.Arrays;

public class ArrayAverage {
    public static void main(String[] args) {

        int[] arr = { 1, 2, 3, 4, 5 };
        double average = Arrays.stream(arr).average().orElse(0);
        System.out.println(average); // 3.0
    }
}

// 중복 요소 제거
import java.util.Arrays;

Arrays.stream(A).distinct().toArray()


// 배열 복사해 배열 요소 추가
import java.util.Arrays;

int[] originalArray = {1, 2, 3};
int[] newArray = Arrays.copyOf(originalArray, originalArray.length+1);
newArray[newArray.length - 1] = 4;


// ArrayList로 변환해 배열 요소 추가
Integer[] originalArray = {1, 2, 3};
ArrayList<Integer> arrayList = new ArrayList<>(Arrays.asList(originalArray));
arrayList.add(4);
Integer[] newArray = arrayList.toArray(new Integer[0]);

// 정수 배열 -> 문자열 배열
String[] stringArr = Arrays.stream(array2).mapToObj(String::valueOf).toArray(String[]::new);

// 문자열 배열 -> 정수 배열
String[] intArr = Arrays.stream(stringArr).mapToInt(Integer::parseInt).toArray();

3-6. 클래스

// 클래스 생성
public class Car1 {
    String name;
    int number;
}


// 생성자로 필드 초기화
public class Car2 {
    String name;
    int number;

    public Car2(String name) {
        // this.name은 필드 name, name은 매개변수
        this.name = name;
    }
}


// 인스턴스 생성
public class CarExam {
    public static void main(String args[]) {
        Car1 c1 = new Car1();
        c1.name = "소방차";
        Car2 c2 = new Car2("구급차");
    }
}

3-7. 변수의 스코프

변수가 선언된 블럭이 그 변수의 사용범위

  • 클래스 내에 선언 - 클래스 안에서 사용 가능
  • 클래스 내의 메서드에서 선언 - 함수 안에서 사용 가능
  • static한 메서드에서는 static하지 않은 필드를 사용할 수 없음
    static한 변수는 class가 인스턴스화 되지 않아도 사용할 수 있음 -> 클래스명.변수명

3-8. 열거 타입

특정 값만 사용하기 위한 방식

enum Gender{
    MALE, FEMALE;
}

Gender gender2;

gender2 = Gender.MALE;
gender2 = Gender.FEMALE;

4. 자주 사용하는 클래스, 메소드

4-1. 입출력

// 입력
import java.util.Scanner

int num1 = 0;
int num2 = 0;

Scanner sc = new Scanner(System.in);
num1 = sc.nextInt(); // 입력 받은 것을 int형으로 변경
num2 = sc.nextLine(); // '\n'을 버린 나머지만 문자열로 리턴

// 빠른 입력
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public static void main(String[] args) throws IOException {
//예외처리 꼭해줘야함. try catch이용해도되지만 대개 이방식 이용

    BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
    String s = bf.readLine();
    int i = Integer.parseInt(bf.readLine());

    // 입력된 값을 공백 단위로 나누기
    String[] strArr = bf.readLine().split(" ");

    // 공백으로 나눈 입력 값을 int 값으로 바꾸기 (java.util 패키지 import 필수!)
    int[] intArr = Arrays.stream(stringArr).mapToInt(Integer::parseInt).toArray();;

}



// 출력
System.out.println();


// 입력된 값이 없을 때까지 받기
while (sc.hasNext()) {
    System.out.println(sc.nextLine());
}
  • next타입은 입력받은 값을 특정 타입으로 변환하지만, 연속으로 입력 받을 때는 사용하기 불편함
  • next()는 공백 기준으로, nextLine()은 줄바꿈 기호 기준으로 문자열로 리턴
  • close()는 사용 종료를 의미하고, hasNext()는 Ctrl+Z 입력이 있을 때 false 리턴함 (그 전에는 무한정 대기)

4-2. Object 클래스

  • 모든 클래스의 최상위 클래스, 메소드를 오버라이딩해서 써야 함
  • Object 메소드는 모든 클래스에서 다 사용할 수 있음
// 객체가 가진 값을 비교할 때 사용 ('=='은 주소의 값을 비교함)
equals

// 객체가 가진 값을 문자열로 반환
toString

// 객체의 해시코드 값 변환
hashCode

4-3. java.lang 패키지/오토박싱

  • import 하지 않고도 사용할 수 있음
  • 기본형 타입을 객체로 변환시킬 때 사용하는 Wrapper 클래스가 있음
    (Boolean, Byte, Short, Integer, Long, Float, Double)
  • Object, String, StringBuffer, StringBuilder, System, Math도 java.lang 패키지
public class WrapperExam { 
  public static void main(String[] args) { 
    int i = 5;
    Integer i2 = new Integer(5);
    Integer i3 = 5; //오토박싱 : 자동으로 Integer 형태로 변환
    int i4 = i2.intValue();
    int i5 = i2; //오토언박싱 : 객체 타입의 값을 기본형 int로 변환
  }
}

4-4. StringBuffer, String

  • StringBuffer의 대부분 메소드는 자기자신을 반환
StringBuffer sb = new StringBuffer();

sb.append("hello");  
sb.append(" ");  
sb.append("world");

String str = sb.toString();

// 메소드 체이닝  
String str2 = new StringBuffer().append("hello").append(" ").append("world").toString();

// StringBuffer는 thread-safe하게 설계되어 멀티 스레드 환경에서 안전하게 사용할 수 있지만, 성능이 떨어질 수 있음  
// StringBuilder는 단일 스레드 환경에서 더 빠르게 동작할 수 있음 (String을 결합할 때마다 객체를 생성 X)
  • String 클래스는 문자열을 다룰 때 사용하는 클래스
  • String 클래스는 불변 클래스
  • String의 메소드 중 String을 반환하는 메소드는 모두 새로운 String을 생성해 반환함

// new 연산자를 사용하지 않고 인스턴스 생성 -> 상수 (str1 == str11)  
String str1 = "hello";  
String str11 = "hello";

// new 연산자를 사용해 인스턴스 생성 -> 다른 인스턴스 (str2 != str22)  
String str2 = new String("hello");  
String str22 = new String("hello");

// 문자열 자르기  
String str3 = str1.substring(3); // str1은 변화 없음

// 길이 구하기  
str1.length()

// 문자열 붙히기  
str1.concat(" world");  
String str3 = str1 + str2;


// 내부적으로 다음과 같은 코드 실행  
// '+' 기호, concat() 메서드를 사용하면 문자열을 결합할 때마다 새로운 String 객체가 생성되어 성능에 문제가 생길 수 있음 
String str4 = new StringBuffer().append(str1).append(str2).toString();

4-5. Math 클래스

  • 생성자가 private으로 되어 있어 new 연산자를 사용해 객체를 생성할 수 업슴
  • 모든 메소드와 속성이 static으로 정의되어 있어 객체를 생성하지 않고도 사용할 수 있음
public class MathExam {  
  public static void main(String\[\] args) {  
    int value1 = Math.max(5, 20);  
    int value2 = Math.min(5, -5);  
    int value3 = Math.abs(-10);  
    double value4 = Math.random();  
    double value5 = Math.sqrt(25);  
    double value6 = ceil(4.67);  
    double value7 = floor(4.67);  
    double value8 = pow(4, 5);  
    double value9 = round(4.67);  
  }  
}

4-6. java.util 패키지

  • 날짜와 관련된 클래스인 Date, Calendar 클래스가 포함됨
  • Date 클래스는 지역화를 지원하지 않아 Calendar 클래스가 등장함 (Locale로 시작하는 클래스가 지역화와 관련된 클래스)
  • 자료구조와 관련된 컬렉션 프레임워크 List, Set, Collection, Map 등이 포함됨
  • 컬렉션 프레임워크에서는 Collection 인터페이스가 가장 기본이 됨 (중복 허용, 순서 기억 X)
  • Collection은 저장된 자료를 하나씩 꺼낼 수 있는 Iterator 인터페이스를 반환함
import java.util.*;

// Collection  
add() // 추가  
size() // 크기  
iterator()

// Iterator  
hasNext() // 꺼낼 것이 있는지 여부  
next() // 하나씩 자료 꺼낼 때 사용

// Set : 중복 허용 X

Set set1 = new HashSet()<>();  
set1.add("kim"); // 같은 자료가 있으면 false, 없으면 true 반환

Iterator iter = set1.iterator();

while (iter.hasNext()) { // 꺼낼 것이 있다면 true 리턴.  
  String str = iter.next(); // next()메소드는 하나를 꺼낸다. 하나를 꺼내면 자동으로 다음것을 참조한다.  
  System.out.println(str);  
}

for (String str: set1) {  
    System.out.println(str);  
}

// List : 순서 기억

List list = new ArrayList<>();

list.add("kim");  
list.add("kim");  
list.add("lee");

System.out.println(list.size());  
for(int i = 0; i < list.size(); i++){  
  String str = list.get(i); // 특정 인덱스 자료 꺼냄  
  System.out.println(str);  


// ArrayList
// 배열과 달리 크기가 가변적, 객체를 데이터로 다뤄 메모리를 많이 차지함

ArrayList<Integer> members = new ArrayList<>();
ArrayList<Integer> num3 = new ArrayList<>(10); // 초기 용량(capacity)지정
ArrayList<Integer> list2 = new ArrayList<>(Arrays.asList(1,2,3)); // 배열을 넣어 생성
ArrayList<Integer> list3 = new ArrayList<>(list2); // 다른 컬렉션으로부터 그대로 요소를 받아와 생성

num3.add(1);
num3.add(2);
num3.add(0, 3); // 기존 데이터는 뒤로 물러남

// 인덱스가 용량이나 크기를 넘어서면 오류 발생
num3.add(11, 3);
num3.add(8, 3);
num3.ensureCapacity(15); // 최소 용량 수정

num3.remove(1);

ArrayList<String> list1 = new ArrayList<>();
list1.add("A");
list1.add("B");
list1.add("C");

list1.contains("A");  // list에 A가 있는지 검색
list1.indexOf("A"); // list에 D가 있는지 순차적으로 검색하고 index를 반환 (만일 없으면 -1)
list1.lastIndexOf("A"); // list에 D가 있는지 역순으로 검색하고 index를 반환 (만일 없으면 -1)
list1.set(1, "setData"); // 데이터 변경
list1.get(2); // 데이터 조회



// Map : Key, Value 존재 (Key 중복 X)

// Key, Value가 모두 String 타입인 HashMap인스턴스를 만듭니다.  
Map<String, String> map = new HashMap<>();

map.put("001", "kim"); // key, value 저장  
map.put("002", "lee");  
map.put("003", "choi");  
map.put("001", "kang"); // 같은 key가 2개 있을 수 없음 -> 값 변경

System.out.println(map.size());  
System.out.println(map.get("001")); // 특정 키의 값을 꺼냄

// map에 저장된 모든 key들을 Set자료구조로 꺼냅니다.  
Set keys = map.keySet(); // 모든 key로 이루어진 set
map.containsKey("001");
map.containsValue("lee");


Iterator iter = keys.iterator();  
while (iter.hasNext()) {  
  String key = iter.next();  
  String value = map.get(key);  
  System.out.println(key + " : " + value);  
}

4-7. 문자열 포매팅


// 출력  
String name = "Alice";  
int age = 25;  
System.out.printf("My name is %s and I am %d years old.", name, age);

// String.format  
// 정수 : %d, 부동 소수 : %f, char : %c, 문자열 : %s  
String s2 = String.format("s2 : |%10d|",12345);//10자리 차지 , 우측 정렬 // s2 : | 12345|  
String s3 = String.format("s3 : |%-10d|",12345);//10자리 차지 , 좌측 정렬 // s3 : |12345 |  
String s9 = String.format("s3 : |%07d|",12345);//빈칸은 0으로 채움 // s9 : |0012345|

String s5 = String.format("s5 : |%.1f|",123.4567); //소숫점 아래 몇째자리까지 나타낼 것인지 설정 // s5 : |123.5|  
String s7 = String.format("s7 : |%9.3f|",123.45); //전체 길이 : 9 / 소숫점 아래 셋째자리 / 우측 정렬 // s7 : | 123.450|  
String s8 = String.format("s8 : |%09.3f|",123.45); //빈칸은 0으로 채우기 // s8 : |00123.450|

// Text Block  (프로그래머스에서 오류가 났는데 버전 문제인 건지 문법을 잘못 쓴 건지 확인해봐야 할 것 같다)
String name = "John Doe";  
int age = 30;

String message = """  
My name is %s and I'm %d years old.  
""".formatted(name, age);

System.out.println(message);

4-8. 형변환

// 타입 확인
// primitive 타입은 Wrapper 클래스 타입으로 확인
int pri_value = 1;
System.out.println(((Integer) pri_value).getClass().getSimpleName());

int a = 1;
System.out.println(Integer.class.isInstance(a)); // true




// String => Array<char>
String a = "abc"
for (char alp: a.toCharArray()) {
    if (Character.isUpperCase(alp)) {
        System.out.println(Character.toLowerCase(alp));
    } else {
        System.out.println(Character.toUpperCase(alp));
    }
}

// String => char
a.charAt(0);


// String => int

String num = "10";

int i_num = Integer.parseInt(num);
int i_num2 = Integer.valueOf(num);

// String => double, float
double d_num = Double.valueOf(num);
float f_num = Float.valueOf(num);

// String => long, short
long l_num = Long.parseLong(num);
short s_num = Short.parseShort(num);


// int => String
int num = 10;

String s_num = String.valueOf(num);
String s_num = Integer.toString(num);

// double, float => String

float f_num = 10.1;
double d_num = 10.1;

String s_num;

s_num = String.valueOf(f_num);
s_num = String.valueOf(d_num);
s_num = Float.toString(f_num);
s_num = Double.toString(d_num);


// double, float => int

double d_num = 10.11;
float f_num = 10.111;

int i_num;

i_num  = (int)d_num;
i_num = (int)f_num;


// int => double, float

double d_num = (double)i_num;
float f_num = (float)i_num;


// char => int
char myChar = '3';
int myInt = Character.getNumericValue(myChar);        
System.out.println(myInt);


// Integer => int
Integer num = 1;
int parseInt = num.intValue();

// int => Integer
Integer integer = new Integer(parseInt);

출처

다중 선언, 다중 할당 - https://pcm9881.tistory.com/167

자바 입문 강의 - https://school.programmers.co.kr/learn/courses/5/5-%EB%AC%B4%EB%A3%8C-%EC%9E%90%EB%B0%94-%EC%9E%85%EB%AC%B8

자바 중급 강의 - https://school.programmers.co.kr/learn/courses/9/9-%EC%9E%90%EB%B0%94-%EC%A4%91%EA%B8%89

배열의 합, 평균 - https://hianna.tistory.com/553

배열 요소 추가 - https://seoulitelab.tistory.com/entry/Java%EC%9E%90%EB%B0%94-%EB%B0%B0%EC%97%B4%EC%97%90-%EC%83%88%EB%A1%9C%EC%9A%B4-%EC%9A%94%EC%86%8C-%EC%B6%94%EA%B0%80%ED%95%98%EB%8A%94-%EC%97%AC%EB%9F%AC-%EA%B0%80%EC%A7%80-%EB%B0%A9%EB%B2%95

arrayList - https://inpa.tistory.com/entry/JAVA-%E2%98%95-ArrayList-%EA%B5%AC%EC%A1%B0-%EC%82%AC%EC%9A%A9%EB%B2%95#arraylist_%EA%B0%9D%EC%B2%B4_%EC%83%9D%EC%84%B1

map - https://devlogofchris.tistory.com/41

입출력 - https://cocoon1787.tistory.com/38

입력 - https://recordevelop.tistory.com/entry/Java-%ED%99%94%EB%A9%B4%EC%97%90%EC%84%9C-%EC%9E%85%EB%A0%A5-%EB%B0%9B%EA%B8%B0-Scanner%EC%8A%A4%EC%BA%90%EB%84%88-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95%EA%B3%BC-%EB%A9%94%EC%84%9C%EB%93%9C

입출력 - https://shutcoding.tistory.com/entry/%EC%9E%90%EB%B0%94-%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98-%EC%9E%85%EC%B6%9C%EB%A0%A5-%EB%B0%9B%EA%B8%B0

빠른 입출력 - https://velog.io/@focusonmx/Java-%EB%B9%A0%EB%A5%B8-%EC%9E%85%EC%B6%9C%EB%A0%A5

입출력, 배열에서의 형변환 - https://adjh54.tistory.com/153

문자열 포매팅 - https://withuscloud.com/4

문자열 포매팅 - https://innovation123.tistory.com/94

타입 확인 - https://inpa.tistory.com/entry/JAVA-%F0%9F%9A%80-%EC%9E%90%EB%B0%94-%EB%B3%80%EC%88%98%EC%9D%98-%ED%83%80%EC%9E%85-%EC%96%BB%EA%B8%B0-typeof

형변환 - https://intheham.tistory.com/119

형변환 - https://velog.io/@juntree/Java-%ED%98%95%EB%B3%80%ED%99%98%EB%AC%B8%EC%9E%90%ED%98%95%EC%A0%95%EC%88%98%ED%98%95%EC%8B%A4%EC%88%98%ED%98%95

형변환 - https://priming.tistory.com/23

형변환, 배열 - https://jeongkyun-it.tistory.com/198