자바 코테 벼락치기..🥲(입력, 배열, 리스트, 문자열)+스트림

Minji Lee·2025년 3월 20일
0

JAVA

목록 보기
11/13

기본으로 넣어두면 좋은 import 문

import java.util.*;
import java.io.*;

// IOException을 붙여주지 않으면 BufferedReader 사용할 때 readLine()에서 에러 발생!
public static void main(String[] args) throws IOException

입력받기

BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());

// 4 5 7 일렬로 입력받을 경우
StringTokenizer st = new StringTokenizer(br.readLine());
int x = Integer.parseInt(st.nextToken());
import java.util.*;
import java.io.*;

public class Exam {
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        System.out.println("n" + n);

        StringTokenizer st = new StringTokenizer(br.readLine());
        int a = Integer.parseInt(st.nextToken());
        int b = Integer.parseInt(st.nextToken());

        System.out.println("a>>"+a+" b>>"+b);
    }
}


배열

1차원 배열 정의

import java.io.*;

public class Exam {
    // 2. 선언 후, 함수 안에서 초기화
    static boolean[] visited; // 2-1 static으로 선언
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        // 배열은 길이가 고정이다!
        // 1. 선언 + 초기화
        int[] arr = {5, 0, 2, 3, 4, 1};
        
        visited = new boolean[n+1]; // 2-2 초기화
    }
}

2차원 배열 정의

import java.io.*;

public class Exam {
    // 2. 선언 후, 함수 안에서 초기화
    static int[][] problems; // 2-1 static으로 선언
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());
        // 2차원 배열도 길이가 고정이다!
        // 1. 선언 + 초기화
        int[][] arr = new int[][]{{5, 40}, {3, 50}, {1, 30}};

        problems = new int[n][2]; // 2-2 초기화 -> nx2 배열
    }
}

리스트

배열의 크기를 모를 때 길이가 가변인 리스트를 사용

  • 보통 그래프 문제에서 많이 쓰임

행의 수는 고정이고, 열의 수는 가변인 2차원 리스트

import java.util.*;
import java.io.*;

public class Exam {
    static List<Integer>[] graph;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        graph = new ArrayList[n+1];

        System.out.println(Arrays.toString(graph)); // n이 3일 때 [null, null, null, null]
        for(int i=0;i<n+1;i++){
            graph[i] = new ArrayList<>();
        }
        System.out.println(Arrays.toString(graph)); // [[], [], [], []]
    }
}

행의 수는 가변이고, 열의 수는 고정인 경우

import java.util.*;
import java.io.*;
import java.util.stream.Collectors;

public class Exam {
    static List<int[]> graph;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        int n = Integer.parseInt(br.readLine());

        graph = new ArrayList<>(); // 가변 리스트 추가

        System.out.println(graph); // n이 2일 때 []
        for(int i=0;i<n+1;i++){
            st = new StringTokenizer(br.readLine());
            int node1 = Integer.parseInt(st.nextToken());
            int node2 = Integer.parseInt(st.nextToken());
            graph.add(new int[]{node1, node2});
        }

        // 리스트를 스트림객체로 변환 후, 각 요소를 String 으로 변환 후 리스트로 출력
        System.out.println(graph.stream().map(Arrays::toString).collect(Collectors.toList())); // [[1, 4], [5, 7], [3, 6]]
    }
}

둘 다 가변인 경우, 명확하게 ArrayList 사용할 것이면, ArrayList로 선언해도 좋음!

import java.util.*;
import java.io.*;

public class Exam {
    static List<List<Integer>> graph;
    // static ArrayList<ArrayList<Integer>> graph;
    public static void main(String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int n = Integer.parseInt(br.readLine());

        graph = new ArrayList<>(); // 가변 리스트 추가

        System.out.println(graph); // n이 2일 때 []
        for(int i=0;i<n;i++){
            graph.add(new ArrayList<>()); // 각 행도 ArrayList로 초기화
        }
        
        System.out.println(graph); // [[], []]
    }
}

배열 메서드

배열 슬라이싱

public class Exam {
    public static void main(String[] args) throws IOException{
        int[] arr = {0, 1, 2, 3, 4, 5};
        arr = Arrays.copyOfRange(arr, 2, 4); // 인덱스 2~3까지 슬라이싱
        System.out.println(Arrays.toString(arr)); // [2, 3]
    }
}

배열 중복된 값 제거

public class Exam {
    public static void main(String[] args) throws IOException{
        int[] arr = {0, 1, 2, 3, 4, 5, 5, 1, 2, 3};
        // 중복 제거 후 다시 배열에 넣기
        arr = Arrays.stream(arr).distinct().toArray();
        System.out.println(Arrays.toString(arr)); // [0, 1, 2, 3, 4, 5]
    }
}

