Вниз  Java-программирование (1-ые посты)
- 22.03.2016 / 21:30
mcdevil
  Пользователь

mcdevil 
Сейчас: Offline
Всем привет, у меня вопрос, оператор instanceof насколько медленный?
P.S. Если он очень медленный, есть ли альтернатива этому оператору?

Изменено mcdevil (22.03 / 21:31) (всего 1 раз)
- 22.03.2016 / 21:50
Ginosaji
  Пользователь

Ginosaji 
Сейчас: Offline
mcdevil, альтернатива - шаблон проектирования Visitor.
- 22.03.2016 / 22:07
mcdevil
  Пользователь

mcdevil 
Сейчас: Offline
Ginosaji, А что это?
- 22.03.2016 / 22:21
Sweety
  Пользователь

Sweety 
Сейчас: Offline
mcdevil, Visitor не совсем об этом :) Здесь просто перегрузка метода.
Вот такой код:
  1. if (object instanceof Integer) { ... }
  2. else if (object instanceof Double) { ... }

Можно переписать так:
  1. ...
  2. do(object);
  3. ...
  4. private void do(Integer value) { ... }
  5. private void do(Double value) { ... }

- 22.03.2016 / 22:46
Sweety
  Пользователь

Sweety 
Сейчас: Offline
А Visitor уже про объекты. Есть набор объектов, над которыми нужно выполнять некоторые операции. При это, если нужно определить новую, то нельзя изменять структуру этих классов (чем меньше мы трогаем её, тем лучше).
  1. public abstract class AbstractElement {
  2.   public abstract void accept(IVisitor visitor);
  3. }
  4. public class ElementA extends AbstractElement {
  5.   private int id;
  6.   ...
  7.   @Override
  8.   public void accept(IVisitor visitor) {
  9.     visitor.visit(this);
  10.   }
  11. }
  12. public class ElementB extends AbstractElement {
  13.   private string name;
  14.   ...
  15. }
  16.  
  17. public interface IVisitor {
  18.   void visit(ElementA el);
  19.   void visit(ElementB el);
  20. }
  21. public class RawFormatStdPrinter implements IVisitor {
  22.   public void visit(ElementA el) {
  23.     System.out.println("Id: "+ el.getId());
  24.   }
  25.   public void visit(ElementB el) {
  26.     System.out.println("Name:" + el.getName());
  27.   }
  28. }

Преимущество такого шаблона в том, что если мы вдруг захотим выводить не в консоль, а в файл, да ещё и в каком-нибудь JSON, то нам придётся просто создать ещё одного «посетителя» (а создание класса дешевле изменения существующего) :)

Изменено Ксакеп (23.03 / 10:14) (всего 1 раз)
- 23.03.2016 / 09:21
ВитаминКО
  Супермодератор

ВитаминКО 
Сейчас: Offline
Короче, я уже запарился разбираться с Enum.. пишу какой-то сс..ый калькулятор уже второй день..

Есть два класса, мейн и класс операций. по задумке, чтобы уйти от использования свитчей, нужно в перечислениях операций реализовать метод getResult.

В основном классе я считываю сканером два значения и оператор (тип String, с char не хочу извращаться, да и много лишнего кода из-за него будет). Далее мне как-то надо вызвать тот метод getResult, чтобы вывести консоль. Текущая реализация с ошибкой. Не знаю, что делать. Пытался привести к типу Operations строковое значение оператора - ошибка, писал похожую конструкцию Operations o = o.getResult(arg1, arg2); - никак.

Примеры гуглил, было похожее что-то, но там просто по-очереди вызывался метод типа моего getResult, но мне не подходит, т.к. оператор заранее не известен.. А то и вообще какие-то громоздкие конструкции.

1 из 2Trulala
Run.java
  1. import java.util.Scanner;
  2.  
  3. public class Run {
  4.  
  5.     private static double argument1;
  6.     private static double argument2;
  7.     private String operator;
  8.     private static String result;
  9.  
  10.     public static void main(String[] args) {
  11.         Run app = new Run();
  12.         app.runApp();
  13.     }
  14.  
  15.     public void runApp() {
  16.  
  17.         Scanner sc = new Scanner(System.in);
  18.  
  19.         System.out.println("Enter your first value:");
  20.         argument1 = sc.nextDouble();
  21.  
  22.         System.out.println("Enter your second value:");
  23.         argument2 = sc.nextDouble();
  24.  
  25.         System.out.println("Enter operation: ");
  26.         operator = sc.next();
  27.         sc.close();
  28.         // Здесь трабла, хз как правильно вызвать метод
  29.         result = operator.getResult(argument1, argument2);
  30.  
  31.         System.out.println("Result: " + result);
  32.     }
  33. }
И еще по поводу @Override: где-то он используется, где-то нет (в разных реализациях одного и того же кода) - здесь оно надо? До этого у меня было проще, но ошибка все равно оставалась, проблемы с типами. Пока пробовал разные варианты кода, допогромировал до такого состояния :gg:
__________________
 わからない!!
- 23.03.2016 / 09:54
Ginosaji
  Пользователь

Ginosaji 
Сейчас: Offline
ВитаминКО, предлагаю такой вариант:
1. Делаем интерфейс IBinaryOperator.
  1. public interface IBinaryOperator {
  2.         double getResult(double arg1, double arg2);
  3. }
Пишем его реализации под каждый оператор:
  1. public class Addition implements IBinaryOperator {
  2.  
  3.         @Override
  4.         public double getResult(double arg1, double arg2) {
  5.                 return arg1 + arg2;
  6.         }
  7. }
  8.  
  9. public class Subtraction implements IBinaryOperator {
  10.  
  11.         @Override
  12.         public double getResult(double arg1, double arg2) {
  13.                 return arg1 - arg2;
  14.         }
  15.  
  16. }
  17. ...
В классе Operations заводим ассоциативный массив:
  1. public class Operations {
  2.         private Map<String, IBinaryOperator> operators;
  3.  
  4.         public Operations() {
  5.                 operators = new HashMap<>(4);
  6.                 operators.put("+", new Addition());
  7.                 operators.put("-", new Subtraction());
  8.                 ...
  9.         }
  10.  
  11.         public double getResult(String op, double arg1, double arg2) {
  12.                 IBinaryOperator operator = operators.get(op);
  13.                 if (operator == null) {
  14.                         throw new IllegalArgumentException("invalid operator " + op);
  15.                 }
  16.                 else {
  17.                         return operator.getResult(arg1, arg2);
  18.                 }
  19.         }
  20. }
В главном классе, как обычно, читаешь сканнером оператор и аргументы и передаёшь их в Operators.getResult(String, double, double);

Изменено Ginosaji (23.03 / 09:55) (всего 1 раз)
- 23.03.2016 / 09:57
mcdevil
  Пользователь

mcdevil 
Сейчас: Offline
Sweety, при этом производительность повышается или нет никакой разницы?
- 23.03.2016 / 10:47
Sweety
  Пользователь

Sweety 
Сейчас: Offline
mcdevil, не знаю, не проверяла. Но, думаю, может слегка просесть. Но не критично, если ты не пишешь для встраиваемых систем :)
- 23.03.2016 / 11:16
ВитаминКО
  Супермодератор

ВитаминКО 
Сейчас: Offline
Ginosaji, оно, конечно, интересно, но мне надо именно с помощью Enum. И у тебя изврат какой-то, зачем так.. сложно, что ли..

С помощью Enum можно сделать, я знаю. Мне просто надо понять, где у меня ошибка.
__________________
 わからない!!
Наверх  Всего сообщений: 16875
Фильтровать сообщения
Поиск по теме
Файлы топика (794)