🟢 FileReader의 .read()는 리턴 타입이 int형
최신코드
BufferedReader br = Files.newBufferedReader(
Paths.get(filename), StandardCharsets.UTF_8)
void readByChar(String filename) ➡ 이렇게 적어보는 것
(메소드 이름은 어떤 기능을 하는지 알 수 있도록 지어야 함)
MDIS 사이트 ➡ 자료이용 ➡ 다운로드 서비스
🟢 미니 프로젝트에서 사용할 데이터 다운로드
인구 ➡ 국내인구이동통계 ➡ 인구관련연간자료(제공) ➡ 2021년 ➡ CSV파일로 저장
2021 서울에서 가장 많이 이사간 지역은 어디인지 알아내기
파일 생성, 쓰기
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
public class CreateFile {
// 파일 하나 생성
public void createAFile(String filename) {
File file = new File(filename);
try {
file.createNewFile();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// List<String>을 지정한 파일에 write
public void write(List<String> strs, String filename) {
File file = new File(filename);
try{
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
for (String str : strs) {
writer.write(str);
}
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
🟢 createAFile : 파일 이름을 받아서 루트에 생성
🟢 write : String List를 받아 파일 이름에 작성
전입, 전출 변수를 갖는 클래스
public class PopulationMove {
private int fromSido;
private int toSido;
// 생성자 추가
public PopulationMove(int fromSido, int toSido) {
this.fromSido = fromSido;
this.toSido = toSido;
}
// 생성자 추가(오버로딩)
public PopulationMove(String fromSido, String toSido) {
this.fromSido = Integer.parseInt(fromSido);
this.toSido = Integer.parseInt(toSido);
}
// getter 추가
public int getFromSido() {
return fromSido;
}
public int getToSido() {
return toSido;
}
}
🟢 생성자를 추가하여 전입, 전출을 입력 받았을 때 변수에 초기화
🔴 오버로딩 : String형으로 매개 변수가 들어오면, Int형으로 변환하여 초기화
🟢 getter : 직접적으로 값을 불러오지 못하게 private을 사용했으므로, 값을 불러올 수 있는 함수 따로 생성
주요 함수를 담고 있는 클래스
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PopulationStatistics {
public List<PopulationMove> readByLine(String filename, int from, int to) throws IOException {
// String을 PopulationMove로 parsing하여 pml에 add합니다.
List<PopulationMove> pml = new ArrayList<>();
BufferedReader bufferedReader = new BufferedReader(
new FileReader(filename)
);
String str;
while((str = bufferedReader.readLine()) != null){
// System.out.println(str);
PopulationMove pm = parse(str, from, to);
pml.add(pm);
}
bufferedReader.close();
return pml;
}
public PopulationMove parse(String data, int from, int to){
String[] dataSplit = data.split(",");
return new PopulationMove(dataSplit[from], dataSplit[to]); // 전입 : To, 전출 : From
}
public String fromToString(PopulationMove populationMove){
return populationMove.getFromSido() + "," + populationMove.getToSido() + "\n";
}
public Map<String, Integer> HowManyFromSido(List<PopulationMove> newPml){
Map<String, Integer> modeSeoulToSido = new HashMap<>();
int cnt;
String key;
for (PopulationMove s : newPml) {
int toSido = s.getToSido();
key = s.getFromSido() + "," + toSido;
cnt = modeSeoulToSido.containsKey(key) ? modeSeoulToSido.get(key) : 0;
modeSeoulToSido.put(key, cnt + 1);
}
return modeSeoulToSido;
}
// 오버로딩
public Map<String, Integer> HowManyFromSido(List<PopulationMove> newPml, int from){
Map<String, Integer> modeSeoulToSido = new HashMap<>();
int cnt;
String key;
for (PopulationMove s : newPml) {
if (s.getFromSido() == from){
int toSido = s.getToSido();
key = s.getFromSido() + "," + toSido;
cnt = modeSeoulToSido.containsKey(key) ? modeSeoulToSido.get(key) : 0;
modeSeoulToSido.put(key, cnt + 1);
}
}
return modeSeoulToSido;
}
// 오버로딩
public Map<String, Integer> HowManyFromSido(List<PopulationMove> newPml, int from, int to){
Map<String, Integer> modeSeoulToSido = new HashMap<>();
int cnt;
String key;
for (PopulationMove s : newPml) {
if (s.getFromSido() == from){
int toSido = s.getToSido();
if (toSido == to) {
key = s.getFromSido() + "," + toSido;
cnt = modeSeoulToSido.containsKey(key) ? modeSeoulToSido.get(key) : 0;
modeSeoulToSido.put(key, cnt + 1);
}
}
}
return modeSeoulToSido;
}
public String modeToSido(Map<String, Integer> modeSeoulToSido){
int maxValue = 0;
String maxKey = "";
for (String key : modeSeoulToSido.keySet()) {
if(modeSeoulToSido.get(key) > maxValue){
maxValue = modeSeoulToSido.get(key);
maxKey = key;
}
}
return maxKey;
}
public Map<String, Integer> heatmapIdxMap() {
Map<String, Integer> map = new HashMap<>();
map.put("11", 0);
map.put("26", 1);
map.put("27", 2);
map.put("28", 3);
map.put("29", 4);
map.put("30", 5);
map.put("31", 6);
map.put("36", 7);
map.put("41", 8);
map.put("42", 9);
map.put("43", 10);
map.put("44", 11);
map.put("45", 12);
map.put("46", 13);
map.put("47", 14);
map.put("48", 15);
map.put("50", 16);
return map;
}
}
🟢 readByLine : 파일을 읽어서 parse 메소드를 거쳐 PopulationMove List형태로 리턴
🟢 parse : 데이터를 split한 후, from, to 변수를 인덱스 값으로 받아 그에 맞는 splited 데이터를 PopulationMove 형태로 리턴
🟢 fromToString : PopulationMove의 fromSido, toSido 값을 묶어서 String 형태로 리턴
🟢 HowManyFromSido : 원하는대로 from, to값을 넣을 수 있도록 오버로딩
🔹 리스트만 : 전체 전입, 전출 경우의 수별 개수
🔹 리스트, from : 전출에 해당하는 전체 전입 경우의 수별 개수
🔹 리스트, from, to : 해당 전입, 전출의 개수
🟢 modeToSido : 경우의 수 중 최빈값 리턴
🟢 heatmapIdxMap : 히트맵을 그릴 수 있도록 맵핑할 수 있는 Map 리턴
메소드를 사용하는 Main클래스
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class PopulationMain {
public static void main(String[] args) throws IOException {
PopulationStatistics populationStatistics = new PopulationStatistics();
// // 파일 생성
// CreateFile createFile = new CreateFile();
// createFile.createAFile("from_to.txt");
//
// // 파일 쓰기(from, to만 남기기)
// String address = "D:\\고관운 자료\\멋쟁이사자처럼\\수업 자료\\221007 실습 자료\\2021_인구관련연간자료_20221006_98568.csv";
// List<PopulationMove> pml = populationStatistics.readByLine(address, 6, 0); // from : 전입 인덱스, to : 전출 인덱스
//
// List<String> strings = new ArrayList<>();
// for(PopulationMove pm : pml) {
// String fromTo = populationStatistics.fromToString(pm);
// strings.add(fromTo);
// }
//
// createFile.write(strings, "from_to.txt");
// 새로 만든 파일로 작업
String newAddress = "./from_to.txt";
List<PopulationMove> newPml = populationStatistics.readByLine(newAddress, 0, 1); // from : 전입 인덱스, to : 전출 인덱스
// from에서 to로 간 시도의 개수 출력, 가장 많이 간 시도 출력(전체출력)
Map<String, Integer> fromToList = populationStatistics.HowManyFromSido(newPml);
System.out.println(fromToList);
String modeToSido = populationStatistics.modeToSido(fromToList);
System.out.println(modeToSido);
// // from에서 to로 간 시도의 개수 출력, 가장 많이 간 시도 출력(from만 입력)
// Map<String, Integer> fromToListInputFrom = populationStatistics.HowManyFromSido(newPml, 11);
// System.out.println(fromToListInputFrom);
//
// // from에서 to로 간 시도의 개수 출력, 가장 많이 간 시도 출력(from, to 입력) 오버로딩 이용
// Map<String, Integer> fromToListInputFromTo = populationStatistics.HowManyFromSido(newPml, 44, 31);
// System.out.println(fromToListInputFromTo);
// 결과를 파일로 저장(전체 경우의 수)
CreateFile createFile = new CreateFile();
String targetFilename = "each_sido_cnt.txt";
createFile.createAFile(targetFilename);
List<String> cntResult = new ArrayList<>();
for (String key : fromToList.keySet()){
String s = String.format("from:%s to value:%d\n", key, fromToList.get(key));
cntResult.add(s);
}
createFile.write(cntResult, targetFilename);
// 결과를 히트맵 형식으로
String targetFilenameForHeatmap = "each_sido_for_heatmap.txt";
createFile.createAFile(targetFilenameForHeatmap);
Map<String, Integer> heatMapIdxMap = populationStatistics.heatmapIdxMap();
List<String> cntResultForHeatmap = new ArrayList<>();
for (String key : fromToList.keySet()){
String[] strForHeatmap = key.split(",");
String s = String.format("[%s, %s, %s],\n", heatMapIdxMap.get(strForHeatmap[0]), heatMapIdxMap.get(strForHeatmap[1]), fromToList.get(key));
cntResultForHeatmap.add(s);
}
createFile.write(cntResultForHeatmap, targetFilenameForHeatmap);
}
}
🟢 필요한 데이터만 추출하기 위해 from_to.txt 생성 후 파일 쓰기
🟢 전체의 경우의 수를 볼 수 있는 each_sido_cnt.txt 생성
🟢 히트맵을 그릴 수 있도록 each_sido_for_heatmap.txt 생성 후 [%s, %s, %s],\n의 형태로 저장
2021년 전입, 전출 그래프
🟢 경기도 ➡ 경기도가 가장 많음 (1,164,252)
🟢 서울 ➡ 서울이 두번째로 많음 (809,201)