연속으로 계산할 경우 이전 연산의 계산결과와 더해져야 하는데, 이전에 입력했던 값과 연산을 수행하는 버그가 있다.
문제가 될만한 부분은 .reduce 메소드의 람다식 부분이다.
reduce의 사용법을 내가 잘못 알고 사용했다. 1, a,b - > b로 사용하면 다음 첫번째 요소에 이전 연산 결과가 들어가는 줄 알았는데,
이전 연산에서의 b값이 첫번째 요소에 들어가는 것 같다.
구글링을 여러 번 했는데 이해도 잘 안되고 정확한 정보를 알 수 없어서 공식 문서로 찾아갔다.
초기값은 연산에서 중립적인 역할을 해야 하고, 모든 t에 대해 accumulator.apply(identity, t)가 t와 같아야 한다.
두 개의 파라미터(초기값, 두 개의 요소를 결합하는 람다식)으로 구성되어 있는데, 덧셈에서는 초기값이 0이어야 하고, 곱셈에서는 초기값이 1이어야 한다. 지금 내 계산기의 경우에는 같은 연산자로 계속 연산하는 것이 아닌, 총 4개 중 사용자가 입력한 연산자로 결과를 내야 하기에 reduce는 사용을 못할 것 같다. reduce가 연속적인 계산에 좋다길래 제대로 된 사용법도 읽지 않고 사용한 내 잘못이다ㅠㅠ.
그렇다면 어떤 방법이 있을까......약간 어지럽지만 고민을 좀 해봐야겠다.
인고의 구글링 시간 on
나에게 가장 필요했던 것은, "함수가 실행 될 때 마다 업데이트되는 결과값을 저장할 수 있는" 메서드였다.
계산이야 뭐 이미 만들어놓은 enum도 있고 stream forEach사용해서 처리 가능하지만, 이전값을 연속적으로 저장하는 변수가 필요했다. 그렇기에 스레드, 동시성 등의 키워드가 계속 눈에 띄었고,
Atomic Type
을 공부하게 되었다.
멀티 스레딩 프로그래밍에서는 동시성 문제, 즉 동기화를 기본적으로 고려해야 한다. 자바는 이런 문제를 해결하기 위해 다양한 방법을 제공하는데, 대표적으로 js에서 많이 봐서 익숙한 synchronyzed와, Atomic Type, volatile이 있다고 한다.
atomic은 원자적이라는 뜻인데, "중간에 끼어들 수 없이 단일 단위로 실행된다"는 의미이다. AtomicReference 변수 타입으로, 멀티스레드 환경에서 원자적으로 업데이트할 수 있는 메서드를 제공한다. 여러 스레드가 동시에 접근해도, AtomicReference의 값을 읽고 쓰는 과정에서 서로 간섭하지 않는 것이다.
AtomicReference는 내 계산기와 같은 단일 스레드 환경에서도 유용하게 사용할 수 있다. 단일 스레드 환경에서는 동기화가 필요없지만 일반적으로 stream을 사용하는 람다식은 외부 변수를 직접 수정할 수 없기 때문에 값을 누적하거나 수정하려면 AtomicReference로 이를 해결한다.
AtomicReference<Double> result = new AtomicReference<>(numbers.get(0));
IntStream.range(0, operators.size()).forEach(i -> {
String operator = operators.get(i);
Operation operation = Operation.fromSymbol(operator);
double a = result.get();
double b = numbers.get(i + 1);
result.set(operation.apply(a, b));
});
AtomicReference<Double> 변수를 선언해서, 초기값으로는 numbers리스트의 첫번째 숫자를 가져오도록 했다. 첫 계산에서는 누적된 결과값이 없기 때문에 첫번째 숫자를 가져와야 한다.
double a = result.get(); 을 통해, result에 저장된 값을 계산식의 첫 번째 숫자에 할당하고,
다시 result.set()으로 이전 계산의 결과값이 atomicreference 타입으로 저장되도록 했다.
이제 이전 계산결과가 잘 저장된다!
'개인 프로젝트 > calculator-project' 카테고리의 다른 글
Parser.java의 중요성을 깨달음 <4> (0) | 2024.11.15 |
---|---|
Stream 공부하다 뇌에서 Steam 나옴😇 <2> (0) | 2024.11.14 |
계산기에 새로 배운 기술을 도입한다면? <1> (0) | 2024.11.14 |