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

    +71

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    List<String> list = ...;
    for (String s : someStringList)
        list.add(s);
    list.set(SOME_CONST, someString);
    list.add(0, secondSomeString);

    Поначалу никак не мог понять, почему list.get(SOME_CONST) != someString. Ну и копирование через цикл тоже норм

    Запостил: evg_ever, 11 Июня 2014

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

    • а как без цикла клонировать список?
      Collections.copy
      с циклом внутри не предлагать
      Ответить
      • Для ArrayList немного reflection'a + System.arraycopy. Впрочем можно глянуть его реализацию на пример "хаков"
        Ответить
        • >Для ArrayList немного reflection'a + System.arraycopy
          System.arraycopy секономили чтобы скопировать десять значений, а рефлексия съела на миллион.
          Я уж молчу что System.arraycopy не всегда самый эффективный способ.

          >а как без цикла клонировать список?
          Рефлексия, System.arraycopy? А всего-то копирующий конструктор new ArrayList(other) или как подсказывает кеп клонировать методом clone().
          Ответить
          • >System.arraycopy секономили чтобы скопировать десять значений, а рефлексия съела на миллион.
            Чукча не знать про количество элементов, чукча отвечать. А если серьезно, как по мне, если надо часто копировать большие ArrayList'ы, может и прокатить. Достать один раз Field и поехали. Unsafe предлагать не стану - ненадежно как по мне.

            >А всего-то копирующий конструктор new ArrayList(other)
            Опять же только если other - ArrayList.
            Ответить
            • >Опять же только если other - ArrayList.
              Да неужели?
              /**
                   * Constructs a list containing the elements of the specified
                   * collection, in the order they are returned by the collection's
                   * iterator.
                   *
                   * @param c the collection whose elements are to be placed into this list
                   * @throws NullPointerException if the specified collection is null
                   */
                  public ArrayList(Collection<? extends E> c)
              Ответить
              • public ArrayList(Collection<? extends E> c) {
                	elementData = c.toArray();
                	size = elementData.length;
                	// c.toArray might (incorrectly) not return Object[] (see 6260652)
                	if (elementData.getClass() != Object[].class)
                		elementData = Arrays.copyOf(elementData, size, Object[].class);
                }


                LinkedList:
                public Object[] toArray() {
                	Object[] result = new Object[size];
                	int i = 0;
                	for (Node<E> x = first; x != null; x = x.next)
                		result[i++] = x.item;
                	return result;
                }


                А вот и цикл. А по делу,
                > как подсказывает кеп клонировать методом clone().
                +1 - пусть уж имплементация решает, с циклом или без.
                Ответить
                • а) НЕ ИСПОЛЬЗУЙТЕ clone()
                  б) НЕ КОПИРУЙТЕ массивы System.arraycopy. используйте array.clone()
                  http://www.artima.com/intv/bloch13.html
                  Josh Bloch: If you've read the item about cloning in my book, especially if you read between the lines, you will know that I think clone is deeply broken. There are a few design flaws, the biggest of which is that the Cloneable interface does not have a clone method. And that means it simply doesn't work: making something Cloneable doesn't say anything about what you can do with it. Instead, it says something about what it can do internally. It says that if by calling super.clone repeatedly it ends up calling Object's clone method, this method will return a field copy of the original.

                  But it doesn't say anything about what you can do with an object that implements the Cloneable interface, which means that you can't do a polymorphic clone operation. If I have an array of Cloneable, you would think that I could run down that array and clone every element to make a deep copy of the array, but I can't. You cannot cast something to Cloneable and call the clone method, because Cloneable doesn't have a public clone method and neither does Object. If you try to cast to Cloneable and call the clone method, the compiler will say you are trying to call the protected clone method on object.

                  The copy constructor approach has several advantages, which I discuss in the book. One big advantage is that the copy can be made to have a different representation from the original. For example, you can copy a LinkedList into an ArrayList.
                  Doug Lea goes even further. He told me that he doesn't use clone anymore except to copy arrays. You should use clone to copy arrays, because that's generally the fastest way to do it. But Doug's types simply don't implement Cloneable anymore. He's given up on it. And I think that's not unreasonable.
                  It's a shame that Cloneable is broken, but it happens.
                  Ответить
                  • Да, тут соглашусь. Не забудем еще и про
                    throws CloneNotSupportedException;


                    Который добавляет макарон в наш суп код.
                    Ответить
                    • А жавкаиде показывает на вызове clone(), что нихуя не выйдет?
                      Ответить
                  • > Cloneable interface does not have a clone method.
                    Вот клоуны! Т.е. полиморфное клонирование, ради которого все это и мутили не работает?
                    Ответить
                    • Лол. В шарпике все работает
                      Ответить
                      • > Лол. В шарпике все работает
                        Если бы в шарпике не проделали работу над ошибками жабы - их можно было бы смело называть долбоёбами-плагиаторами :)
                        Ответить
                    • Clownable
                      Ответить
                      • Сразу вспомнил гег про маленькую машину и много клоунов
                        Ответить
                    • cloneable это просто интерфейс-маркер, у него вообще нет методов

                      package java.lang;
                      
                      /**
                       * A class implements the <code>Cloneable</code> interface to 
                       * indicate to the {@link java.lang.Object#clone()} method that it 
                       * is legal for that method to make a field-for-field copy of instances of that class. 
                       * <p>
                       * Invoking Object's clone method on an instance that does not implement the 
                       * <code>Cloneable</code> interface results in the exception 
                       * <code>CloneNotSupportedException</code> being thrown.
                       * <p>
                       * By convention, classes that implement this interface should override 
                       * <tt>Object.clone</tt> (which is protected) with a public method.
                       * See {@link java.lang.Object#clone()} for details on overriding this
                       * method.
                       * <p>
                       * Note that this interface does <i>not</i> contain the <tt>clone</tt> method.
                       * Therefore, it is not possible to clone an object merely by virtue of the
                       * fact that it implements this interface.  Even if the clone method is invoked
                       * reflectively, there is no guarantee that it will succeed.
                       *
                       * @author  unascribed
                       * @version %I%, %G%
                       * @see     java.lang.CloneNotSupportedException
                       * @see     java.lang.Object#clone()
                       * @since   JDK1.0
                       */
                      public interface Cloneable { 
                      }
                      Ответить
      • >с циклом внутри не предлагать
        Может это прозвучит для кого-то дико и удивительно, но внутри ВСЕГДА был, есть и будет цикл.
        Ответить
        • >внутри ВСЕГДА был, есть и будет цикл.
          аминь
          Ответить
      • >с циклом внутри не предлагать
        Не ну можно рекурсией. Циклы - это ж устаревшая дрянь, для придурошных императивных старпёров.
        Правда нет гарантий, что внутри она не превратится jitом в ненавистный цикл!
        Ответить
        • Проклятые императивщики! И до компилятора жабы добрались
          Ответить
          • Черт, вынудили )

            list.stream().collect(Collectors.toList());


            вроде нигде не ошибся
            Ответить
    • > почему list.get(SOME_CONST) != someString
      а что вы ожидали от list.add(0, secondSomeString);?
      Ответить

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