배열 정렬

오름차순 정렬

public class Exam {
    public static void main(String[] args) throws IOException{
        int[] arr = {5, 3, 2, 1, 4, 9, 4, 6};
        Arrays.sort(arr);
        System.out.println(Arrays.toString(arr)); // [1, 2, 3, 4, 4, 5, 6, 9]

        // 인덱스 1~3까지 오름차순 정렬
        int[] arr2 = {5, 3, 2, 1, 4, 9, 4, 6};
        Arrays.sort(arr2, 1, 4);
        System.out.println(Arrays.toString(arr2)); // [5, 1, 2, 3, 4, 9, 4, 6]
    }
}

내림차순 정렬

public class Exam {
    public static void main(String[] args) throws IOException{
        int[] arr = {5, 3, 2, 1, 4, 9, 4, 6};
        // int형에서 Integer로 변환해서 사용
        Integer[] arr2 = Arrays.stream(arr).boxed().toArray(Integer[]::new);
        Arrays.sort(arr2, Comparator.reverseOrder());
        System.out.println(Arrays.toString(arr2)); // [9, 6, 5, 4, 4, 3, 2, 1]
    }
}

2차원 배열 특정 조건 기준으로 정렬

import java.util.*;
import java.io.*;
import java.util.stream.Collectors;

public class Exam {
    public static void main(String[] args) throws IOException{
        int[][] arr = new int[][]{{5,40}, {3, 50}, {1,30}, {2, 20}, {2, 10}};

        // 첫번째 숫자 기준 오름차순
        Arrays.sort(arr, Comparator.comparingInt((int[] o) -> o[0]));
        System.out.println(Arrays.stream(arr).map(Arrays::toString).collect(Collectors.toList())); // [[1, 30], [2, 20], [2, 10], [3, 50], [5, 40]]

        // 첫번째 숫자 기준 내림차순
        Arrays.sort(arr, Comparator.comparingInt((int[] o) -> o[0]).reversed());
        System.out.println(Arrays.stream(arr).map(Arrays::toString).collect(Collectors.toList())); // [[5, 40], [3, 50], [2, 20], [2, 10], [1, 30]]

        // 첫 번째 숫자 기준으로 오름차순, 첫 번째 숫자가 같으면 두 번째 숫자 기준 내림차순 정렬
        Arrays.sort(arr, Comparator.comparingInt((int[] o) -> o[0]).thenComparingInt(o->-o[1]));
        System.out.println(Arrays.stream(arr).map(Arrays::toString).collect(Collectors.toList())); // [[1, 30], [2, 20], [2, 10], [3, 50], [5, 40]]
    }
}

리스트 정렬

public class Exam {
    public static void main(String[] args) throws IOException{
        // 초기 요소를 가진 ArrayList 생성
        List<Integer> arr = new ArrayList<>(Arrays.asList(5, 0, 2, 3, 4, 9, 1));

        // 오름차순
        Collections.sort(arr);
        System.out.println(arr); // [0, 1, 2, 3, 4, 5, 9]
        // 내림차순
        Collections.sort(arr, Comparator.reverseOrder());
        System.out.println(arr); // [9, 5, 4, 3, 2, 1, 0]
    }
}

숫자와 문제열 변환

Integer.toString(n); // 숫자 -> 문자열
Integer.parseInt(s); // 문자열 -> 숫자

리스트 관련 함수

// String 타입의 빈 리스트 생성
List<String> arr = new ArrayList<>();
// 초기 요소 가진 리스트 생성
List<String> arr2 = new ArrayList<>(Arrays.asList("부산, 서울"));
// 리스트 메서드
arr.add("서울"); // 리스트 가장 뒤에 삽입
arr.add("제주");
arr.add(0, "대전"); // 0인덱스 위치에 대전 삽입
System.out.println(arr); // [대전, 서울, 제주]
arr.addAll(arr2); // arr2 리스트에 있는 모든 요소 arr1에 추가
System.out.println(arr); // [대전, 서울, 제주, 부산, 서울]
arr.get(0); // 0 위치 값 반환
arr.set(1, "제주"); // 1 위치의 값을 제주로 변경
arr.indexOf("제주"); // 제주의 첫 번째 인덱스 반환
arr.lastIndexOf("제주"); // 제주의 마지막 인덱스 반환
arr.isEmpty(); // 리스트가 비어있는지
arr.size(); // 리스트 길이
arr.contains("서울"); // 서울이 포함되어있으면 true
arr.containsAll(arr2); // arr에 arr2의 모든 값이 포함되어있는지 확인
arr.remove(0); // 0번째 인덱스 값 삭제
arr.remove("제주"); // 해당 값 삭제
arr.removeIf(k -> k.equals("부산")); // 람다식으로 arr 안의 값이 부산이라는 값과 같으면 삭제
arr.removeAll(arr2); // arr에서 arr2에 들어있는 모든 값 삭제
arr.retainAll(arr2); // arr에서 arr2에 들어있는 값들을 제외한 모든 값 삭제
arr.clear(); // 리스트 초기화

