Задать вопрос
Ответы пользователя по тегу Java
  • Как работает стирание типов?

    @Mercury13
    Программист на «си с крестами» и не только
    Потому что в коде
    Pair emp = person;
    …не угадываются шаблонные параметры, а просто берётся Pair<Object>.
    Ответ написан
    Комментировать
  • Как именовать два метода один из которых выбрасывает исключение?

    @Mercury13
    Программист на «си с крестами» и не только
    findById и requireById.
    В данном случае.
    Ответ написан
    Комментировать
  • Почему String.codePointCount() возвращает 2 для символа ©?

    @Mercury13
    Программист на «си с крестами» и не только
    Он не прав.
    Второй символ не пробел, а селектор начертания 16.
    Используется во многих символах базовой плоскости, чтобы превратить их в эмодзи.
    А уж в символах двойного назначения — и типографский, и эмодзи — и подавно.
    67253fc645640534308923.png
    Ответ написан
    Комментировать
  • Правильно ли вынесение метода проверки в другой сервис для упрощения тестирования?

    @Mercury13
    Программист на «си с крестами» и не только
    check1() иногда годится, если проверка многократно выполняется в разных функциях, по принципу «не повторяйся». Например, для const-корректности Си++, или для хитрых интерфейсов, когда есть objectId(i), objectName(i).

    А так зачем: тестирования с виду не упростит, ведь мы должны убедиться, что интерфейс верно реализован и действительно некорректные наборы данных (все или хотя бы некоторые) не проходят.

    UPD. Вынесение РАЗОВОЙ функциональности (если это реакция на некорректные данные, конечно) в отдельную функцию КРАЙНЕ РЕДКО делает код более тестопригодным: может быть, что реакция на некорректности так размыта, что вызов основной функции мало что даст. Может, реакция на некорректности так сложна, что стоило бы её проверить отдельно. Ну ХЗ, в большинстве случаев бессмысленно.

    UPD2. Тестируемость кода — это в первую очередь возможность выделить функциональность для тестирования и не тащить вместе с ней половину программы.
    Ответ написан
    Комментировать
  • Для чего нужен слой сервиса без логики?

    @Mercury13
    Программист на «си с крестами» и не только
    Нет, для автоматического построения связей Spring’ом.
    Почему-то этот товарищ сделал эту штуку очень тонкой обёрткой над предметной логикой: то ли имя findWriteLockedByName не нравится, то ли не знал, будет сделана служба на Spring или на чём-то другом.
    Ответ написан
    Комментировать
  • Как сравнить два списка с помощью хеш-кода?

    @Mercury13
    Программист на «си с крестами» и не только
    1. Реализация из Java8:
    public int hashCode() {
        int hashCode = 1;
        for (E e : this)
            hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
        return hashCode;
    }

    Из неё видно, что не совпало — у одинаковых списков хэши одинаковые. Но вспомни комбинаторику: если хэши одинаковы, объекты, СКОРЕЕ ВСЕГО, одинаковые, и один хрен нужно глубокое сравнение. Если разные — точно разные.

    2. Если просто сравнить два списка — сравнивай обычным equals, ничего ты не выиграешь от хэшей. Один хрен для вычисления хэша придётся пройти по всем данным. Хэши используй, если нужно сравнить, например, 100 объектов попарно — я так сжимал WAD’ы для Doom без потерь и рассинхронизаций демо-роликов. Сначала находил множества потенциально равных блоков, потом вёл глубокое сравнение.
    Ответ написан
    5 комментариев
  • Как использовать RATE_VERY_FAST (Java, Android)?

    @Mercury13
    Программист на «си с крестами» и не только
    Давайте посмотрим, что представляет собой RATE_XXX и SENSOR_DELAY_XXX.
    SENSOR_DELAY_FASTEST = 0
    SENSOR_DELAY_GAME = 1
    SENSOR_DELAY_UI = 2
    SENSOR_DELAY_NORMAL = 3

    RATE_STOP = 0
    RATE_NORMAL = 1
    RATE_FAST = 2
    RATE_VERY_FAST = 3

    Функция registerListener требует задержку в мкс, или одну из четырёх констант SENSOR_DELAY. Поставив RATE_VERY_FAST=3, вы реально поставили ему SENSOR_DELAY_NORMAL=3!

    А куда же совать RATE? В SensorDirectChannel.configure! А сам SensorDirectChannel можно получить через SensorManager.createDirectChannel! Вот как-то так — и даже понимаю, откуда такая архитектура. Ну не может система, оптимизированная под низкое энергопотребление, 1700 раз в секунду пинать пользовательскую программу — программа получает управление намного реже, а информация с акселерометра накапливается в буфере памяти.

    UPD. Есть и вторая причина. Обработка может затянуться более чем на 1/1700 секунды, и в это время датчик продолжит писать информацию в тот самый буфер.

    UPD2. Другими словами, через callback и через буфер в памяти — две разных архитектуры. Первая обеспечит низкую задержку. Вторая — высокую (причём стабильно высокую!) частоту опроса, но задержка от регистрации до обработки, скорее всего, будет побольше.
    Ответ написан
    2 комментария
  • Ковариантность возвращаемых типов в Javа, я правильно понял суть?

    @Mercury13
    Программист на «си с крестами» и не только
    Ковариантность начинается, когда мы делаем class BuildCircle extends BuildShape.
    (Лучше BuildShape оформить как интерфейс, а не как класс, но шут с ним.)

    Ковариантность связана с принципом подстановки Лисков: чтобы потомок вписывался в контракт, установленный предком, он может ужесточать требования к себе (скажем, выдавать более узкий тип) и ослаблять требования к другим (скажем, принимать поток реального времени вроде консоли/сокета — а не только файл, который знает себе длину и позволяет перемотку).

    Вот это «выдавать более узкий тип, чем полагает предок» — и есть ковариантность.

    Обратное — принимать поток реального времени, а не только файл — называется контравариантность. Насколько мне известно, в Java на уровне языка её нет, но какие-то части ухитряются делать через шаблоны.
    Ответ написан
    3 комментария
  • Почему у строк всегда одиноковый hashcode()?

    @Mercury13
    Программист на «си с крестами» и не только
    String str1 = "Hello";
    String str2 = "Hello";

    Тут одна и та же ссылка. Но даже если сделать их разными объектами, всё будет аналогично.

    Начнём с того, что такое хэш-код. Если объекты равны, их хэш-коды гарантированно равны. Если не равны — то хэш коды, скорее всего (но не обязательно!) не равны. А теперь — о том, что такое «равные объекты».

    Изначально равенство объектов проверяется просто: никакие два объекта не равны, объект равен самому себе и никому больше. В таком случае естественно каким-то образом построить хэш-код из адреса.Для строк это не так, и функция hashCode() переписана, чтобы учитывала данные внутри, а не адрес.

    (Почему говорю «каким-то образом» — при определённом устройстве хэш-таблицы, если брать просто адрес, часть гнёзд будут простаивать. Так что устройство хэш-функции и хэш-таблицы надо согласовать, чтобы таблица заполнялась равномерно.)
    Ответ написан
    6 комментариев
  • Стоит ли плагину доверят писать unit-тесты?

    @Mercury13
    Программист на «си с крестами» и не только
    Проверим один тест.
    // Какую концепцию проверяем?
       // Это не просто проверка функции ListAll, это проверка какой-то концепции кода
       // Варианты.
       // 1. Пустой listAll() даёт пустой список.
       // 2. Непустой listAll() даёт непустой список.
        void testListAll() {
            ArrayList<Product> productList = new ArrayList<Product>();
            // Проводим поиск в списке — что в этот список вносится?
            // И не будет ли физической зависимости тестов друг от друга?
            // И для чего вообще нужен этот search, если мы listAll тестируем?
            // Что такое ProductRepository и он вообще проверен?
            when(this.productRepository.search((String) any())).thenReturn(productList);
            // Ну, хорошо.
            List<Product> actualListAllResult = this.productService.listAll("Keyword");
            // Отказ, они не same: первый мы только что создали, а второй откуда-то пришёл.
            assertSame(productList, actualListAllResult);
            // Получается, что концепция — поиск, когда ничего не находится?
            assertTrue(actualListAllResult.isEmpty());
            verify(this.productRepository).search((String) any());
            // Получается, единственная концепция, которую мы тестируем,— поиск в пустом списке даёт пустоту
            // (и та некорректная из-за assertSame).
            assertTrue(this.productService.getAll().isEmpty());
        }


    Ну что, понятно, что или фтопку такие инструменты, или нужно их серьёзно осваивать, прежде чем будут приносить хоть какие-то результаты?
    Ответ написан
    Комментировать
  • Что значит после класса?

    @Mercury13
    Программист на «си с крестами» и не только
    Шаблонный класс.
    Гугли «Java Generics»

    String — Input parameter type
    Integer — progress report type
    String — result parameter type
    Ответ написан
    Комментировать
  • Почему финализированные классы в исходниках java имеют private конструкторы?

    @Mercury13
    Программист на «си с крестами» и не только
    Ничем особенным. Просто библиотечные функции сильнее защищают от «нештатного» использования.
    Ответ написан
    Комментировать
  • Почему не проходит запрос из-за foreign key?

    @Mercury13
    Программист на «си с крестами» и не только
    Подозреваю глюки с кодировками. В проге-админке работает?
    Ответ написан
    Комментировать
  • Зачем нужны интерфейсы при реализации внедрения зависимостей?

    @Mercury13
    Программист на «си с крестами» и не только
    Если предположить, что у интерфейса А всего одна реализация…
    1. Если объект А сам ссылается на объект Б — чтобы эти объекты не были единым комком, которые можно втянуть в проект только вместе.
    2. Чтобы ускорить перекомпиляцию при изменениях в объекте А.

    Но у интерфейса может быть и много реализаций, тогда…
    3. Чтобы сделать специальную версию А для модульных тестов объекта Б.
    4. Чтобы проще было расширять код или переносить модуль из проекта в проект: например, один и тот же упаковщик, принимающий на вход абстрактный поток, может работать хоть с файлами, хоть с сетью.
    Ответ написан
    Комментировать
  • Почему цикл do-while работает странно?

    @Mercury13
    Программист на «си с крестами» и не только
    1. in.read() читает один байт.
    2. Введённые вами f и ВВОД остаются в буфере.
    3. Данные передаются в поток, когда вы нажтмаете ВВОД.
    Потому первый раз читает f, второй раз — забуферизированный ВВОД.
    Используйте java.util.Scanner, который позволит считывать строчку целиком.
    Или, на худой конец, пропустите забуферизированные байты System.in.skip(System.in.available());
    Ответ написан
    4 комментария
  • Как правильно связывать между собой разные интерфейсы?

    @Mercury13
    Программист на «си с крестами» и не только
    Тут лучше всего использовать шаблонные классы.
    interface Collection <T> {}
    class PeopleCollection implements Collection <Person> {}
    Ответ написан
    Комментировать
  • Почему именно такое отношение между классами ( Trip has Airplane)?

    @Mercury13
    Программист на «си с крестами» и не только
    Очевидно, тут имеется в виду жизнь аэропорта в динамике. То есть не заполнить его данными и замолкнуть, а вести вылеты-прилёты, сажать пассажиров в самолёты и т.д.
    Trip — это маршрут, и в одном самолёте могут ехать несколько маршрутов (например, с посадками, или рейс вообще чартерный и несколько турагентств заполняют самолёт).
    Ответ написан
    Комментировать
  • Что такое совпадение множеств?

    @Mercury13
    Программист на «си с крестами» и не только
    Совпадают множества — это, собственно, равны как множества. Другими словами, равны, если исключить повторы и отсортировать в каком-нибудь порядке.
    Например, { 1, 2, 3 } = { 3, 3, 2, 1, 2, 1 }.
    Ответ написан
    Комментировать
  • Почему используют interface a не abstract class?

    @Mercury13
    Программист на «си с крестами» и не только
    И первое, и второе имеет право на жизнь.

    Второе действительно используется чаще: у нас есть готовая или полуготовая кнопка, и надо добавить в неё функциональность Нашей Крутой Кнопки™. К тому же слова вроде Clickable лучше подходят для названий интерфейса, чем Button.
    class Button {
      protected void paint(Canvas aCanvas) {}
    }
    
    class MyButton extends Button {
      @Override
      protected void paint(Canvas aCanvas) {}
    }


    А первое — например, мы хотим с Нашей Крутой Кнопкой™ работать как с кнопкой неизвестной функциональности, которая умеет только нажиматься и говорить, в каком она состоянии.
    interface Button {
      void press();
      boolean state();
      void addListener(ButtonListener x);
    }
    
    class GameObject {
      void paint(Renderer renderer);
    }
    
    class MyButton extends GameObject implements Button {
    }
    
    class FridgeGame implements ButtonListener {  // помните, такая была в «Братьях Пилотах»?
      Button buttons[][] = new MyButton[4][4];  
    }
    Ответ написан
    Комментировать
  • Как составить список пути используя алгоритм BFS?

    @Mercury13
    Программист на «си с крестами» и не только
    Вместо
    boolean[][] visited = new boolean[ROW][COL];

    надо сделать такое:
    static final byte DIR_UNKNOWN = 0;
    static final byte DIR_UP = 1;
    ...
    
    byte[][] bestDirection = new boolean[ROW][COL];  // изначально заполнено DIR_UNKNOWN


    for (int dir = DIR_UP; dir <= DIR_RIGHT; ++dir) {
      ...
      bestDirection[row][col] = dir;
    }

    Добравшись до финиша, делаем обратный ход. А именно: определяем, какой bestDirection у финиша, и если он, например, DIR_UP — смещаемся на 1 вниз. И так далее, пока не доберёмся до старта.

    Если финишей много — возможно, лучше будет начинать с них, внеся их в очередь в случайном порядке. А потом, когда поиск доберётся до старта, сделать обратный ход.
    Ответ написан
    Комментировать