1. Java / Говнокод #12102

    +71

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    class ........... {
        BigDecimal t;
    ...
        public boolean t_is_zero(){
            BigDecimal zero = new BigDecimal(0);
    
            if(this.t == zero)
                return true;
            else
                return false;
        }
    ...
    }

    для операции сравнения была создана новая переменная как эквивалент )

    Запостил: azv, 12 Ноября 2012

    Комментарии (39) RSS

    • Но, кстати, что-нибудь типа
      return t == BigDecimal.fromInteger(0);

      по сути будет то же самое.
      Ответить
      • Нет. Во-первых такого метода BigDecimal.fromInteger нет.
        Во-вторых есть BigDecimal.ZERO.

        Говно вот в чем:
        >BigDecimal zero = new BigDecimal(0); //причем в методе, а не константа
        Я промахнулся дважды - коммент плюсанул, а код минуснул. Надо было наоборот.
        Ответить
        • спасибо за BigDecimal.ZERO ) переделаю )
          Ответить
          • В-третьих, BigDecimal.valueOf чуть лучше чем new BigDecimal из-за кеша.
            Ответить
            • Кстати походу equals тоже некорректное решение. Т.к. Unlike compareTo, this method considers two BigDecimal objects equal only if they are equal in value and scale (thus 2.0 is not equal to 2.00 when compared by this method).

              http://ideone.com/i0UAo4
              Ответить
              • return t <= BigDecimal.ZERO && t >= BigDecimal.ZERO;
                ?
                Ответить
              • Это общее негласное правило: если класс реализует Comparable, очень рекомендуется сравнивать через compareTo(), потому что equals() может быть реализован неправильно. Кажется, у Блоха это написано.
                Вот такие вот ЖАБАПРОБЛЕМЫ
                Ответить
                • class MyTools
                  {
                    public static myEquals( object o1, object o2 )
                    {
                      ...
                      if (o1 is Comparable)
                        return ((Comparable)o1).compareTo(o2);
                      ...
                      return o1.equals(o2);
                    }
                  }
                  Ответить
                  • А теперь давайте запилим такое же в стандартные контейнеры типа HashMap.
                    Ответить
                    • На самом деле есть способ. Опять сталкиваемся с джавой и опять говно.
                      В WeakReference да и во всех остальных "забыли" переопределить важные методы.

                      Сделать свой класс Ref с equals и hashCode.
                      Или WeakRef, StrongRef, SoftRef - по вкусу.
                      Билдить так Ref.weak(obj) ну или WeakRef.to(obj). В мапах польза неимоверная.
                      Пишется за две секунды, быдло очень боится.
                      Ответить
                  • if (o1 is Comparable)
                          return ((Comparable)o1).compareTo(o2);

                    Лол, хоть я не минусовал, но самое смешное что этот код тоже неправильный.
                    Comparable<T> означает вызов
                    compareTo(T o);
                    Если o2 is not T получим ошибку.
                    Ответить
                    • Я тоже хотел об этом написать, но поленился. Там на самом деле невозможно сделать типобезопасно и гибко одновременно.
                      Ответить
                      • >Там на самом деле невозможно сделать типобезопасно и гибко одновременно.
                        Но и это еще не всё. Там может быть какой-то Comparable<Time>, или там Comparable<Delayed> который, например сранивает по типу время создания.
                        Если мы напишем код выше, то объекты созданное в одно время будут равны ибо compareTo по времени идентичен.
                        А когда _внезапно_ окажется что объекты содержат поля о которых невозможно какое из них больше, а какое меньше, то вполне резонно, что в compareTo их учитывать никто не станет.
                        А equals наоборот их сранит правильно.

                        >очень рекомендуется сравнивать через compareTo()
                        Потому я сразу засомневался в полезности этой практики, не помню чтобы у Блоха такое было. Помню читал что надо при реализации класса из equals вызвать compareTo, по простой причине - не копипастить и не дублировать код.
                        Кстати разработчики что в BigInteger что в BigDecimal успешно на это забили.

                        PS: http://govnokod.ru/11813#comment155127
                        Ответить
                        • Возможно, с "очень рекомендуется" я загнул, но про то, что equals может быть неконсистентным, есть:

                          "It is strongly recommended, but not strictly required, that (x.compareTo(y) == 0) == (x.equals(y))...
                          ... general contracts for these interfaces (Collection, Set, Map) are defined in terms of the equals method, but sorted collections use the equality test imposed by compareTo in place of equals...
                          Because the Comparable interface is parameterized, the compareTo method is statically typed, so you don't need to type check or cast its
                          arguments..."


                          В общем, складывается тенденция использовать compareTo вместо equals, если это возможно.
                          Ответить
                          • 64-я страница. Немного не дочитал :)
                            The final paragraph of the compareTo contract, which is a strong suggestion
                            rather than a true provision, simply states that the equality test imposed by the
                            compareTo method should generally return the same results as the equals
                            method. If this provision is obeyed, the ordering imposed by the compareTo
                            method is said to be consistent with equals. If it’s violated, the ordering is said to
                            be inconsistent with equals.
                            A class whose compareTo method imposes an order
                            that is inconsistent with equals will still work.


                            Собственно я нахожу эту практику сомнительной и не стал сравнивать объекты через compare ибо сиё условие необходимо для равенства. Но НЕ достаточно!

                            Заменять им equals, который сделан для сравнения - глупо. А если equals - неправильный это проблемы кривого класса, и мы не должны в клиентском коде затыкать их.

                            Со сравнениями чисел много нюансов.
                            Ведь никто ж не ожидает увидеть тут true:
                            Byte.valueOf(2).equals(Integer.valueOf(2 )).
                            Хотя по сути они равны.
                            Ответить
                          • Для сравнения сделали equals - вот его и юзайте. BigDecimal - говно, да. Но не надо лепить Comparable-велосипед, затыкая чужие баги. Ведь в другом случае можно получить 0 когда объекты !=.
                            Можно найти либу, или обернуть как нравится.
                            Кстати из-за этого сраного BigDecimal пострадала и ни в чем не повинная скала.
                            http://govnokod.ru/12003
                            Ответить
                • Я лентяй, я никак не могу заставить себя сесть и начать читать Блоха.
                  Ответить
                  • С другой стороны, зачем вам это надо? :)
                    Там в основном жабо-аспекты, если вы не используете её на работе, оно вам врядли сильно пригодится. Хотя, есть некоторые интересные вещи, не зависящие от языка.
                    Ответить
                    • > зачем вам это надо?
                      Да тут мне задачку под ведроид подкинули... а там же жаба. Вот решил заодно ее подучить, чтобы не писать совсем уж быдлятский код, т.к. мой опыт работы с явой состоит из пары программок на J2ME да копания в клиенте Haven&Hearth.
                      Ответить
                      • Самое главное, что рассказывает Блох, это принципы SOLID:
                        1. На каждый объект - одна обязанность.
                        2. Сущности должны быть открыты для расширения и закрыты от изменения.
                        3. Принцип подстановки Лисков.
                        4. Много специализированных интерфейсов лучше чем один общий.
                        5. Принцип инверсии зависимостей.

                        Пункты 3 и 5 лучше изучить отдельно, их в двух словах не описать.
                        Ответить
                        • Ну принципы SOLID я и так знаю. Причем как это не странно принципы узнал раньше их названий, и по отдельности.
                          Ответить
                          • Ну ещё он говорит, что лучше создавать неизменяемые объекты. Т.е. задать состояние которых можно только в конструкторе.

                            Например:
                            //НЕПРАВИЛЬНО
                            class Point
                            {
                               Point();
                               void setX(int);
                               void setY(int);
                               void moveX(int);
                               void moveY(int);
                               int getX();
                               int getY();
                            };
                            
                            //ПРАВИЛЬНО
                            class Point
                            {
                               Point( int, int );
                               Point move( Point );
                               int getX();
                               int getY();
                            }
                            Ответить
                            • А эту мысль я из хаскела почерпнул ;) Но к сожалению она не везде применима.
                              Ответить
                            • Я бы не стал слепо верить Блоху.
                              Сам подход ПРАВИЛЬНО/НЕПРАВИЛЬНО написанный капсом уже неверен.
                              Ответить
                              • Нет правильных и неправильных решений, есть решения примененные к месту и не к месту.
                                Ответить
                              • Вы правы. Как же я мог решить, что более безопасный вариант лучше, чем опасный объект с состоянием?
                                Ответить
                                • Безопасный то он безопасный, но далеко не всегда можно позволить себе пересоздавать объект с нуля.
                                  Ответить
                                  • На java в основном ынтырпрайз проекты пишутся и от них требуется стабильность.

                                    А если нужна скорость - в пизду объекты, надо писать на голой сишке.
                                    Ответить
                                    • На жабе есть достаточно быстрые программы (Lucene, например). Всё зависит от программиста (хотя ограничения есть, JGit не смогли оптимизнуть так, чтобы хотя бы увидеть далёкий git впереди).
                                      Ответить
                                      • Да. Люцена - широкоиспользуемая штука. И не особо прихотливая к ресурсам.
                                        А мне еще в известной пасте особо нравится этот кусок:
                                        тебя ждет увлекательный мир хайлоада. Apache Hadoop, сверхбыстрые асинхронные key-value хранилища, MapReduce. Отсос хиккующих выблядков джава-хуесосов, которые сосут хуй по жизни
                                        Ответить
                                • Вам, любителям безопасных объектов, сюда:
                                  http://govnokod.ru/7019
                                  Ответить
                                  • Я представляю как этот геттер выглядел бы на яве... Над каждым вызовом 28 раз new... Ведь простые инты да флоаты не пролезут по ссылке.
                                    Ответить
                  • > я никак не могу заставить себя сесть и начать читать Блоха.
                    Такое же. Правда я прочел страниц 50 но потом забил.
                    >очень рекомендуется сравнивать через compareTo(), потому что equals() может быть реализован неправильно
                    >у Блоха это написано.
                    Кажись не. Спасибо, не знал. Еще одни грабли в копилочку equals.

                    Кстати подход предложенный @Steve_Brown MyTools. myEquals - я тоже считаю глубоко правильным.
                    Порочное ООП с его nullами и остальным говном не пройдёт.
                    Ответить
                    • Ну, обработку null-ов я оставил за многоточиями...
                      Ответить
                      • Спасибо кеп. Очевидно же зачем они там.
                        Так лажа еще в том что есть Comparator и Comparable - очередной фейл жабы.
                        Ну как Enumeration и Iterator. Несмотря на иммутабельную полезность первого все используют итераторы только из-за Iterable и сахара в for()
                        Говно, говно повсюду.
                        Ответить
          • ну наконец то народ научился просить о помощи )
            Ответить
        • Так еще и сравнение через == объектов созданных через new...

          P.S. Вот так правильно будет?
          return BigDecimal.ZERO.equals(t);
          Ответить

    Добавить комментарий