초반 계산기LV3를 만들때 결과값이 정수여도 실수로 출력되게 만들었다.
근데 보통 계산기의 경우 결과값이 정수인 경우 정수로, 실수인 경우 실수로 출력된다.
이 부분이 굉장히 불편하게 만들었다.
1. 정수, 실수 관계없이 결과값을 실수로 출력
getChkList에서 값을 doubleValue()를 이용하여 double타입으로 변환시켰기 때문에 int형으로 출력되지 않는다
기존 코드
// 가장 마지막에 저장된 값 출력
public T getList(){
return list.get(list.size()-1);
}
// 마지막에 입력된 값 보다 큰 값 출력
public List<T> getChkList(){
return list.stream().filter(i -> i.doubleValue() > getList().doubleValue()).toList();
}
// 결과값 호출
System.out.println("결과 : " + calculator.getList());
// 연산 값 보다 더 큰 저장 값
System.out.println("해당 연산 값 보다 더 큰 저장된 연산 결과: " + calculator.getChkList());
위의 코드의 경우
🤔 코드의 문제점
1. 결과값이 정수인 경우도 실수로 출력됨
2. 요구사항이 입력값과 저장값 비교였으나 가장 마지막 연산값으로 잘못작성됨
3. 값 비교 메서드 : getChkList(), 연산 결과 출력 : getList() 메서드로 메서드명이 모호함
4. 실수 + 실수로 저장된 경우 오차가 존재한다//ex double exam1 = 12.2; double exam2 = 2.8; System.out.println(exam1 + exam2) // 결과값 : 14.379999999999999
1차 수정 코드
💡 해결내용
ArithmeticCalculator.java
// 가장 최근 연산 값 출력
public T getLastValue(){
return list.get(list.size()-1);
// 메서드 명 수정
// 마지막에 입력된 값 보다 큰 값 출력
public List<T> getList(){
return list.stream().filter(i -> i.doubleValue() > getLastValue().doubleValue()).toList();
}
// 정수 여부 체크
public boolean isInteger(T result){
return result.doubleValue() == result.intValue();
}
CalculatorApp.java
// 결과값 호출
System.out.print("결과 : ");
// 결과값이 정수인 경우
if(calculator.isInteger(calculator.getLastValue())){
System.out.println(calculator.getLastValue().intValue());
// 결과값이 실수인 경우
}else{
System.out.println(calculator.getLastValue());
}
// 연산 값 보다 더 큰 저장 값 호출
if(calculator.getList().isEmpty()){
System.out.println("해당 연산 값 보다 더 큰 저장된 연산 결과는 존재하지 않습니다.");
}else {
System.out.println("해당 연산 값 보다 더 큰 저장된 연산 결과: " + calculator.getList());
}
🤔 코드의 문제점
1, 2번은 해결되었지만CalculatorApp.java에서 정수, 실수를 구분할 경우,
삭제, 리스트 출력시에도if(){System.out.println}을 반복하여 작성해야하기 때문에 복잡해 보였다. 그래서ArithmeticCalculator.java에서 출력만 하는 메서드를 따로 생성하여 문제를 해결했다.
2차 수정 코드
💡 해결내용
- 요구사항이 입력값과 저장값 비교였으나 가장 마지막 연산값으로 잘못작성됨
- 입력된 특정 값보다 큰 값 출력
- 실수 + 실수로 저장된 경우 오차가 존재한다
- roundValue(double) 메서드를 생성하여 소수점 2자리 이상은 반올림
- 리스트 출력시 실수로 출력됨
- new 출력 메서드 생성
ArithmeticCalculator.java
// 사칙 연산시 제네릭 타입의 경우 연산 불가
// double형으로 변환 뒤 연산
double result(T num1, T num2, OperatorType operator) {
double result = 0;
switch (operator) {
case PLUS:
result = num1.doubleValue() + num2.doubleValue();
break;
case MINUS:
result = num1.doubleValue() - num2.doubleValue();
break;
case MULTIPLY:
result = num1.doubleValue() * num2.doubleValue();
break;
case DIVIDE:
result = num1.doubleValue() / num2.doubleValue();
break;
}
// 소수점 변환
return roundValue(result);
}
// 소수점 2자리수 이상은 반올림한다
double roundValue(double result) {
return (double) Math.round(result * 100) / 100;
}
// 입력된 특정 값보다 큰 값 출력
public List<T> getList(T compareValue) {
return list.stream().filter(i -> i.doubleValue() > compareValue.doubleValue()).toList();
}
CalculatorApp.java
// 특정값 입력
System.out.print("특정 값을 입력하세요 : ");
double comPareValue = calculator.isNumber(sc.next());
if(calculator.getList(comPareValue).isEmpty()){
System.out.println("해당 연산 값 보다 더 큰 저장된 연산 결과는 존재하지 않습니다.");
}else {
System.out.println("해당 연산 값 보다 더 큰 저장된 연산 결과: " + calculator.getList(comPareValue));
}
3차 수정 코드
💡 해결내용
- 리스트 출력시 실수로 출력됨
- filter를 이용하여 list와 비교값 비교
- map을 이용하여
i.doubleValue == i.intValueintValue 반환,i.doubleValue != i.intValuedoubleValue 반환printList()리스트 출력- 출력 메서드 생성
- 결과값, 삭제값인 경우 isInteger()로 정수여부 체크 후 printValue() 출력
ArithmeticCalculator.java
// 가장 마지막에 저장된 값 출력
public void getLastValue() {
System.out.print("결과 : ");
isInteger(list.get(list.size() - 1));
}
// 삭제
public void delete() {
System.out.print("삭제된 값 : ");
isInteger(list.remove(0));
}
// 입력된 특정 값보다 큰 값 출력
public void getList(T compareValue) {
compareValue.doubleValue()).toList();
printList(
list.stream()
.filter(i -> i.doubleValue() > compareValue.doubleValue()) // 입력값과 비교
.map(i -> { // 정수 실수 구분
if(i.doubleValue() == i.intValue()){
return i.intValue();
}else {
return i.doubleValue() ;
}
})
.toList()
);
}
// 정수 여부 체크
public void isInteger(T result) {
boolean integerYn = result.doubleValue() == result.intValue();
//결과값 출력
printValue(integerYn, result);
}
// 정수여부 체크후 결과값 출력
public void printValue(boolean integerYn, T result){
if(integerYn){
System.out.println(result.intValue());;
}else {
System.out.println(result.doubleValue());
}
}
// 리스트 출력
// <? extends Number> intList, doubleList 등 다양한 리스트를 하나의 메서드에서 처리하고 싶을때 사용
public void printList(List<? extends Number> resultList){
if(resultList.isEmpty()){
System.out.println("해당 연산 값 보다 더 큰 저장된 연산 결과는 존재하지 않습니다.");
}
System.out.println("해당 연산 값 보다 더 큰 저장된 연산 결과: " + resultList);
}
CalculatorApp.java
// 결과 값 불러오기
calculator.getLastValue();
// 특정값 입력
System.out.print("특정 값을 입력하세요 : ");
double comPareValue = calculator.isNumber(sc.next());
calculator.getList(comPareValue);
// 삭제 여부 체크
System.out.println("저장된 결과값을 삭제하시겠습니까? (yes 입력시 가장 처음 저장된 결과값인 제거)");
String delYn = sc.next();
if (delYn.equals("yes")) {
calculator.delete();
}
처음 리스트에서 정수, 실수를 같이 출력하고자 할때 시간이 많이 걸렸다.
이유는 크게 3가지 정도가 있는데
1. filter안에 if문 적용 가능한지 몰랐다. filter는 비교만 가능한줄 알았다..
2. filter와 map을 같이 사용할 생각을 하지 못했다.
3. 처음 printList()의 리스트 타입을 Number로 생성했는데 오류가 나왔다.
오류 원인 : 제네릭 불공변성(List나 List 같은 하위 타입의 리스트를 List로 처리할 수 없는 특징이 존재)List<? extends Number>가 있는것을 알았다. 추후
이번에 수정을 하면서 스트림과 제네릭에 대한 이해가 +1 증가한것 같다.
이후 피드백을 받은 후 수정할 부분은 더 수정하고 해당 내용을 작성할 예정이다.