/////
Search

221012

작성자
김지영
김희정
이현주
날짜
2022/10/12
학습 내용
최댓값&최소값 알고리즘, DB 실습, 템플릿콜백
텍스트

최댓값&최소값 함수에 다형성 적용 - 김희정

부등호 조건만 다른 최댓값과 최소값 함수를 동시에 어떻게 구현할까?

문제인식

현재 배열의 최댓값을 구하는 getMax함수 구현
배열의 최소값을 구하는 함수도 필요
함수를 더 추가하지말고 최댓값과 동시에 구현할 수 없을까? >> 다형성 이용
public int getMax(int[] arr){ //loop 구성 int maxValue = arr[0]; for(int i = 0; i < arr.length; i++){ if(arr[i] > maxValue){ maxValue = arr[i]; } } return maxValue; }
Java
복사

과정

1.
if문의 조건문을 boolean변수로 따로 뺀다.
최솟값과 최댓값의 차이 : 조건문 부등호 방향(><)
code
2.
Compare interface 구현
doSomething(int valueA, int valueB) : 정수 두개를 받아 조건에 맞는지 아닌지 리턴
해당 인터페이스 구현체를 통해 조건 설정
code
3.
callback 이용 : doSomething 함수로 조건문 boolean을 반환 받음
code
4.
max(), min() 메소드에서 각 로직에 맞게 doSomething을 구현
code
전체코드

템플릿/콜백 패턴

한가지만 바뀌고 중복일 때 주로 사용
템플릿 : 어떤 목적을 위해 미리 만들어둔 모양이 있는 틀
콜백 : 호출(call)한 메소드로 다시 가는 것(back)

콜백과정

max() → getMaxOrMin → max()
1.
main에 `maxAndMin.max(arr) 실행, max()호출
code
2.
max() 실행 , getMaxOrMin() 호출
code
3.
getMaxOrMin() 실행, 실행 중 compare.doSomething 을 위해 다시 max()로
code
4.
max()에서 Compare를 구현한 doSomething 메소드 로직 실행>> return valueA > valueB
code
5.
다시 getMaxOrMin() 계속 진행
cod
intell J 단축키
Alt + 1 : 편집기 → projcet explorer 이동
Alt + Insert : package, class 등 새로운 파일 만들기
esc : projcet explorer → 편집기 이동
Alt + J : 같은 문자를 동시에 드래그.
home : 각 드래그 행의 제일 처음으로
end : 각 드래그 행의 제일 마지막으로
Ctrl + Alt + L : 코드 정렬
다형성 적용 이전, 읽어온 string을 그대로 저장한 LineReader
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class LineReader { List<String> readLine(String filename) throws IOException { List<String> result = new ArrayList<>(); BufferedReader br = new BufferedReader(new FileReader(filename)); String str; while((str= br.readLine())!= null){ // filename을 한 줄씩 읽어옵니다 result.add(str); } return result; } public static void main(String[] args) throws IOException { LineReader lr = new LineReader(); String targetFile = "C:\\Users\\wjdtk\\Downloads\\서울시 병의원 위치 정보.csv"; List<String> line = lr.readLine(targetFile); //한 줄씩 읽어서 line에 저장 System.out.println(line.size()); } }
Java
복사

코드 리팩토링한 이유

파일을 읽어오는 클래스인 LineReader는 다양한 곳에서 사용될 수 있다.
LineReader의 readLines메소드는 어떤 파일을 파싱하느냐에 따라 반환하는 리스트 타입이 달라질 수 있다.
다양한 종류의 파일을 파싱할때마다 readLines를 반복적으로 작성하는 것은 비효율적이다.
interface를 통해서 파일의 종류에 따라 다양한 List 타입을 반환할 수 있도록 코드를 리팩토링한다.
OPP 구현 순서
다형성의 이해

Parser 인터페이스

public interface Parser<T> { // parsing할 파일의 자료형에 따라 Object를 다양하게 받기 위해 제네릭 <T> T parse(String str); }
Java
복사

interface 구현체 HospitalParser 생성

import Parser.Parser; import domain.Hospital; public class HospitalParser implements Parser<Hospital> { // Interface Parser의 구현체 private String getSubdivision(String name) { String[] subDibisions = {"소아과", "피부과", "성형외과", "정형외과", "산부인과", "관절", "안과", "가정의학과", "비뇨기과", "치과", "내과", "외과", "한의원"}; for(String subDivision : subDibisions){ if(name.contains(subDivision)) { return subDivision; } } return ""; } public Hospital parse(String str) { str= str.replaceAll("\"", ""); String[] splitted = str.split(","); String name = splitted[10]; String subDivision = getSubdivision(name); return new Hospital(splitted[0],splitted[1],splitted[2],splitted[6],name, subDivision); } }
Java
복사

Hospital 클래스

package domain; public class Hospital { private String id; private String address; private String category; private String district; private String name; private Integer emergency_room; // emergencyroom은 숫자라서 Integer입니다 private String subDivision; public Hospital(String id, String address, String category, String emergency_room, String name, String subDivision) { this.id = id; this.address = address; this.name = name; this.emergency_room = Integer.parseInt(emergency_room); this.subDivision = subDivision; setDistrict(address); } public void setDistrict(String str) { String[] splitted = str.split(" "); this.district = splitted[0]+" "+splitted[1]; // 서울시 어쩌구~어쩌구 ~ -> "서울시 00구"로 파싱 } public String getId() { return id; } public String getAddress() { return address; } public String getCategory() { return category; } public String getDistrict() { return district; } public String getName() { return name; } public Integer getEmergency_room() { return emergency_room; } public String getSubDivision() { return subDivision; } }
Java
복사

LineReader 클래스 수정

parser을 LineReader생성자에서 초기화
import Parser.Parser; // import Parser import domain.Hospital; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; public class LineReader<T> { Parser<T> parser; private boolean isRemoveColumName = true; public LineReader(Parser<T> parser, boolean isRemoveColumName) { this.parser = parser; this.isRemoveColumName = isRemoveColumName; } List<T> readLine(String filename) throws IOException { List<T> result = new ArrayList<>(); BufferedReader br = new BufferedReader(new FileReader(filename)); String str; if(isRemoveColumName){ br.readLine(); } while((str= br.readLine())!= null){ // parse()가 호출되어 실행되면, return할 때 hospital 객체를 생성하고 종료합니다. // 19xxxx 개의 hospital을 저장하기 위해 main에서 List를 작성할 것이다. result.add(parser.parse(str)); } return result; } }
Java
복사

Main 클래스

import domain.Hospital; import java.io.IOException; import java.util.List; public class Main { public static void main(String[] args) throws IOException { String targetFile = "C:\\Users\\wjdtk\\Downloads\\서울시 병의원 위치 정보.csv"; LineReader<Hospital> hospitalLineReader = new LineReader<Hospital>(new HospitalParser(), true); List<Hospital> hospitals = hospitalLineReader.readLine(targetFile); for(Hospital hospital : hospitals){ System.out.printf("%s,%s,%s,%s,%d,%s,%s\n", hospital.getId(),hospital.getAddress(),hospital.getDistrict(),hospital.getCategory(), hospital.getEmergency_room(),hospital.getName(), hospital.getSubDivision()); } } }
Java
복사

최댓값 찾기 알고리즘과 다형성 _ 이현주

코드업 4596: 최대값 2

코드업 2081: 최대값 1

공공 데이터 분석 (mySQL, java)

활용 데이터: 서울시 병의원 위치 정보.csv

(참고) IntelliJ Default Keymap list (macOS, Windows)