#java #increment #circular-list
Вопрос:
Я работаю над циклическим связанным списком и реализовал следующий метод увеличения элементов списка на заданное значение.
public void IncrementList(E e) { if (!isEmpty()) { Nodelt;Egt; temp = current; do { Double res = temp.element.doubleValue() e.doubleValue(); temp.element = (E) res; temp = temp.next; } while (temp != current); } }
Этот метод отлично работает со списками двойников; однако теперь я пытаюсь использовать его в списке пар, но продолжаю получать ошибку, так как метод используется для двойников. Что я должен сделать, чтобы изменить этот метод и позволить ему принимать пары и увеличивать их. Ниже приведен класс пар, который я реализовал:
public class Pair implements Comparablelt;Pairgt; { 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 gt; o.x) return 1; if (this.x lt; o.x) return -1; else return 0; } }
Комментарии:
1. Каков ваш ожидаемый результат и какую ошибку вы получаете? Из того, что у вас есть сейчас, кажется, что вам нужно будет реализовать специальный интерфейс для объектов, которые может хранить ваш список, чтобы справиться с этим.
2. Это мой ожидаемый результат: перед увеличением: Список 1= [(10,10), (50,50), (50,50)] после приращения: Список 1. Список приращений(p10) Список1 = [(20,20), (60,60), (60,60)]
3. Ошибка, которую я получаю, заключается в том, что пару нельзя привести к java.lang.double, я могу создать отдельный интерфейс, который будет реализован моим классом, но что я должен добавить в этот интерфейс
Ответ №1:
Вы могли бы представить интерфейс Incrementable
, подобный этому:
/** * Interface for objects that can be "incremented" by values * from another object * @param lt;Egt; element type */ public interface Incrementablelt;Egt; { 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()) { Nodelt;Egt; temp = current; do { E increasedValue = temp.element; if ((e instanceof Incrementable) amp;amp; (temp.element instanceof Incrementable)) { increasedValue = ((Incrementablelt;Egt;)temp.element).incrementBy((E)(Incrementablelt;Egt;)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
возвращать новые экземпляры того же типа, но со значениями, увеличенными (например BigInteger.add(BigInteger)
, делает), или метод должен работать со значениями в самом объекте (например StringBuilder.add(...)
, делает)? Это зависит от ваших общих вариантов использования, как указать это поведение.
Приведенный выше код предполагает, что будут использоваться новые экземпляры; если вы предпочитаете изменять значения внутри объектов, то подпись в интерфейсе должна быть void incrementBy(E)
, и IncrementList(E)
методу не нужно повторно присваивать увеличенное значение после применения увеличения.
И последняя мысль: чтобы заставить IncrementList(E)
метод работать с элементами, которые не реализуются Incrementable
, вы можете использовать вспомогательный класс с методом, который обрабатывает некоторые другие типы объектов, особенно Number
s и String
s. Поскольку эти классы не поддерживают изменение своих «внутренних» значений, вам необходимо повторно назначить результат вызова увеличения элементам списка.
В качестве отправной точки этот вспомогательный класс может выглядеть следующим образом:
public class IncrementUtils { public static lt;Egt; E increment(E obj1, E obj2) { if ((obj1 == null) || (obj2 == null)) { return null; } if ((obj1 instanceof Integer) amp;amp; (obj2 instanceof Integer)) { return (E)(Integer)(((Integer)obj1) ((Integer)obj2)); } if ((obj1 instanceof Double) amp;amp; (obj2 instanceof Double)) { return (E)(Double)(((Double)obj1) ((Double)obj2)); } if ((obj1 instanceof Long) amp;amp; (obj2 instanceof Long)) { return (E)(Long)(((Long)obj1) ((Long)obj2)); } if ((obj1 instanceof Float) amp;amp; (obj2 instanceof Float)) { return (E)(Float)(((Float)obj1) ((Float)obj2)); } if ((obj1 instanceof BigDecimal) amp;amp; (obj2 instanceof BigDecimal)) { return (E)((BigDecimal)obj1).add((BigDecimal)obj2); } if ((obj1 instanceof BigInteger) amp;amp; (obj2 instanceof BigInteger)) { return (E)((BigInteger)obj1).add((BigInteger)obj2); } if ((obj1 instanceof String) amp;amp; (obj2 instanceof String)) { return (E)((String)obj1 (String)obj2); } if ((obj1 instanceof StringBuilder) amp;amp; (obj2 instanceof StringBuilder)) { return (E)(new StringBuilder().append(obj1).append(obj2)); } if ((obj1 instanceof StringBuffer) amp;amp; (obj2 instanceof StringBuffer)) { return (E)(new StringBuffer().append(obj1).append(obj2)); } return null; } }
Комментарии:
1. есть ли способ написать тот же метод приращения в рекурсивной форме
2. Метод приращения зависит от объекта, с которым он работает.
IncrementUtils.increment(...)
может работать с любым объектом, но должно быть определение того, как это должно работать с конкретными типами объектов. С другой стороны, вы можете использовать отражение, чтобы найти все поля объекта, а затем обработать их рекурсивно.