2013-10-10 1 views
1

미리 설정된 천장에 도달 할 때마다 롤오버 할 카운터를 만들고이 천장에 도달하면 다시 플로어 값으로 다시 설정합니다. 클래스를 구현하고 잘 작동합니다. 그러나 제 솔루션에가는 도중에 Java Generics를 실험하고 싶었습니다. 나는 카운터를 확장하여 정수를 사용하지 않고 대신 모든 유형의 숫자를 사용할 수 있도록 카운터를 확장하려고합니다. 어쨌든 카운터는 대개 정수 사용만을 요구하지만, 수행 할 수 있는지 알고 싶었습니다.숫자의 하위 클래스 Generics를 사용하여 롤오버 카운터 만들기

코드가 아래와 비슷할 것이라고 생각했습니다. 그러나 java.lang.Number에는 값을 가져 오거나 설정하는 "일반적인"방법이 없습니다. 이 기능을 사용하려면 자체 번호 클래스를 만들어야합니까? 또한이 작업을 수행하면 부동 소수점 값에 대한 오류 임계 값을 갖도록 내 동등 검사를 변경해야한다는 것을 알고 있습니다. 이는 내 int 카운터의 수정 된 버전입니다. 제네릭.

편집 : 나는 숫자를 뱉어하려고 할 때, 난 그냥 증분 값으로 내 현재의 수를 곱 있도록 내가 정수 카운터를 저장하고 증분 값을 유지 매핑 접근 방식을 제안하고있어 . 그러나 매번 동일한 금액만큼 증분하고 싶지 않기 때문에 이것이 내 정확한 필요를 채울 것이라고는 생각하지 않습니다. 이 카운터의 주된 초점은 고정 된 범위 번호를 갖는 방법에 더 가깝습니다. 고정 된 범위 번호는 더하거나 뺄 때 래핑을 처리하는 방법을 알고 있습니다.

(아마도 부적절 할지라도) 가장 좋은 방법은 자동으로 오버/언더 플로우를 처리하는 Integer과 같을 것입니다.

package com.math; 

public class GenericRolloverCounter<T extends Number> { 

    private T value; 
    private T lowValue; 
    private T highValue; 

    public GenericRolloverCounter(T l_startValue, T l_highValue) { 
     this.lowValue = l_startValue; 
     this.highValue = l_highValue; 
     this.value = l_startValue; 
    } 

    public T getValue() { 
     return value; 
    } 

    public void setValue(T value) { 
     this.value = value; 
    } 

    public void increment(T valToIncrementBy) { 
     this.value += valToIncrementBy; 
     if (this.value > this.highValue) { 
     this.value = (this.lowValue + (this.value - (this.highValue + 1))); 
     } 
    } 

    public void increment() { 
     this.increment(1); 
    } 

    public void decrement(T valToDecrementBy) { 
     this.value -= valToDecrementBy; 
     if (this.value < this.lowValue) { 
     this.value = ((this.value + this.highValue + 1) - this.lowValue); 
     } 
    } 

    public void decrement() { 
     this.decrement(1); 
    } 

    @Override 
    public String toString() { 
     return Integer.toString(this.value); 
    } 
} 
+1

어떤 종류의 숫자입니까? 카운터가 있고 5.54643643 인 경우 다음 숫자는 무엇을 기대합니까? – Cruncher

+1

정수 계산에 이유가 있습니다. 정수는 ... 계산 가능하기 때문입니다. "다음 실수"라는 개념은 없습니다. 다음 더블의 개념이 있습니다. 그러나 그것은 다소 임의적이며 double 사이의 간격은 일정하지 않습니다. – Cruncher

+0

@Cruncher 우리는 모두 "5로 계산"을 배우며, 우리는 항상 하나의 정수로 계산되지는 않는다고 제안합니다. 예를 들어, 우리는 동전을 미국 달러로 나누는 방식이기 때문에 미국에서는 .01과 .05 및 .10과 .25 단위로 돈을 계산합니다. 나는 다음 두 배를 고정 된 양 또는 양의 세트만큼 증가 및 감소시키는 개념을 생각하지 않는다. –

