SMALL

java.nio.file.Files 클래스는 Java 1.7 버전부터 제공되었다.

Files 클래스는 static 메서드로만 이루어져 있다.

제공되는 대부분의 메서드는 file, directory를 다룬다.

 

 

create

 

Files.createFile(file)

파일을 생성할 때 사용

만약, parent directory가 존재하진 않는다면 Exception이 발생한다

 

Files.createDirectory(path)

디렉토리를 생성할 때 사용

만약, parent directory가 존재하진 않는다면 Exception이 발생한다

 

Files.createDirectories(path)

디렉토리를 생성할 때 사용

위의 메서드들과 다르게 parent directory가 존재하지 않아도 동작한다

    public static void main(String[] args) {

        Path file = Paths.get("test.txt");
        Path path = Paths.get("dir");
        Path path2 = Paths.get("dir2/test");

        try {
            System.out.println(Files.createFile(file));
            Files.writeString(file, "ttttt");
            Files.delete(file);

            Path dirTest = Files.createDirectory(path);
            System.out.println(dirTest);
            System.out.println(Files.exists(dirTest));
            Files.delete(dirTest);

            Path dirTest2 = Files.createDirectories(path2);
            System.out.println(dirTest2);

            System.out.println(dirTest);
            System.out.println(Files.exists(dirTest));

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

 

walk

1.8 이상에서만 사용 가능

path 경로 및 하위 파일 및 디렉토리 탐색하여 Stream으로 반환

    public static void main(String[] args) {
    
        Path walkPath = Paths.get("src");
        try {
            Stream<Path> stream = Files.walk(walkPath);
            stream.filter(Files::isRegularFile).forEach(p -> System.out.println(p));
            
            Files.walk(walkPath).filter(Files::isDirectory)
                .forEach(p -> System.out.println(p));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

Path 경로를 탐색하며 해당 경로에 존재하는 모든 Path를 반환하여

해당 Stream을 기반으로 Directory, File 등등 특정 정보를 추출할 수 있다

 

walkFileTree

파일 시스템 트리를 재귀적으로 순회하는 기능

FileVisitor 객체를 인자로 받는다

 

public class SimpleFileVisitor implements FileVisitor<Path> {

    @Override
    public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
        System.out.println("preVisit - " + dir.toString());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
        System.out.println("visit - " + file.toString());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult visitFileFailed(Path file, IOException exc) throws IOException {
        System.out.println("visitFail - " + file.toString());
        return FileVisitResult.CONTINUE;
    }

    @Override
    public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
        System.out.println("postVisit - " + dir.toString());
        return FileVisitResult.CONTINUE;
    }

}

 

FileVisitor 메서드의 return 값으로 FileVisitResult를 반환하는데

FileVisitResult Enum의 각각의 값들을 알아보자.

 

    public static void main(String[] args) {
    
        Path walkPath = Paths.get("src");
        try {
            System.out.println("-- walk file tree --");
            Files.walkFileTree(walkPath, new SimpleFileVisitor());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
LIST
SMALL

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

You may assume that each input would have exactly one solution, and you may not use the same element twice.

You can return the answer in any order.

 

정수 배열 nums와 정수 target이 주어진다.

배열의 두 수를 더해서 target이 되는 숫자를 반환하라.

주어진 배열에 정답이 되는 쌍은 정확히 하나이고, 같은 숫자들을 중복해서 사용할 수 없다.

 

Example 1:

Input: nums = [2,7,11,15], target = 9
Output: [0,1]
Explanation: Because nums[0] + nums[1] == 9, we return [0, 1].

배열에 관련된 여러 문제를 풀면서 느꼈는데, 배열 문제를 푸는 시간 복잡도로는 크게 분류가 나누어진다.

O(n), O(nlogn), O(n^2)

각각의 방식들에 맞는 솔루션이 어떤 것이 있는지 고민하며, 가장 최적화된 방법으로 문제를 풀어나가 보자.

우선 가장 단순하게 배열을 2중으로 순회하며 값을 비교할 수 있다.

O(n^2)

    public int[] twoSum(int[] nums, int target) {

        for (int i = 0; i < nums.length - 1; i++) {
            int num1 = nums[i];
            for (int j = i + 1; j < nums.length; j++) {

                if (target - num1 == nums[j]) {
                    return new int[] { i, j };
                }
            }
        }

        return null;
    }

 

또한, HashMap을 이용해서 배열은 한 번만 순회하는 방법도 존재한다. 

O(n)

    // time complexity - o(n)
    public int[] twoSum(int[] nums, int target) {

        Map<Integer, Integer> map = new HashMap<>();
        int t = 0;
        for (int i = 0; i < nums.length; i++) {
            t = target - nums[i];
            if (map.containsKey(t)) {
                return new int[] { i, map.get(t) };
            } else {
                map.put(nums[i], i);
            }
        }
        return null;
    }
LIST
SMALL

정의

RestTemplate은 Spring에서 제공하는 Http Client

REST 서비스를 호출하는 복잡한 과정을 단순한 방식으로 만들어 주는 클래스

( 기계적이고 반복적인 코드를 깔끔하게 만들 수 있도록 도와준다)

 

Http Client 종류 

RestTemplate 뿐만 아니고 다른 종류의 Http Client가 존재하는데 각각의 특징을 간단하게 알아보자.

  • RestTemplate
    • Spring 3.0에서부터 지원
    • REST API 호출 후, 응답을 받을 때까지 기다리는 동기 방식
  • AsyncRestTemplate
    • Spring 4.0에서부터 지원
    • 비동기 RestTemplate
  • WebClient
    • Spring 5.0에서부터 지원
    • 논 블록, 리엑티브 웹 클라이언트
    • 동기, 비동식 방식 모두 지원 

 

사용법(예시)

 

Bean 등록

@RequiredArgsConstructor
@Configuration
public class WebConfig {
	
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
        return restTemplateBuilder
                .requestFactory(() -> 
                    new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory())
                )
                .setConnectTimeout(Duration.ofMillis(5000)) // connection-timeout
                .setReadTimeout(Duration.ofMillis(5000)) // read-timeout
                .build();
    }
}

 

예시

@RequiredArgsConstructor
@Service
public class RestTestService {

    private final RestTemplate template;
    
    private String getLoggerFromActuator(String url) {
    
        ResponseEntity<String> response = 
            template.getForEntity(url + "/actuator/loggers", String.class);
        
        HttpStatus statusCode = response.getStatusCode();   //상태코드확인
        HttpHeaders headers = response.getHeaders();    //헤더정보확인
        String body = response.getBody();   //바디정보확인
        
        return body;
    }
}

( 각 메서드 별 자세한 예시 : https://advenoh.tistory.com/46 )

RestTemplate 메서드

출처 :&nbsp;https://advenoh.tistory.com/46

Connection Pool 사용

기본적으로 제공되는 RestTemplate는 Connection Pool을 사용하지 않는다.

원한다면 추가적인 설정이 필요하다.

Connection Pool이 존재하지 않는다면, 

RestTemplate을 호출할 때마다, TCP 소켓을 열고, 3-way hand shaking이 발생하여 성능에 문제가 될 수 있고, 

요청량이 많아지게 되면 connection을 재활용할 수 없기 때문에 응답이 지연될 수 있다.

@RequiredArgsConstructor
@Configuration
public class WebConfig {
	
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
    
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); 
        factory.setReadTimeout(5000); // 읽기시간초과, ms 
        factory.setConnectTimeout(3000); // 연결시간초과, ms 
        HttpClient httpClient = HttpClientBuilder.create()
                .setMaxConnTotal(100) // connection pool 적용 
                .setMaxConnPerRoute(5) 
                .build(); 
        factory.setHttpClient(httpClient); // HttpClient 세팅 
        
        return new RestTemplate(factory);
    }
}

 

추가 참고 사항

RestTemplate 내부에서는 HttpURLConnection, HttpClient 등을 사용하는데,

해당 클래스들의 대한 내용( https://amagrammer91.tistory.com/65 )

LIST
SMALL

Given an array of integers nums containing n + 1 integers where each integer is in the range [1, n] inclusive.

There is only one repeated number in nums, return this repeated number.

You must solve the problem without modifying the array nums and uses only constant extra space.

 

Example 1:

Input: nums = [1,3,4,2,2]
Output: 2

n+1개 integer를 가지고 있는 nums 배열이 주어진다.

각각의 원소의 범위는 [1, n]이다.

오직 하나의 숫자만 반복이 되는데, 그 숫자를 반환하라.

주어진 배열을 수정하지 말고, 추가적인 공간도 상수 개만 사용해서 문제를 풀어라.


해당 문제를 풀기 위해서는 Set, Map과 같은 추가적인 공간을 사용할 수도 있고,

Sorting을 통해서 인접한 원소들을 비교할 수도 있다. 

다만, 문제의 조건이 추가적인 공간이 상수 개이고, 정렬도 없다는 조건이므로 이러한 방식 이외의 것이 필요하다.

이 문제에서 중요하게 볼 부분은 배열에 주어진 값이 배열 인덱스 내의 값이라는 것이다.

즉, 배열의 값을 통해서 다른 배열로 포인팅이 가능해지고 해당 과정을 반복하며 2번 방문한 곳을 찾을 수 있다.

두 번 반복했는지 확인하기 위해서는 추가적인 공간을 사용하지 않고 주어진 배열을 활용할 수 있다.

방문한 배열의 값에 마이너스 표시 , 방문했을 때 배열의 값이 음수이면 중복 방문

 

    public int findDuplicate(int[] nums) {

        for (int i = 0; i < nums.length; i++) {
            int tmp = Math.abs(nums[i]);

            if (nums[tmp] < 0) {
                return tmp;
            } else {
                nums[tmp] = -nums[tmp];
            }
        }

        return -1;
    }

 

LIST

+ Recent posts