본문 바로가기
Algorithm

Java 알고리즘 풀이 기능 구현, 메서드 호출 모음

by brother_stone 2023. 3. 25.

지금까지 알고리즘 문제를 파이썬으로 풀다가 자바로 풀다보니 아이디어는 금방 떠올라도 코드로 구현하는 게 익숙하지 않아서 너무 오랜 시간이 걸리는 문제점이 있다.

그래서 공통적으로 사용하는 코드나 메서드 사용 코드를 정리하고 반복적으로 사용하면서 궁극적으로 문제 풀이 시간을 줄여보려고 한다.

이미 작성한 내용이라도 더 효율적인 코드 발견 시 지속적으로 업데이트 할 예정이다.

출처: 이것이 자바다 15.1 컬렉션 프레임워크

Arrays

Arrays.copyOfRange()

/**
* @param <T> the class of the objects in the array
* @param original the array from which a range is to be copied
* @param from the initial index of the range to be copied, inclusive
* @param to the final index of the range to be copied, exclusive.
*/
public static <T> T[] copyOfRange(T[] original, int from, int to) {
    return copyOfRange(original, from, to, (Class<? extends T[]>) original.getClass());
}

예시

String[] names = {"Alex", "Brian", "Charles", "David"};
// till second name from with index '0'
String[] partialNames = Arrays.copyOfRange(names, 0, 2);        // [Alex, Brian]
//Copy all names from with index '2'
String[] endNames = Arrays.copyOfRange(names, 2, names.length);    // [Charles, David]
//Copy last 8 names start with index '2'
//No ArrayIndexOutOfBoundsException error
String[] moreNames = Arrays.copyOfRange(names, 2, 10);   // [Charles, David, null, null, null, null, null, null]

Collection

Collection자료구조(List, Set 등)를 array로

기본형

<T> T[] toArray(T[] a)

예시

List<Integer> list = new ArrayList<>();

Integer[] arr = list.toArray(new Integer[0]);

toArray의 매개변수로 들어가는 배열의 크기가 collection의 크기보다 작다면, 배열은 collection의 크기로 생성되고 기존 요소를 모두 갖는다.

그렇지 않고, 배열의 크기가 더 크다면 collection의 모든 요소를 갖고 나머지 요소는 기본값 null을 갖는다.

참고로 제네릭 타입이기 때문에 기본타입은 들어갈 수 없다. 반드시 박싱 후 사용하자.

일반적으로 list를 그대로 배열로 만드는 상황이 더 많을 것이다. 따라서 매개변수로 새로운 배열을 생성, size를 0으로 주어 사용하면 되겠다.

예시2(List<int[]> -> int[][])

private List<int[]> hist = new ArrayList<>();
return hist.toArray(new int[0][]);

어떤 Collection타입을 특정 Collection에 모두 추가 - Collection.addAll()

        List<String> filtered = _map.entrySet()
            .stream()
            .filter(e->e.getValue()==max&&e.getValue()>1)
            .map(e->e.getKey())
            .collect(Collectors.toList());

        list.addAll(filtered);

Collections

참고(이것이 자바다 Chapter15. 컬렉션 자료구조, java docs)

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Collections.html

https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Collection.html

import

import java.util.Collections

collection의 최대 · 최소 element

기본형

//최댓값
static <T> T max(collection<? extends T>);

//최솟값
static <T> T min(collection<? extends T>);

collection element 정렬

기본형

//오름차순 정렬
static <T> void Collections.sort(list)

* 추후 Comparable, Comparator 개념 링크 추가

내림차순 코드 예시

Collections.sort(list, Collections.reverseOrder());
Collections.sort(list, (e1,e2)->e2-e1);

reverseOrder()는 Arrays.sort나 PriorityQueue 생성 등에서 사용할 수 있다.

String

String indexing

기본형

char charAt(int index)

예시

String alphabet = "abcdefghi"; //문자열의 두번째 문자 추출. (return type: char) char b = alphabet.charAt(1); //예시) String[]의 y번째 요소의 x번째 문자가 'O'||'S'일 때 if(park[y].charAt(x)=='O'||park[y].charAt(x)=='S')

String to CharArray()

String을 한글자씩 순환할 목적으로 문자열 자체를 향상된 for문의 배열변수로 사용하려고 한적이 있다.

하지만 향상된 for문은 array 혹은 java.lang.Iterable 타입만 사용가능하다. 따라서 이를 구현하기 위해선 아래와 같이 char배열로 변환 후 char 혹은 Character 타입으로 받는 방법을 이용할 수 있다.

private int hash(K key) {
    int hash = 0;

    for (Character ch : key.toString().toCharArray()) {
        hash += (int) ch;
    }

    return hash % this.bucketSize;
}

StringTokenizer

public StringTokenizer(String str,
                       String delim,
                       boolean returnDelims)
Constructs a string tokenizer for the specified string. All characters in the delim argument are the delimiters for separating tokens.
If the returnDelims flag is true, then the delimiter characters are also returned as tokens. Each delimiter is returned as a string of length one. If the flag is false, the delimiter characters are skipped and only serve as separators between tokens.

Note that if delim is null, this constructor does not throw an exception. However, trying to invoke other methods on the resulting StringTokenizer may result in a NullPointerException.

Parameters:
str - a string to be parsed.
delim - the delimiters.
returnDelims - flag indicating whether to return the delimiters as tokens.

StringTokenizer는 보통 delim이 whitespace일 때 StringTokenizer(String str)형식으로 생성해서 사용한다.

하지만 공백으로 토크나이징하되, 토큰에 공백까지 포함하고자 한다면 위 생성자 형식을 사용하면된다.

예시

StringTokenizer st = new StringTokenizer(str, " ", true);

Map

Map자료구조의 특정 key값이 존재하는지

기본형

boolean containsKey(Object key)

예시

if (map.containsKey(kind)) {
    map.get(kind).add(name); 
    continue;
}

Map자료구조에 특정 value값이 존재하는지

기본형

 boolean containsValue(Object value)

Map의 모든 entry를 Set으로 받아 순회하는 예시

    Set<Map.Entry<String, Integer>> entries = map.entrySet();
        for(Map.Entry<String, Integer> entry: entries){
            if(entry.getKey().length()==menuSize){
                _map.put(entry.getKey(), entry.getValue());
            }
        }

Set

Set 자료구조에 특정 값이 존재하는지

boolean contains(Object o)

Set 자료구조에 특정 Collection이 존재하는지

boolean containsAll(Collection<?> c)

Set을 공집합으로

void clear()

Stream

int배열의 모든 원소의합

Arrays.stream(arr)
            .mapToInt(i->i)
            .sum();
    }

int배열을 List로 변환

List<Integer> list = Arrays.stream().boxed().collect(Collectors.toList());

int배열을 Integer배열로 변환

Integer[] _arr = Arrays.stream(arr).boxed().toArray(Integer[]::new);

Integer배열은 int배열을 내림차순 정렬할 때 변환이 필요하므로 이 때 사용될 수 있다.

Integer배열을 int배열로 변환

Integer[] integerArr = {1,2,3,4};
int[] intArr = Arrays.stream(integerArr).mapToInt(Integer::intValue).toArray();

mapToInt는 스트림의 중간 메서드로 기본적인 메커니즘은 map과 같되, intStream을 반환하는 메서드이다.

mapToXXX는 모두 같은 원리이다.

List를 int배열로 반환

List<Integer> list = List.of(1,2,3,4);
int[] intArr = list.stream().mapToInt(Integer::intValue).toArray();