이번 포스팅은 문제 조건에 따른 문제 풀이 설명입니다.
Type 객체 사용하지 않음
여러 방면을 시도해본 끝에 Type 객체를 사용하지 않고 문제를 해결할 수 있었다. 생각해보면 너무 어렵게 접근한 것 같다.
Team 클래스 수정!
먼저 코드부터 살펴보자
package sample;
public class Team{
private String teamName;
private int games;
private int wins;
private int draws;
private int losses;
private double score;
// 기본 생성자
public Team() {
}
// 매개변수를 받는 생성자
public Team(String teamName, int games, int wins, int draws, int losses,double score) {
this.teamName = teamName;
this.games = games;
this.wins = wins;
this.draws = draws;
this.losses = losses;
this.score = 0.0;
}
// Getter 및 Setter 메서드
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public int getGames() {
return games;
}
public void setGames(int games) {
this.games = games;
}
public int getWins() {
return wins;
}
public void setWins(int wins) {
this.wins = wins;
}
public int getDraws() {
return draws;
}
public void setDraws(int draws) {
this.draws = draws;
}
public int getLosses() {
return losses;
}
public void setLosses(int losses) {
this.losses = losses;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
// toString 메서드 오버라이드
@Override
public String toString() {
return "2018K리그[" +
"팀명='" + teamName + '\'' +
", 경기수=" + games +
", 승=" + wins +
", 무승부=" + draws +
", 패=" + losses +
", 승점=" + score +
']';
}
}
팀명, 경기수, 승, 무, 패, 총점 을 클래스 변수로 선언하여 각 셀에 맞는 값을 저장할 수 있도록 하였음
이전 포스팅에서 엑셀 데이터를 불러올 때 코드를 보면 Cell의 타입별로 value값을 지정하였다. Cell로 올 수 있었던 타입에는 NUMERIC , STRING, BLANK, ERROR 가 있는데 엑셀에서 불러지는 데이터에는 NUMERIC 과 STRING 뿐이다. 따라서 불러온 값들을 하나의 자료형으로 통일 시키고 변환된 자료형을 재가공 하는게 어떨까 하는 생각을 하였다.
// 셀의 값을 문자열로 변환하는 메서드
private static String getCellValueAsString(XSSFCell cell) {
if (cell == null) {
return "";
}
CellType cellType = cell.getCellType();
switch (cellType) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf((int) cell.getNumericCellValue());
default:
return "";
}
}
위 메소드를 통해서 각 셀의 값을 모두 문자열로 반환한다. STRING 과 NUMERIC이 아닌 경우 ""를 반환하여 오류가 발생하지 않도록 처리하였다.
엑셀 데이터의 각 셀을 받아 값을 지정하는 코드는 아래와 같이 작성하였다.
// 팀 리스트 생성
List<Team> teams = new ArrayList<>();
// 각 행을 순회
for (int rowNo = 1; rowNo < rows; rowNo++) {
XSSFRow row = sheet.getRow(rowNo);
// 새로운 팀 객체 생성
Team team = new Team();
// 각 열을 순회
for (int colNo = 0; colNo < cols; colNo++) {
XSSFCell cell = row.getCell(colNo);
// 각 셀의 값을 문자열로 변환
String cellValue = getCellValueAsString(cell);
// 각 열에 따라 팀 객체에 값을 설정
// Type 객체를 사용하고 싶었지만 액셀 열의 값을 아는 경우 아래 코드가 더 깔끔하다고 생각됨.
switch (colNo) { // 팀 , 경기수 , 승 , 무 , 패 순서
case 0:
team.setTeamName(cellValue);
break;
case 1:
team.setGames(Integer.parseInt(cellValue));
break;
case 2:
team.setWins(Integer.parseInt(cellValue));
break;
case 3:
team.setDraws(Integer.parseInt(cellValue));
break;
case 4:
team.setLosses(Integer.parseInt(cellValue));
break;
default:
break;
}
}
// 팀 객체를 리스트에 추가
teams.add(team);
}
각 행과 열을 순회하면서 Team 클래스 setter에 맞도록 값을 지정한다. 첫 번째 행을 제외하고 순회를 돌렸다. 첫 행은 "팀명 , 경기수 , 승 , 무 , 패" 로 이루어져있기 때문에 Team 객체에 들어가면 안되는 값들이기 때문이다.
전체적인 코드는 아래와 같다.
package sample;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class readFile {
public static void main(String[] args) {
try {
// 엑셀 파일을 읽기 위한 FileInputStream 생성
FileInputStream file = new FileInputStream("2018K리그.xlsx");
// XSSFWorkbook 객체 생성하여 엑셀 파일 로드
XSSFWorkbook workbook = new XSSFWorkbook(file);
// 첫 번째 시트 가져오기
XSSFSheet sheet = workbook.getSheetAt(0);
// 행의 수
int rows = sheet.getPhysicalNumberOfRows();
// 열의 수
int cols = sheet.getRow(0).getPhysicalNumberOfCells();
// 팀 리스트 생성
List<Team> teams = new ArrayList<>();
// 각 행을 순회
for (int rowNo = 1; rowNo < rows; rowNo++) {
XSSFRow row = sheet.getRow(rowNo);
// 새로운 팀 객체 생성
Team team = new Team();
// 각 열을 순회
for (int colNo = 0; colNo < cols; colNo++) {
XSSFCell cell = row.getCell(colNo);
// 각 셀의 값을 문자열로 변환
String cellValue = getCellValueAsString(cell);
// 각 열에 따라 팀 객체에 값을 설정
// Type 객체를 사용하고 싶었지만 액셀 열의 값을 아는 경우 아래 코드가 더 깔끔하다고 생각됨.
switch (colNo) { // 팀 , 경기수 , 승 , 무 , 패 순서
case 0:
team.setTeamName(cellValue);
break;
case 1:
team.setGames(Integer.parseInt(cellValue));
break;
case 2:
team.setWins(Integer.parseInt(cellValue));
break;
case 3:
team.setDraws(Integer.parseInt(cellValue));
break;
case 4:
team.setLosses(Integer.parseInt(cellValue));
break;
default:
break;
}
}
// 팀 객체를 리스트에 추가
teams.add(team);
}
// 엑셀 파일 사용 후에는 닫아주어야 함
workbook.close();
file.close();
// 결과 출력
System.out.println("엑셀 파일 읽은 후 객체 저장 후 출력");
for (Team team : teams) {
System.out.println(team);
}
// 각 팀 승점 계산
int wins = 0, draws = 0, losses = 0;
for(int i = 0 ; i < teams.size() ; i++) {
wins += (teams.get(i).getWins() * 3);
draws += (teams.get(i).getDraws() + 1);
losses += (teams.get(i).getLosses());
int total = wins + draws + losses;
double score = (double)(total / teams.get(i).getGames());
teams.get(i).setScore(score);
}
System.out.println("승점 계산 후 출력");
// 계산 후 출력
for (Team team : teams) {
System.out.println(team);
}
System.out.println("내림차순 정렬 후 출력");
// 내림차순 정렬
// Comparable 내에 정의된 Collection 클래스 사용
// 참고 : https://www.daleseo.com/java-comparable-comparator/
Collections.sort(teams, (a, b) -> (int)b.getScore() - (int)a.getScore());
// 정렬 후 출력
for (Team team : teams) {
System.out.println(team);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 셀의 값을 문자열로 변환하는 메서드
private static String getCellValueAsString(XSSFCell cell) {
if (cell == null) {
return "";
}
CellType cellType = cell.getCellType();
switch (cellType) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf((int) cell.getNumericCellValue());
default:
return "";
}
}
}
글을 작성하다보니 Type 객체를 사용하여서도 충분히 구현할 수 있을 것이라 판단되었다.
위에서 언급했듯이 첫 번째 행을 제외하고 case를 0-4로 나누어 각 열에 맞는 값을 저장하였다.
그 뜻은 첫 행은 Type에 해당 된다는 뜻이므로 첫 행에 대한 값들을 Type 리스트로 저장하면 된다.
List<Type> types = new ArrayList<>();
XSSFRow rowZero = sheet.getRow(0);
for (int colNo = 0; colNo < cols; colNo++) {
Type type = new Type();
XSSFCell cell = rowZero.getCell(colNo);
// 각 셀의 값을 문자열로 변환
String cellValue = getCellValueAsString(cell);
type.setType(cellValue);
types.add(type);
}
System.out.println("타입 출력 ");
System.out.println(types);
Type 객체에 엑셀의 첫 행의 값을 저장하는 코드이다. Team 객체에 값을 저장하는 방식과 많이 유사하다.
타입 출력
[팀 , 경기수 , 승 , 무 , 패 ]
출력 결과 선언한 각 객체에 셀에 맞는 값이 잘 저장되었고 리스트로 표현할 수 있었다.
위 데이터를 Team 객체에 저장할 때 각 값에 맞는 데이터를 저장할 수 있도록 가공한다.
for (int rowNo = 1; rowNo < rows; rowNo++) {
XSSFRow row = sheet.getRow(rowNo);
// 새로운 팀 객체 생성
Team team = new Team();
// 각 열을 순회
for (int colNo = 0; colNo < cols; colNo++) {
XSSFCell cell = row.getCell(colNo);
// 각 셀의 값을 문자열로 변환
String cellValue = getCellValueAsString(cell);
// 각 열에 따라 팀 객체에 값을 설정
switch (types.get(colNo).getType()) { // 팀 , 경기수 , 승 , 무 , 패
case "팀":
team.setTeamName(cellValue);
break;
case "경기수":
team.setGames(Integer.parseInt(cellValue));
break;
case "승":
team.setWins(Integer.parseInt(cellValue));
break;
case "무":
team.setDraws(Integer.parseInt(cellValue));
break;
case "패":
team.setLosses(Integer.parseInt(cellValue));
break;
default:
break;
}
}
// 팀 객체를 리스트에 추가
teams.add(team);
}
수정 된 최종 소스 코드
▷readFile.java
package sample;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
public class readFile {
public static void main(String[] args) {
try {
// 엑셀 파일을 읽기 위한 FileInputStream 생성
FileInputStream file = new FileInputStream("2018K리그.xlsx");
// XSSFWorkbook 객체 생성하여 엑셀 파일 로드
XSSFWorkbook workbook = new XSSFWorkbook(file);
// 첫 번째 시트 가져오기
XSSFSheet sheet = workbook.getSheetAt(0);
// 행의 수
int rows = sheet.getPhysicalNumberOfRows();
// 열의 수
int cols = sheet.getRow(0).getPhysicalNumberOfCells();
// 팀 리스트 생성
List<Team> teams = new ArrayList<>();
List<Type> types = new ArrayList<>();
XSSFRow rowZero = sheet.getRow(0);
for (int colNo = 0; colNo < cols; colNo++) {
Type type = new Type();
XSSFCell cell = rowZero.getCell(colNo);
// 각 셀의 값을 문자열로 변환
String cellValue = getCellValueAsString(cell);
type.setType(cellValue);
types.add(type);
}
System.out.println("타입 출력 ");
System.out.println(types);
// 각 행을 순회
for (int rowNo = 1; rowNo < rows; rowNo++) {
XSSFRow row = sheet.getRow(rowNo);
// 새로운 팀 객체 생성
Team team = new Team();
// 각 열을 순회
for (int colNo = 0; colNo < cols; colNo++) {
XSSFCell cell = row.getCell(colNo);
// 각 셀의 값을 문자열로 변환
String cellValue = getCellValueAsString(cell);
// 각 열에 따라 팀 객체에 값을 설정
switch (types.get(colNo).getType()) { // 팀 , 경기수 , 승 , 무 , 패
case "팀":
team.setTeamName(cellValue);
break;
case "경기수":
team.setGames(Integer.parseInt(cellValue));
break;
case "승":
team.setWins(Integer.parseInt(cellValue));
break;
case "무":
team.setDraws(Integer.parseInt(cellValue));
break;
case "패":
team.setLosses(Integer.parseInt(cellValue));
break;
default:
break;
}
}
// 팀 객체를 리스트에 추가
teams.add(team);
}
// 엑셀 파일 사용 후에는 닫아주어야 함
workbook.close();
file.close();
// 결과 출력
System.out.println("엑셀 파일 읽은 후 객체 저장 후 출력");
for (Team team : teams) {
System.out.println(team);
}
// 각 팀 승점 계산
int wins = 0, draws = 0, losses = 0;
for(int i = 0 ; i < teams.size() ; i++) {
wins += (teams.get(i).getWins() * 3);
draws += (teams.get(i).getDraws() + 1);
losses += (teams.get(i).getLosses());
int total = wins + draws + losses;
double score = (double)(total / teams.get(i).getGames());
teams.get(i).setScore(score);
}
System.out.println("승점 계산 후 출력");
// 계산 후 출력
for (Team team : teams) {
System.out.println(team);
}
System.out.println("내림차순 정렬 후 출력");
// 내림차순 정렬
// Comparable 내에 정의된 Collection 클래스 사용
// 참고 : https://www.daleseo.com/java-comparable-comparator/
Collections.sort(teams, (a, b) -> (int)b.getScore() - (int)a.getScore());
// 정렬 후 출력
for (Team team : teams) {
System.out.println(team);
}
} catch (Exception e) {
e.printStackTrace();
}
}
// 셀의 값을 문자열로 변환하는 메서드
private static String getCellValueAsString(XSSFCell cell) {
if (cell == null) {
return "";
}
CellType cellType = cell.getCellType();
switch (cellType) {
case STRING:
return cell.getStringCellValue();
case NUMERIC:
return String.valueOf((int) cell.getNumericCellValue());
default:
return "";
}
}
}
▷Team.java
package sample;
public class Team{
private String teamName;
private int games;
private int wins;
private int draws;
private int losses;
private double score;
// 기본 생성자
public Team() {
}
// 매개변수를 받는 생성자
public Team(String teamName, int games, int wins, int draws, int losses,double score) {
this.teamName = teamName;
this.games = games;
this.wins = wins;
this.draws = draws;
this.losses = losses;
this.score = 0.0;
}
// Getter 및 Setter 메서드
public String getTeamName() {
return teamName;
}
public void setTeamName(String teamName) {
this.teamName = teamName;
}
public int getGames() {
return games;
}
public void setGames(int games) {
this.games = games;
}
public int getWins() {
return wins;
}
public void setWins(int wins) {
this.wins = wins;
}
public int getDraws() {
return draws;
}
public void setDraws(int draws) {
this.draws = draws;
}
public int getLosses() {
return losses;
}
public void setLosses(int losses) {
this.losses = losses;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
// toString 메서드 오버라이드
@Override
public String toString() {
return "2018K리그[" +
"팀명='" + teamName + '\'' +
", 경기수=" + games +
", 승=" + wins +
", 무승부=" + draws +
", 패=" + losses +
", 승점=" + score +
']';
}
}
▷Type.java
package sample;
public class Type {
private String type;
public Type() {
//
}
public Type(String type) {
this.type =type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
@Override
public String toString() {
return type + " ";
}
}
최종 실행 화면

https://github.com/MinWook6457/Insilicogen-Test
GitHub - MinWook6457/Insilicogen-Test
Contribute to MinWook6457/Insilicogen-Test development by creating an account on GitHub.
github.com
'인실리코젠' 카테고리의 다른 글
[인실리코젠] WebCrawling - 1 (0) | 2024.01.16 |
---|---|
[인실리코젠] Maven에 대하여 (0) | 2024.01.12 |
[인실리코젠] Programmers Lv2.JadenCase 문자열 만들기 리뷰 답변 및 BPM(Business Process Management) 프로세스 모델링 (1) | 2024.01.11 |
[인실리코젠] Apache POI 라이브러리를 이용한 Exel 데이터 읽기 (2) | 2024.01.11 |
[인실리코젠] 배열 vs 리스트 (1) | 2024.01.11 |