Как реализовать метод приращения на парах

#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(...) может работать с любым объектом, но должно быть определение того, как это должно работать с конкретными типами объектов. С другой стороны, вы можете использовать отражение, чтобы найти все поля объекта, а затем обработать их рекурсивно.