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

    +76

    1. 1
    2. 2
    3. 3
    4. 4
    5. 5
    6. 6
    7. 7
    8. 8
    9. 9
    @Override
        public ResponseBag[] send(SmsBag[] smsBag) {
            ArrayList<ResponseBag> responseList = new ArrayList<ResponseBag>();
            for(SmsBag bag : smsBag) {
                responseList.add(super.send(bag));
            }
            ResponseBag[] responseBag = new ResponseBag[responseList.size()];
            return responseList.toArray(responseBag);
        }

    Запостил: manyrus, 18 Августа 2011

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

    • Хотя и смахивает на гк, но как сделать лучше?
      Ответить
    • Как минимум, ArrayList нужно заменить на LinkedList.
      Ответить
    • есть же System.copy()
      Ответить
    • Строку 7 и 8 заменить на
      return responseList.toArray();
      Ответить
      • Возвратит объект типа Object :).
        Ответить
      • Лучше не лезьте с советами по java, если её не знаете. Информация о типе массива, в отличие от списков, НЕ стирается в рантайме. Массив Object не кастится в массив подклассов Object. Вот так можно было бы
        return responseList.toArray(new ResponseBug[0]);
        только толку от этого немного, одну строчку сыкономили.
        Ответить
    • нормальный код.

      Только почему super.send(bag), а не просто send(bag)?

      П. С. В объявлениях переменной лучше использовать интерфейсы, т. е.
      List<ResponseBag> responseList = new ArrayList<ResponseBag>();

      Ну и можно было сразу размер списка задать через конструктор new ArrayList<ResponseBag>(smsBag.length).

      Можно было так:
      public ResponseBag[] send(SmsBag[] smsBag) {
      ResponseBag[] responseBag = new ResponseBag[smsBag.length];
      for (int i = 0; i < smsBag.length; i++) {
      responseBag[i] = super.send(smsBag[i]);
      }
      return responseBag;
      }
      Ответить
      • +1. Только научитесь, пожалуйста, использовать bbcode для кода.
        А ещё лучше было бы совсем избавиться от массивов и использовать только списки. Если, конечно, есть такая возможность.
        Ответить
    • Вообще говоря, довольно странный код. Раз стоит @Override, значит, мы переопределяем метод суперкласса. Однако же никакого внятного функционала в коде нет - один тупой foreach. Что же тогда в родительском классе? Может, конечно, оверрайдится метод интерфейса, не определённый в суперклассе (тогда код не скомпилится javaс 1.5), но тогда непонятно, почему этот метод не определён в суперклассе.
      Короче, довольно изысканное говнецо.
      Ответить
      • Предвижу, что super.send() выполняет отправку для одного SmsBag, а нам представлен метод наследника являющегося коллекцией типа своего родителя. Т.е., если super -> Node, то this -> Tree.
        Но я не на столько хорошо знаю Java, чтобы понять зачем столько раз нужно было создавать разные коллекции.
        Ответить
        • > что super.send() выполняет отправку для одного SmsBag
          очевидно (есть @Override), у super должен быть ещё и метод, отправляющий массив SmsBag
          public ResponseBag[] send(SmsBag[] smsBag);

          Он либо не реализован, либо делает не то, что нужно. Возможно ещё, что этот метод определён в некотором другом интерфейсе, не реализованным суперклассом, но мне кажется это маловероятным.
          Подтвердить или опровергнуть догадки может только @manyrus.

          > зачем столько раз нужно было создавать разные коллекции
          Чтобы правильно перевести кошерные коллекции в некошерные массивы.
          Ответить
          • Я спроектировал свою библиотеку так:
            Namespace: components.
            ISendSingLesms:
            public interface ISendSingleSms {
                /**
                 * This method will send the msg.
                 * @param bag
                 * @return 
                 */
                public ResponseBag send(SmsBag bag);
            }

            ISendingSms:
            /**
             *
             * @author manyrus
             */
            public interface ISendingSms {
                public ResponseBag[] send(SmsBag[] bag);
            }

            Так же тут есть 2 класса - ResponseBag и SmsBag - обычные классы со своими геттерами/сеттерами.
            ------------------------------
            Namespace: components.epochta.
            BaseSmsSender:
            public class BaseSmsSender {
                
                public ResponseBag send(SmsBag bag) {
                    throw new UnsupportedOperationException("Not supported yet.");
                }
            }

            SendingSms:
            public class SendingSms extends BaseSmsSender implements ISendingSms{
            
                @Override
                public ResponseBag[] send(SmsBag[] smsBag) {
                    ResponseBag[] responseBag = new ResponseBag[smsBag.length];
                    for (int i = 0; i < smsBag.length; i++) {
                        responseBag[i] = super.send(smsBag[i]);
                    }
                    return responseBag;
                }
                
            }

            SendingSingleSms:
            public class SendSingleSms extends BaseSmsSender implements ISendSingleSms {
            
                @Override
                public ResponseBag send(SmsBag bag) {
                    return super.send(bag);
                }
                
            }

            Только вот это архитектура мне совсем не нравиться, за 2 мин. её придумал. Надо ещё посидеть :).
            Ответить
            • Вот всё и всплыло.
              Странно разделять один и тот же фасадный функционал по разным интерфейсам. Я бы сделал так:
              public interface SmsSender {
                  ResponseBag send(SmsBag bag);
                  Collection<ResponseBag> sendAll(Collection<SmsBag> bags);
              }

              Ещё мне не совсем понятен суффикс "Bag". Почему бы не использовать имена Sms и Response?
              И, кстати, аннотация @Override над реализацией метода, определённого в интерфейсе, работает только в java 1.6. Если не хотите проблем с обратной совместимостью, лучше ставить её только при переопределении метода базового класса.
              Ответить
              • Я думаю так - класс не должен быть "на все руки мастер", поэтому я разбил его на 2 класса.
                Ответить
                • Вы говорите правильные вещи, но применяете эти правила неправильно. Класс должен делать что-то одно, но делать это хорошо (в традициях UNIX). Тем не менее, это не значит, что в классе должно быть не более 1 метода. К примеру, отправка SmsBag - функционал, достойный отдельного класса (интерфейса). Он может отправить одну SmsBag или пачку, только один этот класс должен знать, как это делается. Когда появляется второй похожий класс (интерфейс), ответственность размазывается, её границы расплываются.
                  Ответить
                • Кстати сказать про объектную систему... ситуация когда нужно наследовать класс с send(multiple itmes) от send(item) похожа на ситуацию с наследованим эллипс от круга. Т.е. это `встроенный' недостаток объектно ориентированого подхода - нет однозначного решения, как правильно и нужно ли вообще. Я бы представлял отправку множества посылок как более универсальный метод, и его бы закладывал в базисный класс, а его потомок делал бы более специализированую операцию (если вообще такой потомок нужен) - отправку одной посылки. Кроме того, я старался бы не создавать интерфейсы пока в этом нет необходимости. Необходимость в интерфейсе, в моем представлении возникает тогда, когда обычное наследование не позволяет решить проблему.
                  Ответить
                  • Не учите плохому :)
                    Интерфейсы - добро и ядро IoC, наследование от обычных классов нужно довольно редко и должно наводить на размышления (очень часто его можно заместить композицией). Именно в этом конкретном случае лучше создать интерфейс и его реализацию, чем строить невнятные иерархии классов.
                    Ответить
                  • > наследованим эллипс от круга
                    наследование эллипса от круга так же бессмысленно, как и создание двух интерфейсов, один из которых посылает одно сообщение, а второй - коллекцию.
                    Разве недостаточно одного эллипса? Круг ведь - просто эллипс, у которого совпадают фокусы.
                    Ответить
                    • Это известное противоречие, и у каждой из сторон есть сторонники и противники и т.д. Как бы нет смысла со мной по этому поводу спорить.
                      Что до интерфейсов - то это типичное мировозрение любителей Java. Мне интерфейс, как часть языка, престваляется объектом очень сомнительной полезности. И потому, что не решает полностью возложенных на него задач (способ определения типа по этикетке не описывает все возможные определения типа и, что еще хуже, плохо расширяется и дополняется). В данном случае я не вижу необходимости в создании более одного класса, который посылает сообщения, и не вижу никакой необходимости в интерфейсах, наследовании и т.д.
                      Ответить
                      • >Мне интерфейс, как часть языка, престваляется объектом очень сомнительной полезности
                        Видимо, вы не большой любитель юнит-тестирования.
                        Ответить
                      • И декораторы, фабрики и прочие вкусности, судя по всему, вам писать не приходилось. По своему опыту могу сказать, что интерфейсы чрезвычайно полезны и позволяют писать меньше кода, делая его в тоже время более гибким.
                        Ответить
                        • Спасибо, вы так смело подытожили мой жизненный опыт... :)
                          А если серьезно, вы вообще не поняли о чем речь. То есть на столько не поняли, что я затрудняюсь как-то иначе ответить.
                          Ответить
                          • > А если серьезно, вы вообще не поняли о чем речь
                            Что-то в последнее время вы часто остаётесь недопонятым.
                            http://govnokod.ru/7422#comment100869
                            Ответить
                            • Да, потому что речь шла о проблеме когда класс Warrior с существующим методом draw(sword) нужно расширить в классе Samurai в котором нужно имплементить интерфейс Artist с методом draw(picture). И в такой ситуации вы останетесь в пролете с вашими интерфейсами. Откуда вам в голову пришли мысли о том использовал ли я когда либо какие либо шаблоны в программировании - одному вам известно.
                              Ответить
                              • > Откуда вам в голову пришли мысли
                                > Мне интерфейс, как часть языка, престваляется объектом очень сомнительной полезности
                                Думаю, тут комментарии излишни.

                                Проблему примера с Warrior я не понял, ибо draw(Sword) и draw(Picture) имеют разные сигнатуры и могут быть в разных интерфейсах. Выглядит, конечно, не ахти, но явных проблем я не вижу. Если вы не можете ясно выразить свои мысли, лучше дайте ссылку на литературу.
                                Ответить
                              • Инструменты не обязаны быть хороши во всех ситуациях. Если в какой-то ситуации они не подходят, может, кто-то просто неправильно сделал выбор?
                                Ответить
                                • Вы спорите с христоматийными примерами. Этим проблемам уже по очень много лет, и очень много людей о них высказалось. Это как в анекдоте, когда в поезде уже тошнит рассказывать одни и те же анекдоты, и их по номеру вспоминают. Проблема интерфейса, если вкратце, заключается в том, что в естесственных языках одно и то же слово может обозначать разные вещи. Если вы в интерфейсе описали функцию, которая должна выполнять что-то, что соответствует одному из значений ее названия, существует вероятность, что вам в этом же классе нужно будет реализовать интерфейс к функции с таким же названием и ковариантными параметрами, но абсолютно другого назначения. Эту проблему нельзя решить никак - это как корень квадратный из -1. В другом виде, проблема возникает тогда, когда вы не можете планировать наперед: например, вы можете написать функцию: add(Point, Point) где Point - интерфейс с getX, getY. Но вы можете вполне себе столкнуться с ситуацией, когда вам нужно прибавить координаты прямоугольников - и, у них тоже будет getX, getY но они не наследуют тот же класс / не реализуют тот же интерфейс, что и Point. Если оба класса создавали вы - вы, возможно, сможете их поменять таким образом, чтобы они реализовывали один интерфейс. В реальной жизни - как правило вы не сможете это сделать.
                                  Ответить
                                  • Раз пример хрестоматийный, дайте ссылку, я почитаю. Я не спорю, что с интерфейсами могут быть гипотетические проблемы. Просто от этого они не перестают быть чрезвычайно полезными (как и многие другие виды программных контрактов). А вы утверждаете обратное.
                                    Слышали о теории множеств? Наивная теория множеств приводит к парадоксам. Но именно теория множеств стала основой современной математики.

                                    > Эту проблему нельзя решить никак - это как корень квадратный из -1
                                    i ^ 2 = -1

                                    Я так понял, что вы намекаете на динамическую типизацию, т.к. она, возможно, позволит избежать описанных вами проблем.
                                    Ответить
                                    • http://en.wikipedia.org/wiki/Circle-ellipse_problem

                                      Например...
                                      Корень из минус единицы потому и называется иррациональным, что иррациональный...
                                      Ответить
                                      • > Корень из минус единицы потому и называется иррациональным
                                        мнимый. Иррациональное число не представимо в виде отношения целых.
                                        Ответить
                                        • Это смотря в какой школе учились :) По другому определиню, иррациональное - то число, которое нельзя представить в виде дроби из двух целых чисел, и мнимое вполне может быть иррациональным. Это, кстати, еще один аргумент не в пользу иерархических структур для описания знаний.
                                          Ответить
                                          • Ваше определение иррационального числа ничем не отличается от моего, разве что моё короче. Если уж строго, то иррациональное число r непредставимо в виде p/q, где p и q являются целыми числами. Определения рациональных и иррациональных чисел относятся только к действительным числам, к комплексным они отношения не имеют.
                                            И, кстати, как раз типы чисел укладываются в строгую иерархию.
                                            Комплексные
                                               |
                                            Действительные
                                               |              \
                                            Рациональные     Иррациональные
                                               |                   |                  \
                                            Натуральные         Алгебраические  Трансцендентные
                                               |
                                            Целые

                                            Уж поверьте, в математике я кое-что смыслю.
                                            Ответить
                                            • Целые с натуральными местами перепутал, пока этот ASCII арт выводил. Striker, а можно предпросмотр замутить???
                                              Ответить
                                        • Ой, это уже я недосмотрел. Прошу прощения. Да. Напутал. Иррациональное - это вещественное число, которе нельзя представить в виде дроби. Так что вы правы, а я не прав в этом случае. Но это не меняет сути высказывания - корень из -1 не получить никак (собственно, как и корень из 2). Т.е. пример неразрешимой проблемы.
                                          Ответить
                                          • Корень из 2 не получить? Не смешите людей. Нарисуйте квадрат 1x1. Проведите у него диагональ. Её длина в точности равна корню из 2.
                                            Ответить
                                  • >я старался бы не создавать интерфейсы пока в этом нет необходимости
                                    Кстати, я так и не понял, причём здесь интерфейсы. Проблема возникает не из-за интерфейсов как таковых, а из-за того, что мир не укладывается в единственно правильную таксономию (что и ежу понятно). Вы призываете избегать интерфейсов как инструмента абстракции и объявлять всё обычными классами. Что никак не исправит описанной вами проблемы.
                                    Ответить
                                    • Пожалуйста не смешивайте. Перед нами три проблемы:
                                      - ненужный код (интерфейс призван решать определенные проблемы, которые в приведенной задаче не наблюдаются).
                                      - интерфейс плохо справляется с проблемами, которые он призван решать (в принципе).
                                      - класс выполняющий более узко-специфичную функцию является прототипом класса с менее специфичной функцией (отправить одно сообщение - это частный случай отправки множества сообщений).

                                      Последняя проблема может быть воспринята двояко (о чем и говорилось в сравнении с проблемой круг - эллипс). И, возможно, в каком-то свете и не проблема вовсе, но было это сказано с иронией по поводу того, как автор восхвалял прелести ОО в Java по сравнению с PHP, хотя, если по-честному, они не так уж и различаются... (и в этом конкретном случае ведут себя одинаково).
                                      Ответить
                                      • > ненужный код
                                        как тестировать зависимой код, если нельзя подложить в тесте реализацию-заглушку? Отсылать кому-то реальные СМС? Отнаследоваться и полностью переопределить методы суперкласса? бред.

                                        > интерфейс плохо справляется с проблемами, которые он призван решать
                                        он отлично справляется с проблемами, которые призван решать, а именно гарантировать, что программист предоставил реализации для методов, определённых в интерфейсе, и скрывать конкретную реализацию. Остальное на совести программиста.

                                        > класс выполняющий более узко-специфичную функцию является прототипом класса с менее специфичной функцией
                                        Вгляните на интерфейс Collection. У него есть методы add и addAll. Потому что создавать ещё один класс только чтобы предоставить add, вызывающий addAll - маразм.

                                        Итак, я вообще никаких проблем не вижу.

                                        > автор восхвалял прелести ОО в Java по сравнению с PHP
                                        не помню такого. в php даже все ключевые слова для ООП с java слизаны. php просто поощряет использование не-ООП практик. Причём не самых лучших. Поэтому новичок в java, пересевший с php, пишет далеко не самый лучший код.

                                        У меня складывается впечатление, что вы не особо глубоко вникали в ООП.

                                        P.S. Мне больше по душе функциональный стиль, но для каждой задачи нужен свой инструмент.
                                        Ответить
                                        • > автор восхвалял прелести ОО в Java по сравнению с PHP
                                          Извиняюсь, я понял, о чём вы. По глупости принял на свой счёт.
                                          Ответить
                                    • Автору нужна всего одна функция - интерфейсы и наследование не нужны. Наличие или отсутсвие интерфейсов на тестах в этом случае никак не отразится. Нормально - делать юнит тесты в классах наследниках тестируемого класса - вот там как хотите, так и извращайтесь, в коде, который будет просто выполнять задание заказчика тесты не то что не нужны, они вредны. И если в этот код напихать чего-то лишнего, то вы просто напишете менее качественный код, чем могли бы.

                                      Проблема померять эту диагональ... если продолжать в таком же шуточном духе - вы можете попробовать сделать линейку для того, чтобы эту диагональ измерять
                                      Ответить
                                      • > Нормально - делать юнит тесты в классах наследниках тестируемого класса
                                        Вы что, правда ТАК делаете? Не хотел бы я поддерживать ваш код. Вы используете наследование явно не по назначению.

                                        > Проблема померять эту диагональ
                                        Зачем вам её мерить? она в точности равна корню из двух.

                                        Думаю, дискуссия себя исчерпала.
                                        Ответить
                                        • Фотографию линейки, пожалуйста :)
                                          Ответить
                                          • На этой линейке будут деления: корень из двух см, два корня из двух см, три корня из двух см и т. п. Трудно что ли расчертить?
                                            Ответить
                                          • Имея линейку с единичными делениями, карандаш и циркуль (или угольник), можно построить отрезок длиной корень из 2 (3, 5, ...). Если нужно, можно отметить длину этого отрезка карандашом на линейке. И потом, к примеру, построить квадрат площади 2 (3, 5, ...).
                                            Учите матчасть, у меня нет больше ни малейшего желания объяснять такие вещи.
                                            Ответить
                                            • Я то при желании найду аттестат с отличием по начертательной геометрии и черчению, а вот фотографию такой линейки, которая бы могла иметь деление соответствующее корню из двух, пожалуй что нет... :)
                                              Может вы еще и правильный семиугольник построите заодно, ну, чтобы человечество освободить от еще одной, казалось бы неразрешимой проблемы? :D
                                              Ответить
                                              • Так отметьте это деление сами. В чём проблема?
                                                Ответить
                                                • Поверьте, если бы это было возможно... я не знаю, где вы с этим сталкивались на практике, а мне приходилось рассчитывать размеры цилиндров и печатных форм для флексографии, например. Эх, если бы были такие линейки... :)
                                                  Отметить можно только приблизительно - в этом и заключается проблема. Т.е. если у нас линейка будет в сантиметрах, дюймах или еще чем, то корень из двух сантиметров на ней никак не отметить. Обратное тоже справедливо - если у вас будет линейка, на которой вы бы отмечали только значения кратные корню из двух сантиметров, то целые или дробные значения в сантиметрах вы бы не могли точно отметить на той же линейке. Конечно, для каждой ситуации можно [попытаться] добиться результата с приемлимой точностью, но абсолютно точно - не получится.
                                                  Ответить
                                                  • wvxvw, вы как-то странно шаблонно мыслите
                                                    Ответить
                                                  • Что-то мне подсказывает, что даже отметка 2 сантиметра будет на линейке приблизительной.
                                                    Ответить
                                              • Я видел линейку даже с делением π! Логарифмическую.
                                                Ответить
                                            • Можно построить и более сложные отрезки — корень четвёртой степени, например.
                                              Ответить
                                              • На линейке есть деления, деление - это то, чего не может быть в иррациональном числе. При желании, 2 сантиметра можно представить точно. Корень из двух, на линейке, точно представить нельзя. А так - хоть бесконечность туда допишите... дописать-то, конечно, проблемы нет :) Для логарифмической линейки это не принципиально, потому что точность там особая и не требуется. А если, например, проектировать многоэтажное здание, или рассчитывать детали приборов, то разница становится очевидной. Например, синус представленный как 64-битное число с плавающей запятой не достаточно точен для того, чтобы рассчитать диаметр цилиндра или длину декеля для флексографической формы, хотя порядок, в котором описывается длина декеля, - нанометры.
                                                Ответить
                                                • Иррациональные числа не менее точны, чем целые. Это вам любой математик скажет.

                                                  Попробуйте представить 2 сантиметра точно дюймовой линейкой.

                                                  И я сомневаюсь, что вы держали в руках линейку, точность делений которых меньше 1e-17 (для сантиметровой это много меньше размера ядра атома).
                                                  Ответить
                                                  • Да не в этом дело... линейка состоит из делений, в которых нельзя по определению выразить иррациональное число. На практике это выражается в потере точности, когда вы оперируете формулами, где могут быть использованы иррациональные числа. Потому что линейка, как инструмент, не зависимо от своей точности (которая описывает на сколько одно деление на линейке совпадает с каким-то стандартом) не сможет точно (по отношению к тому же стандарту) представить иррациональное число. По-моему это объясняют на уроках алгебры в 6-7 классе...
                                                    Это невозможно потому, что что бы вы ни отметили на линейке будет целым числом каких-то минимальных ее составляющих. Иррациональные числа, по определению не могут быть представлены таким способом. Т.о. если у вас будет идеальная линейка, то, если вам нужно будет измерять что-то, что являестя рациональным числом по отношению к делению этой линейки, то, потери точности не будет. Но та же самая линейка не будет точно измерять то, что по отношению к делению этой линейки ялвяется иррациональным числом.
                                                    Ответить
                                                    • По-моему, вы несёте ахинею. Линейка есть объект непрерывный и отметку на ней можно поставить хоть в числе Эйлера, хоть в дзета-функции от трёх с точностью не меньшей, чем точность отметки с единичкой. А уж корень из двух на ней намалевать - дело вообще плёвое. Другое дело, что ни одно из этих чисел не будет (и не может) совпадать с отметками на стандартных делениях в сантиметрах и миллиметрах.
                                                      Ответить
                                                      • > с точностью не меньшей, чем точность отметки с единичкой
                                                        точность, однако, является также числом конечным, а для представления иррационального числа нужна бесконечная точность - таким образом, на линейке будет представлено рациональное число, с точностью до некоторого числа цифр после запятой совпадающее с нужным иррациональным.

                                                        ни один физический измерительный прибор не может быть бесконечно точен.

                                                        даже эталон килограмма и тот допускает минимальное отклонение веса.
                                                        Ответить
                                                    • To: wvxvw
                                                      Вы можете точно сказать, деления логарифмической линейки рациональны или иррациональны?
                                                      Ответить
                                                    • Мне кажется, вам нужно отойти и подумать. Одно дело троллить глупого ламера, а умного человека с временным заскоком — жалко.

                                                      Если линейка идеальная, то любое число, хоть целое, хоть иррациональное, хоть трансцендентное, на ней отложить можно (и «отложить число» — значит отложить отрезок, в определённое число раз отличающийся от единичного, а длина этого единичного может быть иррациональной относительно другого). Если же линейка реальная, физическая, то любая отметка нанесена на ней с определённой точностью, и единица не точнее корня с двух.
                                                      Ответить
                                      • > вы можете попробовать сделать линейку для того, чтобы эту диагональ измерять
                                        Магистро велемуро штангенциркуль членомеро
                                        Ответить
                              • Тогда нужно смотреть на иерархию и архитектуру классов и пересобрать кубик-рубика xD Если не сложно накидайте эти классы, чтобы пример был более живым =) Буду очень вам признателен.
                                Ответить
                            • О-о-о! Сколь открытий чудных во глубине комментов скрыто…
                              Ответить
                  • Беда в том, что необходимость в интерфейсе возникает тогда, когда менять уже поздно. Вот поэтому в Java предпочитают подстелить соломки заранее.
                    Ответить
                    • В случае с Java ею лучше стенки оббивать, чем разбрасывать где попало :)
                      Ответить
            • Просто из области общих знаний, все еще не опубликованных в Википедии: во Франции в 18-м веке, чтобы оформить официальный документ необходимо было обратиться к специально обученному писцу, который был, в теории, грамотнее и обладал более изящным почерком. Собственно, тогда же и появилось слово `каллиграфия'. Платили писцам за количество знаков в документе т.как каждый знак был произведением искусства. Кроме того, эстетика документов требовала чтобы последняя буква в строке имела либо выносной элемент (например, как в русской `у') либо открытую правую часть (как в русской `г'), чтобы, таким образом, можно было дополнить букву декоративным элементом заполняющим пустое пространство до поля. Таким образом во французском языке появилась куча слов с абсолютно неоправданно сложным написанием, и типичные для француского (и, впоследствии, для других романских языков) окончания на `е' которая никогда не читалась. В те времена строчаня кусривная `е' писалась так, что ее перекладину можно было продолжить вправо за пределы отведенные одному знаку. Аналогичная ситуация со словами оканчивающимися на непроизносимую `t' и т.п.
              Я надеюсь, вам хоть платят достойно за проделанную работу :) Иначе - себя пожалейте :)
              Ответить
            • Похоже, вы пересели на java с .net. Вас выдают наименования интерфейсов, начинающиеся с I, и Namespace вместо package =)
              Ответить
    • и почему никто не сказал, что можно обойтись без цикла, addAll?
      Ответить
    • показать все, что скрытоvanished
      Ответить

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