문자열 관련 함수

String str = "abcdec";

str.length(); // 길이
str.isEmpty(); // 빈 문자열인지
str.charAt(2); // 인덱스의 문자 찾기 ex) c
str.indexOf("c"); // 문자로 첫 번째 인덱스 찾기 ex) 2
str.lastIndexOf("c"); // 문자로 마지막 인덱스 찾기 ex) 5
str.substring(2,4); // 2~3 위치의 문자열 반환 ex) cd
str.substring(3); // 3부터 끝까지 문자열 반환 ex) dec
str = str.replace('b', 'k'); // 문자 변경
str.equals("akcdec"); // 문자열 동일하면 true
str.contains("de"); // 문자열 포함되어있으면
str.trim(); // 문자열 앞 뒤 공백 제거
str = str.toLowerCase(); // 소문자로
str = str.toUpperCase(); // 대문자로
str.compareTo("AKCED"); // 사전 순 비교
String[] s = str.split(""); // 띄어쓰기 없는 문자열 한 문자씩 분리해서 String 배열로 반환
System.out.println(Arrays.toString(s)); // [A, K, C, D, E, C]
str = String.join("", s); // String 배열을 ""안의 문자로 연결해서 다시 문자열로 반환
char[] charArr = str.toCharArray(); // 문자열 한 문자씩 분리해서 char 배열로 반환
str = str.replaceAll("[^0-9]]", " "); // 0-9가 아닌 것들을 공백으로 치환

StringBuilder 관련 함수

String str = "Hello Java!"; // String은 한 번 만들어지면, 문자 추가하거나 삭제 불가능
StringBuilder sb = new StringBuilder();
for(int i=0;i<str.length();i++){
    // String 문자열을 StringBuilder로 변환
    sb.append(str.charAt(i));
}

sb.insert(1, "eee"); // 1 위치에 삽입 Heeeello Java!
sb.delete(1, 3); // 1-2위치 문자열 삭제 Heello Java!
sb.deleteCharAt(1); // 1 위치의 문자열 삭제 Hello Java!
int index = sb.indexOf("!"); // 해당문자 첫 번쨰 인덱스 찾기
sb.setCharAt(index, '~'); // !위치의 문자를 ~로 변경
sb.reverse(); // 문자열 거꾸로 뒤집기
sb.setLength(2); // 문자열 길이를 2로 줄임

[Java] 코딩테스트 벼락치기 정리 1편


자바 스트림(Stream)

Java 8부터 추가된 기술로 람다를 활용해 배열과 컬렉션을 함수형으로 간단하게 처리할 수 있는 기술

  • 기존의 for문과 Iterator를 사용하면 코드가 길어져 가독성과 재활용성 떨어지며 데이터 타입마다 다른 방식으로 다뤄야 하는 불편함 존재
  • 스트림은 데이터 소스를 추상화하고, 데이터를 다루는데 자주 사용되는 메서드를 정의해 놓아서 데이터 소스에 상관없이 모두 같은 방식으로 다룰 수 있는 코드의 재사용성이 높아짐

스트림 특징

  • 원본 데이터 소스 변경하지 않음
  • 일회용이다 → 한번 사용하면 닫혀서 재사용 불가능
  • 최종 연산 전까지 중간 연산 수행X
  • 작업을 내부 반복으로 처리한다.
  • 병렬 처리가 쉽다
  • 기본형 스트림 제공한다.

스트림 사용 절차

  1. 스트림 만들기
// 배열 스트림: Arrays.stream()
String[] arr = new String[]{"a", "b", "c"};
Stream<String> stream = Arrays.stream(arr);

// 컬렉션 스트림: .stream()
List<String> list = Arrays.asList("a","b","c");
Stream<String> stream1 = list.stream();

// Stream.builder()
Stream<String> builderStream = Stream.<String>builder().add("a").add("b").add("c").build();

// 람다식 Stream.generate(), iterate()
Stream<String> generatedStream = Stream.generate(() -> "a").limit(3);
// 생성할 때 스트림의 크기가 정해져있지 않기 때문에 최대 크기를 제한해주어야 함

// 기본 타입형 스트림
IntStream intStream = IntStream.range(1,5); // [1,2,3,4]

