728x90
반응형
🔶Stream
🔶코딩테스트
🔶CS 기초 복습
🔶Annotation
≣ 목차
/ 오늘의 TIL /
Stream
range vs rangeClosed
range | rangeClosed |
|
|
//fail이 int[]일 경우 처리 방식
int[] nums = IntStream.range(0, fail.length) //0~fail.length-1 stream 생성
.map(i -> Arrays.stream(fail, i, fail.length).sum()) //fail 배열의 i~fail.length 까지의 부분 배열 stream 만든 후 합계 반환
.toArray(); //int[]로 변환
Map key, value로 각각 내림차순, 오름차순을 진행할 수도 있다.
더보기
참고 문제 https://school.programmers.co.kr/learn/courses/30/lessons/42889
import java.util.HashMap;
public class Solution {
/**
* @param N 스테이지의 개수
* @param stages 게임을 이용하는 사용자가 현재 멈춰있는 스테이지의 번호가 담긴 배열
* @return 실패율이 높은 스테이지부터 내림차순으로 스테이지의 번호가 담겨있는 배열
*
* 시간복잡도: N^2 불가 (stages)
* 실패율: 스테이지에 도달했으나 아직 클리어하지 못한 플레이어의 수 / 스테이지에 도달한 플레이어 수
* 실패율이 같은 스테이지: 작은 번호의 스테이지가 먼저 오도록 작성
* 스테이지에 도달한 유저가 없는 경우 실패율: 0
*
* 인원 수, 실패율을 저장할 배열 생성
* 인덱스에 따라 인원 수가 달라지므로 반복문 진행
* 실패율을 구하고 나면 배열에 그대로 담는다.
* Comparator를 통해 내림차순으로 정렬하고, 동일한 경우는 스테이지 번호 오름차순으로 정렬한다.
* int[] 로 반환한다.
*/
public static int[] solution(int N, int[] stages) {
//인원 수
int[] challenger = new int[N+2];
//각 스테이지 별 인원 수 구하기
for (int stage : stages) challenger[stage]++;
//스테이지 번호, 실패율
HashMap<Integer, Double> fails = new HashMap<>();
double total = stages.length;
//실패율 계산
for (int i=1; i<=N; i++) {
if (challenger[i] == 0) { //도전한 사람이 없는 경우
fails.put(i, 0.); //실패율은 0
} else {
fails.put(i, challenger[i] / total); //실패율
total -= challenger[i]; //현재 스테이지 인원 수 제거
}
}
//실패율 내림차순, 동일할 경우 스테이지 오름차순
//entrySet에는 key, value값이 있다.
return fails.entrySet().stream()
.sorted(((o1, o2) -> Double.compare(o2.getValue(), o1.getValue()))) //value(실패율) 내림차순 정렬
.mapToInt(HashMap.Entry::getKey).toArray(); //key(스테이지) 오름차순 정렬 후, 정수 배열로 변환
}
public static void main(String[] args) {
int[] a = {2, 1, 2, 6, 2, 4, 3, 3};
solution(5, a);
}
}
코딩테스트
명령어에 따른 좌표 이동, 중복되지 않는 경로 개수 구하기
https://school.programmers.co.kr/learn/courses/30/lessons/49994
힌트
음수 좌표인 경우 원점을 (0, 0) -> (0+n, 0+n) 양수 좌표로 수정해서 탐색할 수 있다.
해당 좌표가 유효한 좌표인지 검증한다.
HashSet을 사용하면 중복 경로를 제외하고 값을 구할 수 있다.
방향성이 있는지 없는지 확인을 해야한다.
A 값에 따라 방향성이 정해진다면 HashMap으로 구현할 수 있다.
좌표를 이동하고 난 후, 좌표 업데이트를 해준다.
* 코드
더보기
import java.util.HashMap;
import java.util.HashSet;
public class Solution {
// 좌표평면을 벗어나는지 체크하는 메서드
private static boolean isValidMove(int nx, int ny) {
//0~10까지의 범위 (음수 좌표때문에 원점 (0,0) -> (5,5) 변경)
return 0 <= nx && nx < 11 && 0 <= ny && ny < 11;
}
//좌표 결졍을 위한 해시맵 생성
private static final HashMap<Character, int[]> location = new HashMap<>();
private static void initLocation() {
location.put('U', new int[]{0, 1});
location.put('D', new int[]{0, -1});
location.put('L', new int[]{-1, 0});
location.put('R', new int[]{1, 0});
}
/**
* @param dirs 명령어
* @return 처음 걸어본 길의 길이
*
* 중복 포함 X -> HashSet 이용
*/
public static int solution(String dirs) {
initLocation(); //좌표 객체 생성
int x = 5, y = 5; //원점
HashSet<String> answer = new HashSet<>(); //중복 좌표 처리 X
//주어진 명령어로 움직이면서 좌표 지정
for (int i=0; i<dirs.length(); i++) {
int[] offset = location.get(dirs.charAt(i)); //명령어로 인한 좌표 이동 값
int nx = x + offset[0];
int ny = y + offset[1];
//유효한 좌표값인 경우만 이동 가능하다.
if (!isValidMove(nx, ny)) continue;
//(5, 6) == (6, 5)은 동일한 경로이므로 좌표를 추가해준다.
answer.add(x + " " + y + " " + nx + " " + ny); //(x, y) -> (nx, ny)
answer.add(nx + " " + ny + " " + x + " " + y); //(nx, ny) -> (x, y)
//좌표 이동 값으로 좌표 업데이트
x = nx;
y = ny;
}
return answer.size() / 2;
}
public static void main(String[] args) {
solution("ULURRDLLU");
}
}
CS 기초 복습
- Server: '기능'을 제공해주는 것. 컴퓨터 자체를 말하기도 한다.
- 라이브러리 vs 프레임워크
- 라이브러리: 특정 기능을 수행하기 위한 코드의 모음. 제어 흐름은 개발자가 관리한다.
ex) 김치를 먹고싶을 때, 마트에서 김치를 사서 먹는다(라이브러리 O) / 배추 농사를 짓는다(라이브러리 X) - 프레임워크: 소프트웨어 개발을 위한 구조와 기본적인 코드 흐름을 제공하고, 개발자가 구조 내에서 필요한 부분을 구현한다. 제어 흐름은 프레임워크가 관리한다.
ex) 김치찌개를 만들 때, 밀키트를 사용하고 재료를 추가한다(프레임워크 O) / 하나씩 레시피를 보면서 만든다(프레임워크 X)
- 라이브러리: 특정 기능을 수행하기 위한 코드의 모음. 제어 흐름은 개발자가 관리한다.
- DNS: Domain Name System. 도메인 이름과 IP 주소 간의 변환을 제공하는 인터넷 서비스이다.
- HTTP Method
- GET: query를 통해 데이터를 받는다.
- @RequestParam
- @RestController 덕분에 객체를 반환할 때, 컬럼들의 `getter`가 있다면 스프링이 HTTP Bod에 JSON로 변환해준다.
- POST: HTTP Body를 통해 데이터를 주고 받는다. (JSON)
- @RequestBody
- DTO에 List 객체가 있을 경우, JSON의 배열이 담긴다.
- GET: query를 통해 데이터를 받는다.
Annoation
어노테이션을 사용하는 이유
1. 코드의 가독성 및 명확성 향상
- 코드의 의미와 의도를 명확하게 전달할 수 있다.
- 예시로 @Override는 부모에서 정의한 메서드를 오버라이딩한다는 것을 명확하게 나타낸다.
2. 메타데이터 제공
- 클래스, 메서드, 변수 등에 추가적인 정보를 제공한다.
- 예시로 @Deprecated를 사용할 경우 프로그래밍에서 사용되지 않거나 더이상 추천되지 않는 요소로 판별됩니다.
@Deprecated를 사용하면 해당 요소를 사용할 때 컴파일러가 경고를 표시해줘서 유지보수하기 용이해진다.
이전 버전의 API를 호환성을 유지하면서 새로운 버전으로 업데이트 할 수 있다.
3. 코드 검증 및 유효성 검사
- Bean Validation API에서 @NotNull, @Size 등으로 입력값의 유효성을 검사할 수 있다.
4. 컴파일러 지시
- @SuppressWarnings은 컴파일러에게 특정 경고를 무시하도록 지시한다.
unchecked(타입 안정성이 보장되지 않는 경우), deprecation(deprecated 메서드, 클래스 사용하는 경우), rawtypes(제네릭 타입을 지정하지 않은 경우) 등 옵션을 사용할 수 있다.
5. 프레임워크 통합
- Spring Framework에서 @Autowired를 통해 의존성 주입을 간단하게 처리할 수 있다.
- 어노테이션을 활용하여 설정을 단순화하고 코드 구성을 돕는다.
6. 런타임 처리
- 런타임에 리플렉션을 통해 메타데이터를 읽고 처리할 수 있게 한다.
리플렉션: 프로그램이 실행되는 동안에 자신의 구조를 검사하고 수정할 수 있는 능력
-> 사용자 시점에 사용자 어노테이션 정보를 읽고 처리하기 (메서드명, 값 등을 빼낼 수 있다.) - 동적 프록시 생성, AOP(Aspect-Oriented Programming) 구현 등 다양한 응용 프로그램에서 유용하다.
- 추가 공부 필요...
사용자 어노테이션을 만드는 방법
어노테이션은 메타데이터를 제공하는 인터페이스의 일종이기 때문에 메타 어노테이션도 추가로 작성해야 한다.
- 어노테이션 정의: @interface
- 메타 어노테이션
- @Retention: 어노테이션 유지 기간 설정 (RUNTIME, CLASS, SOURCE)
- @Target: 어노테이션 적용될 요소 지정 (TYPE, METHOD, FIELD...)
어노테이션 정의
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
// 애노테이션이 런타임까지 유지됨을 명시
@Retention(RetentionPolicy.RUNTIME)
// 애노테이션이 메서드에만 적용될 수 있음을 명시
@Target(ElementType.METHOD)
public @interface MyCustomAnnotation {
String value(); // 애노테이션의 요소 정의
}
어노테이션 사용
value: 어노테이션 속성으로, 해당 값을 지정하여 메타 데이터로 사용할 수 있다.
public class MyClass {
@MyCustomAnnotation(value = "Example value")
public void myMethod() {
System.out.println("My method is called");
}
}
리플렉션을 사용하여 어노테이션 처리
import java.lang.reflect.Method;
public class AnnotationProcessor {
public static void main(String[] args) {
try {
// MyClass의 클래스 객체를 가져옴
Class<?> clazz = MyClass.class;
// 클래스의 모든 메서드를 가져옴
Method[] methods = clazz.getDeclaredMethods();
// 각 메서드에 대해
for (Method method : methods) {
// MyCustomAnnotation이 있는지 확인
if (method.isAnnotationPresent(MyCustomAnnotation.class)) {
// MyCustomAnnotation 객체를 가져옴
MyCustomAnnotation annotation = method.getAnnotation(MyCustomAnnotation.class);
// 애노테이션의 값 출력
System.out.println("Method: " + method.getName() + ", Value: " + annotation.value());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
728x90
반응형
'Blog > TIL' 카테고리의 다른 글
[240528] 백문이 불여일타! (0) | 2024.05.28 |
---|---|
[240527] 코딩테스트 다다익선 (0) | 2024.05.27 |
[240524] 수학 지식을 넓히자 (0) | 2024.05.24 |
[240523] 배워도 배워도 끝이 없네 (0) | 2024.05.23 |
[240522] 드디어 JPA를 접하다 (0) | 2024.05.22 |
댓글