답변

0

또한 계산할 금액을 지정할 수도 있습니다. 기본값은 1입니다.

Number 방법 .doubleValue()을 사용하고 이중 산술을 수행하면 일부 문제를 해결할 수 있습니다.

다음은이 아이디어를 사용하기 위해 변환 된 방법 중 하나입니다.

public void decrement(double valToDecrementBy) { 
    double work = this.value.doubleValue(); 
    work -= valToDecrementBy; 
    // should use some value related to incrementing amount 
    if ((this.value.doubleValue() - this.lowValue.doubleValue()) < 0.1D) { 
    work = ((this.value.doubleValue() + this.highValue.doubleValue() + 1) - this.lowValue.doubleValue()); 
    } 
    // ... no way to put it back 
} 

하지만 여전히 깨끗하고 쉬운 값을 되돌릴 방법이 없습니다. 'Number'에는 일반적으로 사용되는 비 추상 하위 클래스가 있기 때문에 값을 저장하기 위해 추한 instanceof 물건을 사용할 수 있습니다.

if (theValue instanceof Double) { // depends on it having a non-null value prior 
    theValue = (T)(new Double(work)); 
} 

아니면 시작 그냥 복식로 작업 할 때 당신은 double에 시작 값을 변환 할 수 있습니다 : 그것은 다음과 같이 보일 것입니다.

private double value; 
private double lowValue; 
private double highValue; 

public GenericRolloverCounter(T l_startValue, T l_highValue) { 
    this.lowValue = l_startValue.doubleValue(); 
    this.highValue = l_highValue.doubleValue(); 
    this.value = l_startValue.doubleValue(); 
} 

이렇게하면 부동 소수점 값이 증가하고 반올림/평가 문제가 발생합니다.

아 ... 그리고 당신의 toString()은 다음과 같아야합니다

return value.toString(); 

T 클래스에 기본 toString() 방법을 사용합니다.

@ Crusher의 의견은 다른 방법으로 제안합니다. 모든 것을 'int'에 매핑하고 승수를 유지하십시오. 제가 의미하는 것을 보여주는 몇 가지 코드가 있습니다.(감사합니다 크러셔)

private int value; 
private int lowValue; 
private int highValue; 
private double incr; 

public GenericRolloverCounter(T l_startValue, T l_highValue, T incrementAmount) { 
    double incr = incrementAmount.doubleValue(); 
    this.lowValue = Math.round(l_startValue.doubleValue()/incr); 
    this.highValue = Math.round(l_highValue.doubleValue()/incr); 
    this.value = Math.round(l_startValue.doubleValue()/incr); 
} 

public void increment(int valToIncrementBy) { 
    this.value += valToIncrementBy; 
    if (this.value > this.highValue) { 
    this.value = (this.lowValue + (this.value - (this.highValue + 1))); 
    } 
} 

@Override 
public String toString() { 
    return String.valueOf(incr * this.value); 
} 
+1

나는이 수업에서하고 싶은 것들 중 하나를 편집하면서 편집을했다. toString의 올바른 사용에 대한 팁을 주셔서 감사합니다. 내가 물건을 instanceOf 시도 할 수 있지만 중요한 것은 내가 이것을 너무 복잡하게 만들고 필요가없는 것을 일반화하려고한다는 것입니다. 우리는 언제든지 곧 다른 원시적 인 숫자 타입을 생각해 내지 못할 것이라는 것을 의미합니다. 우리가 그렇게한다면, 먼저 다른 것들을 다루어야한다고 생각합니다. – zero298

+0

필자는이 답변을 받아 들일 것입니다. 왜냐하면 내가 말한 것처럼 실제로 이렇게 할 수있는 방법이 없기 때문입니다. 그러나이 대답은 유효한 대안을 제시합니다. – zero298

관련 문제