// 병렬 스트림: parallelStream()
Stream<String> parallelStream = list.parallelStream();
  1. 중간 연산(가공하기)
  • 필터링: 스트림 내 요소들을 하나씩 평가해서 걸러내는 작업
List<String> list = Arrays.asList("a","b","c");
Stream<String> stream = list.stream().filter(l -> l.contains("a"));
System.out.println(stream.collect(Collectors.toList())); // [a]
  • 맵핑: 스트림 내 요소들을 하나씩 특정 값으로 변환하는 작업
List<String> list = Arrays.asList("a","b","c");
Stream<String> stream = list.stream().map(String::toUpperCase); // 대문자로 변경
List<String> list2 = Arrays.asList("1","2","3");
Stream<Integer> stream2 = list2.stream().map(Integer::parseInt); //  문자열 -> 정수로 변환

System.out.println(stream.collect(Collectors.toList())); // [A, B, C]
System.out.println(stream2.collect(Collectors.toList())); // [1, 2, 3]
  • Sorting: 스트림 내 요소들을 정렬하는 작업, Comparator 사용
List<String> list = Arrays.asList("a","b","c");
Stream<String> stream = list.stream()
        .sorted() // [a, b, c] 오름차순 정렬
        .sorted(Comparator.reverseOrder()); // 내림차순
List<String> list2 = Arrays.asList("a", "bb", "ccc");
Stream<String> stream1 = list2.stream().sorted(Comparator.comparingInt(String::length)); // 문자열 길이 기준 정렬
  • 기타 연산
List<String> list = Arrays.asList("a","b","c");
Stream<String> stream = list.stream()
                .distinct() // 중복 제거
                .limit(max) // 크기 제한
                .skip(n) // 앞에서부터 n개 skip
                .peek(System.in::println); // 중간 작업결과 확인
  1. 최종 연산(결과 만들기)
  • Calculating: 기본형 타입을 사용하는 경우 스트림 내 요소들로 최소, 최대, 합, 평균 구하는 연산 수행
IntStream stream = list.stream()
                .count() // 스트림 요소 개수 반환
                .sum() // 스트림 요소 합 반환
                .min() // 스트림 최솟값 반환
                .max() // 스트림 최대값 반환
                .average(); // 스트림 평균값 반환
  • Reduction: 스트림 요소를 하나씩 줄여가며 누적연산 수행
int sum = IntStream.range(1, 6)
                .reduce(10, (total, num) -> total+num);
                // reduce(초기값, (누적 변수, 요소) -> 수행문)
System.out.println(sum); // 20 = 10 + 1 + 2 + 3 + 4 +5
  • Collecting: 스트림 요소를 원하는 자료형으로 변환
List<Person> members = Arrays.asList(new Person("lee", 26),
                new Person("kim", 23),
                new Person("park", 23));

// toList(): 리스트로 반환
members.stream().map(Person::getLastName).collect(Collectors.toList()); // [lee, kim, park]

// joining(): 작업 결과를 하나의 스트링으로 이어 붙이기
members.stream().map(Person::getlastName).collect(Collectors.joining(delimiter="+", prefix="<", suffix=">")); // <lee+kim+park>

// groupingBy(): 그룹지어서 Map으로 반환
members.stream()
	.collect(Collectors.groupingBy(Person::getAge));
    // {26 = [Person{lastName="lee",age=26}],
    //  23 = [Person{lastName="kim",age=23},Person{lastName="park",age=23}]}

// collectingAndThen(): collecting 이후 추가 작업 진행
members.stream().collect(Collectors.collectingAndThen(Collectors.toSet(), Collections.unmodifiableSet));
// Set으로 collect한 후 수정불가한 set으로 변환하는 작업 실행
  • Matching: 특정 조건 만족하는 요소가 있는지 체크한 결과 반환
    - anyMatch: 하나라도 만족하는지
    • allMatch: 모두 만족하는지
    • noneMatch: 모두 만족하지 않는지
List<String> members = Arrays.asList("Lee","Park","Hwang");

boolean matchResult = members.stream().anyMatch(member -> member.contains("w"));
boolean matchResult2 = members.stream().allMatch(member -> member.length() >= 4); // 모든 요소의 길이가 4인지
boolean matchResult3 = members.stream().noneMatch(member -> member.endsWith("t"));
  • Iterating: forEach로 스트림 돌면서 실행되는 작업
members.stream().map(Person::getName).forEach(System.out::println);
// peek은 중간, forEach는 최종
  • Finding: 스트림에서 하나의 요소 반환
Person person = members.stream()
                .findAny() // 먼저 찾은 요소 하나 반환, 병렬 스트림의 경우 첫번째 요소가 보장되지 않음
                .findFirst(); // 첫번째 요소 반환

자바 Stream

0개의 댓글