Ответы пользователя по тегу Java
  • Стоит ли полностью переходить на последнии версии JAVA (9, 10, 11)?

    @MaxLich
    java developer
    Можно, но если будете работать, то есть некоторая немаленькая вероятность, что там будет старая версия джавы. Переход на новые версии языков, библиотек и программ в интерпрайзе происходит довольно медленно.
    Ответ написан
    Комментировать
  • Как установить задержку на выполнение KeyListener?

    @MaxLich
    java developer
    Так что сложного. После первого нажатия блокируешь (деактивируешь) кнопку, одновременно запускаешь тред, который через указанный промежуток времени выполнить нужное действие. Кроме того, вместе с этим запускаешь ещё один тред, который ждёт указанный промежуток времени, а потом активирует эту кнопку.
    Ответ написан
    Комментировать
  • JAVA JDBC не удается получить одну запись из таблицы?

    @MaxLich
    java developer
    Если Вы действительно пытаетесь без вызова метода next() получить результат, то у Вас ничего не получится. Внутренний указатель ResultSet вначале стоит перед первой строкой. Так что в любом случает next() нужно вызывать.
    Ответ написан
    Комментировать
  • Почему не работает замена \n?

    @MaxLich
    java developer
    У вас реплейс вызывается у последней строки, то есть сначала выполняется такой код:
    "If-Modified-Since: Wed, 06 Jul 2016 07:58:20 GMT\n\n".replaceAll("\n", "E")

    "" - это объект типа String,
    replaceAll() - это его метод.
    Ваш код равносилен:
    MyClass myObj = new MyClass(); 
    System.out.println(myObj.replace().toString());
    Ответ написан
    Комментировать
  • Как на java сделать, генератор случайных букв и чисел?

    @MaxLich
    java developer
    Можно ещё завести массив или строку со всеми перечисленными буквами и цифрами. И уже случайным образом выбирать элемент этого массива или строки.
    Ответ написан
  • Как узнать сложность (количество переходов) в поиске по хэш таблице?

    @MaxLich
    java developer
    В идеальном случае - О(1), в худшем - О(n). В чём проблема?
    Ответ написан
    Комментировать
  • Как эффективно сгруппировать строки?

    @MaxLich Автор вопроса
    java developer
    Нашёл одно решение. Алгоритм:
    1. храним результат в виде списка списков: [номер_группы -> [строки_группы]]
    2. используем вспомогательный список хэш-таблиц: [позиция_слова -> { слово -> номер_группы }] и вспомогательную хэш-таблицу для хранения какая группа в какую была влита
    3. каждое слово строки ищем в соответствующей (позиции слова в строке) хэш-таблице
      а) если слово есть, запоминаем номер группы (значение из хэш-таблицы), в которой оно найдено
      б) если слова нет, то добавляем его в список новых слов
    4. если строка (а точнее её слова) найдена в группах, то берём первую из "живых" (объяснение этого позже) групп, иначе создаём новую группу
    5. добавляем новые слова в соответствующие хэш-таблицы с номером найденной/созданной группы
    6. объединяем найденные группы в одну, выбранную ранее. Так как группы хранятся в виде списка строк, то просто объединяем списки строк в один у выбранной группы, а более ненужные группы отмечаем как "мёртвые" (присваиваем null, дабы не перемещать элементы внутри списка)
    7. добавляем строку в список строк группы


    Код метода поиска групп:
    code
    private static List<List<String>> findLineGroups(List<String> lines) {
            class NewLineElement {
                private String lineElement;
                private int columnNum;
    
                private NewLineElement(String lineElement, int columnNum) {
                    this.lineElement = lineElement;
                    this.columnNum = columnNum;
                }
            }
    
            if (lines == null)
                return Collections.emptyList();
    
            List<List<String>> linesGroups = new ArrayList<>(); //список групп, каждый элемент вида "номер группы - список строк группы"
            if (lines.size() < 2) {
                linesGroups.add(lines);
                return linesGroups;
            }
    
            List<Map<String, Integer>> columns = new ArrayList<>(); // список стобцов, каждый столбец - мапа с парами "элемент строки/столбца-номер группы"
            Map<Integer, Integer> unitedGroups = new HashMap<>(); //мэп с парами "номер некоторой группы - номер группы, с которой надо объединить данную"
            for (String line : lines) {
                String[] lineElements = line.split(";");
                TreeSet<Integer> groupsWithSameElems = new TreeSet<>(); //список групп, имеющих совпадающие элементы
                List<NewLineElement> newElements = new ArrayList<>(); //список элементов, которых нет в мапах столбцов
    
                for (int elmIndex = 0; elmIndex < lineElements.length; elmIndex++) {
                    String currLnElem = lineElements[elmIndex];
                    if (columns.size() == elmIndex)
                        columns.add(new HashMap<>());
                    if ("".equals(currLnElem.replaceAll("\"","").trim()))
                        continue;
    
                    Map<String, Integer> currCol = columns.get(elmIndex);
                    Integer elemGrNum = currCol.get(currLnElem);
                    if (elemGrNum != null) {
                        while (unitedGroups.containsKey(elemGrNum)) // если группа с таким номером объединена с другой,
                            elemGrNum = unitedGroups.get(elemGrNum); //то сохраняем номер группы, с которой была объединена данная
                        groupsWithSameElems.add(elemGrNum);
                    } else {
                        newElements.add(new NewLineElement(currLnElem, elmIndex));
                    }
                }
                int groupNumber;
                if (groupsWithSameElems.isEmpty()) {
                    linesGroups.add(new ArrayList<>());
                    groupNumber = linesGroups.size() - 1;
                } else {
                    groupNumber = groupsWithSameElems.first();
                }
                for (NewLineElement newLineElement : newElements) {
                    columns.get(newLineElement.columnNum).put(newLineElement.lineElement, groupNumber);
                }
                for (int matchedGrNum : groupsWithSameElems) { //перебираем все группы с таким же элементом
                    if (matchedGrNum != groupNumber) {
                        unitedGroups.put(matchedGrNum, groupNumber); //сохраняем инф-цию об объединённых группах
                        linesGroups.get(groupNumber).addAll(linesGroups.get(matchedGrNum)); //объединяем группы
                        linesGroups.set(matchedGrNum, null); //помечаем группу с текущим номер, как несуществующую
                    }
                }
                linesGroups.get(groupNumber).add(line);
            }
            linesGroups.removeAll(Collections.singleton(null)); //удаляем несуществующие группы
            return linesGroups;
        }
    Ответ написан
    Комментировать
  • Как эффективно разбить множество строковых значений на непересекающиеся группы?

    @MaxLich
    java developer
    Нашёл одно решение. Алгоритм:
    1. храним результат в виде списка списков: [номер_группы -> [строки_группы]]
    2. используем вспомогательный список хэш-таблиц: [позиция_слова -> { слово -> номер_группы }] и вспомогательную хэш-таблицу для хранения какая группа в какую была влита
    3. каждое слово строки ищем в соответствующей (позиции слова в строке) хэш-таблице
      а) если слово есть, запоминаем номер группы (значение из хэш-таблицы), в которой оно найдено
      б) если слова нет, то добавляем его в список новых слов
    4. если строка (а точнее её слова) найдена в группах, то берём первую из "живых" (объяснение этого позже) групп, иначе создаём новую группу
    5. добавляем новые слова в соответствующие хэш-таблицы с номером найденной/созданной группы
    6. объединяем найденные группы в одну, выбранную ранее. Так как группы хранятся в виде списка строк, то просто объединяем списки строк в один у выбранной группы, а более ненужные группы отмечаем как "мёртвые" (присваиваем null, дабы не перемещать элементы внутри списка)
    7. добавляем строку в список строк группы


    Код метода поиска групп:
    code
    private static List<List<String>> findLineGroups(List<String> lines) {
            class NewLineElement {
                private String lineElement;
                private int columnNum;
    
                private NewLineElement(String lineElement, int columnNum) {
                    this.lineElement = lineElement;
                    this.columnNum = columnNum;
                }
            }
    
            if (lines == null)
                return Collections.emptyList();
    
            List<List<String>> linesGroups = new ArrayList<>(); //список групп, каждый элемент вида "номер группы - список строк группы"
            if (lines.size() < 2) {
                linesGroups.add(lines);
                return linesGroups;
            }
    
            List<Map<String, Integer>> columns = new ArrayList<>(); // список стобцов, каждый столбец - мапа с парами "элемент строки/столбца-номер группы"
            Map<Integer, Integer> unitedGroups = new HashMap<>(); //мэп с парами "номер некоторой группы - номер группы, с которой надо объединить данную"
            for (String line : lines) {
                String[] lineElements = line.split(";");
                TreeSet<Integer> groupsWithSameElems = new TreeSet<>(); //список групп, имеющих совпадающие элементы
                List<NewLineElement> newElements = new ArrayList<>(); //список элементов, которых нет в мапах столбцов
    
                for (int elmIndex = 0; elmIndex < lineElements.length; elmIndex++) {
                    String currLnElem = lineElements[elmIndex];
                    if (columns.size() == elmIndex)
                        columns.add(new HashMap<>());
                    if ("".equals(currLnElem.replaceAll("\"","").trim()))
                        continue;
    
                    Map<String, Integer> currCol = columns.get(elmIndex);
                    Integer elemGrNum = currCol.get(currLnElem);
                    if (elemGrNum != null) {
                        while (unitedGroups.containsKey(elemGrNum)) // если группа с таким номером объединена с другой,
                            elemGrNum = unitedGroups.get(elemGrNum); //то сохраняем номер группы, с которой была объединена данная
                        groupsWithSameElems.add(elemGrNum);
                    } else {
                        newElements.add(new NewLineElement(currLnElem, elmIndex));
                    }
                }
                int groupNumber;
                if (groupsWithSameElems.isEmpty()) {
                    linesGroups.add(new ArrayList<>());
                    groupNumber = linesGroups.size() - 1;
                } else {
                    groupNumber = groupsWithSameElems.first();
                }
                for (NewLineElement newLineElement : newElements) {
                    columns.get(newLineElement.columnNum).put(newLineElement.lineElement, groupNumber);
                }
                for (int matchedGrNum : groupsWithSameElems) { //перебираем все группы с таким же элементом
                    if (matchedGrNum != groupNumber) {
                        unitedGroups.put(matchedGrNum, groupNumber); //сохраняем инф-цию об объединённых группах
                        linesGroups.get(groupNumber).addAll(linesGroups.get(matchedGrNum)); //объединяем группы
                        linesGroups.set(matchedGrNum, null); //помечаем группу с текущим номер, как несуществующую
                    }
                }
                linesGroups.get(groupNumber).add(line);
            }
            linesGroups.removeAll(Collections.singleton(null)); //удаляем несуществующие группы
            return linesGroups;
        }
    Ответ написан
  • Как влияет импорт библиотек из пакета на производительность и размер байт кода Java?

    @MaxLich
    java developer
    Никак не влияет. Это просто указание компилятору и JVM, где брать нужные классы.
    Ответ написан
    Комментировать
  • Как добавить изображение на панель?

    @MaxLich
    java developer
    Хм, у меня сейчас в рабочем проекте такой код.
    Код создания метки для фото:
    JLabel photo = new JLabel();
                Icon icon = loadPhoto(editingRecord == null ? "" : editingRecord.getPhotoBase64());
                photo.setIcon(icon);


    Метод loadPhoto():
    private Icon loadPhoto(String base64String) {
            if (isBlank(base64String)) {
                return null;
            }
    
            byte[] bytes = DatatypeConverter.parseBase64Binary(base64String);
            ByteArrayInputStream bin = new ByteArrayInputStream(bytes);
            try {
                BufferedImage original = ImageIO.read(bin);
    
                if (original == null || original.getHeight() == 0) {
                    return null;
                }
    
                double factor = 100.0 / original.getHeight();
    
                int newWidth = new Double(((double) original.getWidth()) * factor).intValue();
                int newHeight = 100;
    
                BufferedImage resized = new BufferedImage(newWidth, newHeight, original.getType());
                Graphics2D g = resized.createGraphics();
                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                        RenderingHints.VALUE_INTERPOLATION_BILINEAR);
                g.drawImage(original, 0, 0, newWidth, newHeight, 0, 0, original.getWidth(),
                        original.getHeight(), null);
                g.dispose();
    
                return new ImageIcon(resized);
            } catch (Exception e) {
                logger.error(LogHelper.print("Can't load photo preview for employee", e));
                MessageDialog.showError(this,
                        Global.data().getString("ERROR_READING_EMPLOYEE_PHOTO"),
                        Global.data().getString("ERROR_TITLE"));
            }
    
            return null;
        }
    Ответ написан
    Комментировать
  • Как очистить панель JPanel?

    @MaxLich
    java developer
    Попробуйте сначала вызывать метод removeAllItems(), а потом repaint() и revalidate(). Насколько помню, у меня так работало (именно эти три метода, и именно в таком порядке).
    Ответ написан
    1 комментарий
  • Как отобразить иерархию должностей в виде дерева для Swing JTree?

    @MaxLich
    java developer
    Можете глянуть мою прогу на гитхабе: ссылка
    Собственно код с функцией добавления узлов в модель:
    код
    public class MainModel extends Model {
        private String extensionOfFiles;
        private String textToFind;
        private boolean matchCase;
    
        @Override
        public void loadFileTree(Path sourceDir, String extensionFiles, String textToFind, boolean matсhCase) {
    
            this.extensionOfFiles = extensionFiles;
            this.textToFind = textToFind;
            this.matchCase = matсhCase;
    
            DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode(sourceDir,true);
    
            addChildrenNodes(rootNode,sourceDir);
            deleteAllEmptyBranches(rootNode);
    
            TreeModel treeModel = new DefaultTreeModel(rootNode,true);
    
            setChanged();
            notifyObservers(treeModel);
        }
    
        //ищет и добавляет "детей" узлам дерева
        private void addChildrenNodes(DefaultMutableTreeNode rootNode, Path sourceDir) {
            try (DirectoryStream<Path> stream = Files.newDirectoryStream(sourceDir)) {
                for (Path path: stream) {
                    if (Files.isRegularFile(path)) {
                        String fileName = path.getFileName().toString().toLowerCase(); //имя файла в нижнем регистре
                        if (fileName.endsWith("."+extensionOfFiles) && isFileContainsText(path)) //если файл имеет нужное расширение и содержит искомый текст
                            rootNode.add(new DefaultMutableTreeNode(new PathContainer(path),false)); //то добавляет его в дерево
                    } else if (Files.isDirectory(path)) {
                        File[] listFiles = path.toFile().listFiles();
                        if (listFiles == null || listFiles.length == 0) continue;
                        DefaultMutableTreeNode newChild = new DefaultMutableTreeNode(new PathContainer(path), true);
                        rootNode.add(newChild); //добавляем папку в дерево
                        addChildrenNodes(newChild,path); //рекурсивный вызов метода с данной папкой и данным узлом в качестве параметров
                    }
                }
            } catch (IOException | DirectoryIteratorException x) {
                System.err.println(x);
            }
        }
    
        //метод проверяет, содержит ли файл  искомый текст
        private boolean isFileContainsText(Path file) throws IOException {
            try {
                List<String> fileContent = Files.readAllLines(file);
                if (matchCase) {
                    for (String str : fileContent) {
                        if (str.contains(textToFind)) {
                            return true;
                        }
                    }
                } else {
                    for (String str : fileContent) {
                        if (str.toLowerCase().contains(textToFind.toLowerCase())) {
                            return true;
                        }
                    }
                }
            } catch (MalformedInputException e) {}
    
            return false;
        }
    
        //метод очищает дерево от пустых веток (содержащих одни пустые каталоги)
        private void deleteAllEmptyBranches(DefaultMutableTreeNode currNode) {
            if (currNode == null) return;
            Enumeration<DefaultMutableTreeNode> children = currNode.children();
            if (children == null || !children.hasMoreElements()) return;
    
            Queue<DefaultMutableTreeNode> queue = new LinkedList<>();
    
            while (children.hasMoreElements()) {
                DefaultMutableTreeNode child = children.nextElement();
                if (child.getAllowsChildren())    //если это каталог, то добавляем его в очередь
                    queue.add(child);
            }
    
            while (!queue.isEmpty()) {
                DefaultMutableTreeNode node = queue.poll();
                if (node == null)  continue;
                if (node.getAllowsChildren()) {
                    if (node.isLeaf()) {
                        DefaultMutableTreeNode parent = (DefaultMutableTreeNode) node.getParent();
                        node.removeFromParent();
                        if (queue.contains(parent) || parent == null) continue; // если родитель этого узла уже есть в очереди
                                                                                // или он равен нулл, то ничего не делаем
                        queue.offer(parent); //иначе добавляем его в очередь
                    } else {
                        children = node.children();
                        while (children.hasMoreElements()) {
                            DefaultMutableTreeNode child = children.nextElement();
                            if (child.getAllowsChildren() && !queue.contains(child))    // если это каталог и его ещё нет в очереди, то...
                                queue.add(child);                         // добавляем его в очередь
                        }
                    }
                }
            }
    
    
        }
    }
    Ответ написан
    Комментировать
  • Не работает сторонняя бибиотека в сборке, как исправить?

    @MaxLich
    java developer
    Перейти на нормальную систему сборки, которая сама разрешает зависимости (мейвен или грейдл)
    Ответ написан
    Комментировать
  • Легкий вопрос по теории ООП. Создание экземпляра класса в этом же классе?

    @MaxLich
    java developer
    Такое применяется в некоторых паттернах (синглтон, фабрика и прочее), также для тестирования класса можно в нём объявлять метод main() и в теле этого метода создавать экземпляр этого класса и работать с ним. Но это больше подходит для небольшого тестирования (разового) и для небольших учебных программ, в серьёзных продакшн-проектах так делать не нужно.
    Ответ написан
    Комментировать
  • Вывод данных со всех листов наследниках?

    @MaxLich
    java developer
    Пока приходит в голове такое: объявить лист в суперклассе, в наследниках его заполнять. В каком-то внешнем классе (который не входит в эту иерархию) создать список наследников суперкласса, и потом в цикле всех их перебирать и добавлять элементы из их списков в общий список.

    ЗЫ Единственное тут возникает вопрос с типами элементов. Если для всех товаров используется один класс (то есть у них у всех одинаковые характеристики), то можно сразу список и типизировать этим классом. Иначе можно сделать суперкласс дженериком, и в каждом наследнике определять тип товара; правда, тогда все типы товаров должны иметь общего наследника (или общий интерфейс), т.д.. ...
    Ответ написан
    Комментировать
  • Почему так работает побитовый сдвиг?

    @MaxLich
    java developer
    В первом случае происходит переполнение, поэтому получается отрицательное число, а вот по второму случаю сходу так ничего не могу сказать.
    Ответ написан
    Комментировать
  • Как прописывать пути к шрифтам и картинкам в файлах шаблонов JasperReports?

    @MaxLich Автор вопроса
    java developer
    Помог такой путь: "config/font/ARIAL.TTF", правда, файл находится в главном проекте, что не очень логично и удобно. Но в той папке уже был какой-то шрифт, значит, такое уже практикуется (проект не мой, я на такой пришёл).
    Ответ написан
    Комментировать
  • Как правильно работать с данными из файла?

    @MaxLich
    java developer
    Ещё добавлю, что данные лучше хранить в базе, а не в файлах.
    Ответ написан
    Комментировать
  • Как в Swing получать ширину кнопки выпадающего списка JComboBox?

    @MaxLich Автор вопроса
    java developer
    В итоге решил свою проблему, вызывая метод "public void setPrototypeDisplayValue(E prototypeDisplayValue)" у объекта классы JComboBox. Это конечно, не ответ на вопрос, который я задал, но позволяет решить изначальную проблему, из-за которой мне и пришлось задать этот вопрос.
    Ответ написан
    Комментировать
  • Философия Java - что дальше?

    @MaxLich
    java developer
    Если чисто по новым особенностям языка, то можно ещё (кроме того, что описал Сергей Горностаев) почитать книжки Хорстманна (последнее издание библиотеки профессионала, а также его книги чисто по Java 8). А если вообще - то "Эффективное программирование" Джошуа Блоха.
    Ответ написан
    Комментировать