如何在对上实现增量方法

How to implement an increment method on pairs

我正在处理循环链表,并实现了以下方法以给定值递增列表的元素。

 public void IncrementList(E e) {
    if (!isEmpty()) {
        Node<E> temp = current;

        do {
            Double res = temp.element.doubleValue() +  e.doubleValue();
            temp.element = (E) res;
            temp = temp.next;
        } while (temp != current);
    }
}

此方法适用于双精度列表;但是,现在我试图在成对列表上使用它,但由于该方法用于双打,所以我不断收到错误消息。 我应该怎么做才能更改此方法并让它接受对并增加它们。 下面是我实现的对class:

public class Pair implements Comparable<Pair> {
    int x, y;
    
    public Pair(int x, int y) {
        this.x = x;
        this.y = y;
    }
    
    public int getX() {
        return x;
    }
    
    public void setX(int x) {
        this.x = x;
    }
    
    public int getY() {
        return y;
    }
    
    public void setY(int y) {
        this.y = y;
    }
    
    public String toString() {
        return "(" + x + "," + y + ")";
    }
    
    @Override
    public int compareTo(Pair o) {
    if (this.x > o.x)
        return 1;
    if (this.x < o.x)
        return -1;
    else 
        return 0;
    }
}

您可以引入这样的界面 Incrementable

/**
 * Interface for objects that can be "incremented" by values 
 * from another object
 * @param <E>   element type
 */
public interface Incrementable<E> {
    public E incrementBy(E otherObj);
}

Pair中实现此接口时,方法可以指定为

@Override
public Pair incrementBy(Pair otherObj) {
    if (otherObj == null) {
        return new Pair(this.getX(), this.getY());
    }
    return new Pair(this.getX() + otherObj.getX(), this.getY() + otherObj.getY());
}

请注意,IncrementList(E)方法也需要更改:

public void IncrementList(E e) {
    if (!isEmpty()) {
        Node<E> temp = current;
        do {
            E increasedValue = temp.element;
            if ((e instanceof Incrementable) && (temp.element instanceof Incrementable)) {
                increasedValue = ((Incrementable<E>)temp.element).incrementBy((E)(Incrementable<E>)e);
            } else {
                // perform increment on other types?
                //increasedValue = IncrementUtils.increment(temp.element, e);
            }
            if (increasedValue != null) {
                temp.element = increasedValue;
            }
            temp = temp.next;
        } while (temp != current);
    }
}

还有一点需要考虑:接口 Incrementable return 相同类型但值增加的新实例(像 BigInteger.add(BigInteger) 那样)还是方法应该与对象本身的值(就像 StringBuilder.add(...) 那样)?指定此行为的方式取决于您的整体用例。

以上代码假定将使用新实例;如果你更喜欢更改对象内部的值,那么接口中的签名应该是 void incrementBy(E) 并且 IncrementList(E) 方法不需要在应用增加后重新分配增加的值。

最后一个想法:要使 IncrementList(E) 方法与未实现 Incrementable 的元素一起使用,您可以使用 helper class 和处理其他类型对象的方法,尤其是 Numbers 和 Strings。由于此 classes 不支持更改其“内部”值,因此您需要将增加调用的结果重新分配给列表元素。

作为起点,这个助手 class 可能如下所示:

public class IncrementUtils {
    
    public static <E> E increment(E obj1, E obj2) {
        if ((obj1 == null) || (obj2 == null)) {
            return null;
        }
        if ((obj1 instanceof Integer) && (obj2 instanceof Integer)) {
            return (E)(Integer)(((Integer)obj1) + ((Integer)obj2));
        }
        if ((obj1 instanceof Double) && (obj2 instanceof Double)) {
            return (E)(Double)(((Double)obj1) + ((Double)obj2));
        }
        if ((obj1 instanceof Long) && (obj2 instanceof Long)) {
            return (E)(Long)(((Long)obj1) + ((Long)obj2));
        }
        if ((obj1 instanceof Float) && (obj2 instanceof Float)) {
            return (E)(Float)(((Float)obj1) + ((Float)obj2));
        }
        if ((obj1 instanceof BigDecimal) && (obj2 instanceof BigDecimal)) {
            return (E)((BigDecimal)obj1).add((BigDecimal)obj2);
        }
        if ((obj1 instanceof BigInteger) && (obj2 instanceof BigInteger)) {
            return (E)((BigInteger)obj1).add((BigInteger)obj2);
        }
        if ((obj1 instanceof String) && (obj2 instanceof String)) {
            return (E)((String)obj1 + (String)obj2);
        }
        if ((obj1 instanceof StringBuilder) && (obj2 instanceof StringBuilder)) {
            return (E)(new StringBuilder().append(obj1).append(obj2));
        }
        if ((obj1 instanceof StringBuffer) && (obj2 instanceof StringBuffer)) {
            return (E)(new StringBuffer().append(obj1).append(obj2));
        }
        return null;
    }
    
}