Ответы пользователя по тегу Java
  • Как оганизовать функционал, при добавлении комментария под книгой сообщение о добавлении комментария должно всплывать всем подключённым пользователям?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Необходимо добавить метод для отправки сообщения всем подключенным клиентам при добавлении нового комментария.

    public void sendCommentToAllClients(Comment comment) {
        if (ns != null) {
            ns.broadcast("comment:save", comment);
        }
    }


    После сохранения комментария, необходимо отправить его через SocketEmitter всем клиентам.

    @PostMapping("/add-comment")
    public ResponseEntity<Comment> addComment(@RequestBody BookResponse reqBody, Authentication authentication) {
        try {
            // (...)
            commentRepository.save(comment);
    
            // Отправляем комментарий всем подключенным клиентам
            socketEmitter.sendCommentToAllClients(comment);
    
            return ResponseEntity.status(HttpStatus.OK).body(comment);
        } catch (Exception ex) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .build();
        }
    }


    Вы уже реализовали прослушивание события comment:save на клиенте, поэтому необходимо только убедиться, что данные обрабатываются корректно.

    useEffect(() => {
        socket.on('comment:save', (data: Comment) => {
            const comment = JSON.parse(data as any)
            console.log('comment', comment);
            props.book.comments.push(comment);
            // Если setBookInState обновляет состояние, это может быть полезно для перерисовки
            // props.setBookInState({...props.book}); 
            toast.info('Got event from socket: Book ' + comment.text)
        });
    }, [socket]);
    Ответ написан
  • Почему @ModelAttribute возвращает значение только одной колонки?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Когда вы используете атрибут disabled для<input>, значение этого поля не отправляется на сервер вместе с другими данными формы. Таким образом, при отправке формы, поля с атрибутом disabled будут игнорироваться.

    В вашем коде, поле *{settings[__${item.index}__].name} установлено как disabled, и поэтому name всегда будет null при обработке POST-запроса на сервере.

    Чтобы решить эту проблему, вы можете использовать дополнительное скрытое поле для передачи значений, которые не предназначены для редактирования пользователем, например

    <td>
        <input disabled th:value="*{settings[__${item.index}__].name}">
        <input type="hidden" th:field="*{settings[__${item.index}__].name}">
    </td>
    Ответ написан
  • Как посчитать звёзды на небе?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Здесь можно посмотреть решение, выполненное на Python. Здесь репозиторий проекта. Чисто в практических целях можете реализовать то же с Java, никакая нейросеть вам для этого не нужна. Желаю удачи.
    Ответ написан
    1 комментарий
  • Как проверить список на введенное слово из input и вывести количество сходств?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Scanner input = new Scanner(System.in);
            String[] list = new String[4];
            System.out.println("Insert list elements: ");
            for (int i = 0; i < list.length; i++) {
                list[i] = input.nextLine();
            }
            System.out.print("Inserted list elements: ");
            for (String s : list) {
                System.out.print(" " + s);
            }
            System.out.print("Ввод нужного адреса: ");
            String address = input.nextLine();
            long count = IntStream.range(0, list.length).filter(i -> address.equals(list[i])).count();
            System.out.println(count);
    Ответ написан
    2 комментария
  • Как распарсить текстовый документ на java?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Вы можете использовать регулярные выражения для поиска нужной вам информации. Например, для поиска чисел в тесте вы можете использовать следующее решение:

    Pattern p = Pattern.compile("[0-9]+");
    Matcher m = p.matcher("string1234(((more56))7))string890");
    while (m.find()) {
        System.out.println(m.group()); //1234 56 7 890
    }
    Ответ написан
  • Как усовершенствовать код, чтобы можно было работать со знаками препиания?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Вы можете использовать просмотр вперед и просмотр назад, которые являются функциями регулярных выражений.
    Вы даже можете поместить плейсхолдеры, например %1$s и использовать String.format для замены плейсхолдеров на фактическую строку, которую вам нужно использовать.

    Простое решение для Java 8 и новее:

    public class Main {
        public static final String DELIMITER = "((?<=%1$s)|(?=%1$s))";
    
        public static void main(String[] args) {
            String task = "Заменить, в тексте все! слова длиной? не больше 6 символов; в обратном порядке начинающиеся на: согласную букву ";
            String[] arr = task.split(String.format(DELIMITER, "[:?;!. ]"));
            String result = Arrays.stream(arr)
                    .map(s -> !check(s.charAt(0)) && !length(s) ? reverse(s) : s)
                    .collect(Collectors.joining());
            System.out.println(result); /* Заменить, в етскет есв! аволс йонилд? ен ешьлоб 6 символов; в обратном порядке начинающиеся ан: согласную увкуб */
    
        }
    
        public static boolean check(char c) {
            return "аиеёоуыэюя".indexOf(c) > -1;
        }
    
        public static boolean length(String s) {
            return s.length() > 6;
        }
    
        public static String reverse(String s) {
            return new StringBuilder(s).reverse().toString();
        }
    }
    Ответ написан
    Комментировать
  • Как удалить из hashmap все элементы с одинаковым значением?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Использовать HashSet, если использование HashMap не обязательное условие задачи.
    Ответ написан
    2 комментария
  • Как узнать какие версии библиотек установлены в Java проекте?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Библиотеки могут быть добавлены в проект как в виде java-архива вручную, так и управляться системой автоматической сборки проектов по типу maven/gradle/ant. Делают абсолютно то же самое, а именно добавляют java-архивы в раздел "External Libraries" вашего проекта, в названии самого архива как правило указывается версия этой библиотеки, либо если вы пользуетесь системой авто-сборки, то версия библиотеки указывается в разметке при ее добавлении.
    Ответ написан
    Комментировать
  • Какой из бесплатных курсов посоветуете пройти?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Согласен с Dmitry Roo в плане литературы. Насчет Javarush не уверен. Да, там все на русском. Да, концепт прикольный, без нудятины + дополнительный материал в виде статей от пользователей. Но проект позиционирует себя как обучающий портал с большим количеством практических задач, которые как по мне расчитаны на механическое заучивание основ, но никак не на понимание того, как оно работает. Во многих задачах, особенно тех, где требуется написать клон какой-либо старой игры за тебя дописывают часть кода, что как по мне не очень хорошо, если речь идет об обучении. Пусть код будет плохой или вообще неправильный, но ты потратишь время и найдешь в чем была ошибка, тем самым поняв, почему она вообще возникла. Hyperskill от Jetbrains в этом плане гораздо лучше + 2 месяца бесплатного обучения с доступом к любым проектам и разделам. Но опять же все это сугубо индивидуально. Лучший способ научиться чему-то - поставить себе задачу и копать материал для решения этой задачи.
    Ответ написан
    Комментировать
  • Как поменять элементы массива?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Простое решение с использованием Stream API:
    public static void main(String[] args) {
            int[] array = {1, 2, 3, 4, 5};
            int[] result = IntStream.rangeClosed(1, array.length)
                    .map(i -> array[array.length - i])
                    .toArray();
            System.out.println(Arrays.toString(result));
        }


    Еще проще с использованием класса Collections, интерфейса List и обертки над примитивом int:
    public static void main(String[] args) {
            Integer[] array = {1, 2, 3, 4, 5};
            List<Integer> list = Arrays.asList(array);
            Collections.reverse(list);
            System.out.println(Arrays.toString(list.toArray()));
        }


    Если не нравятся предыдущие варианты, то можно по классике:
    public static void main(String[] args) {
            int[] array = {1, 2, 3, 4, 5};
            for (int i = 0; i < array.length / 2; i++) {
                int tmp = array[i];
                array[i] = array[array.length - 1 - i];
                array[array.length - 1 - i] = tmp;
            }
        }
    Ответ написан
    Комментировать
  • Как работает рекурсия в Java?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Когда вы вызываете метод из другого метода, то вызывающий метод приостанавливается в частично завершенном состоянии. Все значения переменных вызывающей функции физически сохраняются в памяти. Метод, вызванный вызывающим его методом размещается поверх вызывающего метода и происходит все то же самое, пока соблюдается рекурсивный случай (условие, при котором метод вызывает сам себя). Когда происходит базовый случай (условие, при котором рекурсия должна быть остановлена), методы по очереди возвращают управление вызвавшему их методу, вплоть до полного завершения исходного (самого нижнего) метода.
    Ответ написан
    Комментировать
  • Зачем json считывать через Scanner?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Зачем считывать файл через Scanner?


    С помощью класса Scanner вы можете читать данные из файла точно так же, как и с помощью BufferedReader'а, BufferedInputStream'а и других классов, способных читать файловые данные. Почему же здесь использовали Scanner известно только тому, кто написал этот класс, потому что есть более подходящие классы для подобных операций.

    Зачем использовать цикл? нельзя взять и всю прочитать без цикла?


    Поскольку это универесальный класс и в реальной рабочей ситуации вы бы не знали, файлы какого размера будут читать с помощью этого метода, гораздо лучше использовать циклы и читать файл построчно. Вы можете прочитать файл целиком, но на больших файлах это будет работать ужасно медленно.

    Зачем строке происваевать данные файла?


    В переменной fromJson мы сохраняем прочитанные данные, а поскольку JSON представляет собой обычный набор текста, то использование типа String более чем подходит для этой операции. Вы также можете использовать коллекции или массивы для этого.

    Зачем указывать тип объекта в конце?


    Метод fromJson десериализует JSON, прочитанный из Reader'а (в данном случае из строки) в объект класса, указанного вторым аргументом.
    Ссылочка на спек класса
    https://www.javadoc.io/doc/com.google.code.gson/gs...
    Ответ написан
    Комментировать
  • Как переключаться между панелями из разных классов?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Приветствую. Возможно это то что вы ищете.
    https://docs.oracle.com/javase/7/docs/api/javax/sw...

    Касаемо архитектуры пока трудно сказать, т.к. иерархия классов весьма небольшая. Единственное что я бы сделал, так это выделил среди ваших классов-компонентов общие поля и методы и вынес все это в абстрактный класс, который будет наследовать JPanel, а затем уже наследовался от него.
    Ответ написан
    1 комментарий
  • Почему кнопка отображается только при наведении курсора?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Приветствую. Вам не нужно переопределять paint контейнер верхнего уровня, вместо этого переопределите метод paintComponent, в нем вызовете суперконструктор и отрисуйте вашу кнопку.
    Ответ написан
    1 комментарий
  • Наследование приватных полей и методов?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Подкласс не наследует закрытые члены своего родительского класса. Однако, если у суперкласса есть общедоступные или защищенные методы для доступа к его частным полям, они также могут использоваться подклассом. Так же, если класс-потомок является вложенным классом по отношению к классу-родителю, то имеет доступ ко всем частным полям и методам класса-родителя. В вашем же случае вы обязаны вызвать конструктор родительского класса в классе-потомке. Это не значит что вы получили доступ к приватному полю класса-родителя
    Ответ написан
    2 комментария
  • Добавление строки к строке до определённого (бесконечно большого) числа и нахождение в ней символа 'а'. Как решить?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Вам не нужно конкатенировать миллиарды символов, вы можете посчитать количество повторов в исходной строке, а затем умножить это число на количество полных повторов строки + остаток
    static long repeatedString(String s, long n) {
            /* Кол-во повторов в исходной строке */
            int rep = (int) s.toLowerCase()
                    .chars()
                    .filter(c -> c == 'a').count();
    
            /* Кол-во циклов, в которых исходная строка будет полностью скопирована */
            long cycles = (n / s.length()) - 1;
    
            /* Кол-во повторов в остаточной строке, которой не хватило на полный цикл */
            int remainder = (int) s.toLowerCase()
                    .substring(0, (int) n % s.length())
                    .chars()
                    .filter(c -> c == 'a').count();
    
            return rep * cycles + remainder + rep;
    }
    Ответ написан
    2 комментария
  • Как преобразовать String[] в Map через Stream API?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    Если вам нужны ключи и значения в исходном порядке, то используйте LinkedHashMap.
    String[] array = {"name", "Ivanov", "country", "Ukraine", "city", "Kiev", "age", null};
    
           Map<String, String> map = Stream.iterate(
                    Arrays.asList(array), list -> list.subList(2, list.size()))
                    .limit(array.length / 2)
                    .collect(Collectors.toMap(
                            list -> list.get(0) == null ? "null" : list.get(0),
                            list -> list.get(1) == null ? "null" : list.get(1),
                            (x, y) -> y, LinkedHashMap::new));
    
            map.entrySet().forEach(System.out::println);
    Ответ написан
    Комментировать
  • @Volatile, кэшировние?

    Erik_Mironov
    @Erik_Mironov
    Старые вопросы: *Dies from cringe*
    CPU имеют кэши разного уровня L1, L2, L3. Каждый поток(а также ядро процессора) имеет собственный кэш. Эти кэши хранят минимальный набор оперативной памяти для обеспечения производительности. Если переменная определена как volatile, то все операции записи над ней сразу же отражаются в памяти и не кэшируются. У потоков нет локальной копии памяти и часть данных которую поток читает / записывает может быть из кэша, а не из основной памяти, а поэтому когда один поток изменяет какую-либо переменную, то другой поток не может увидеть изменения над ней. Грубо говоря, для таких случаев и нужен volatile. Фух, объяснил как мог, возможно кто-то объяснит более подробно.

    5fec4c344c127654024248.png

    Можете почитать про модель памяти в Java
    https://docs.oracle.com/javase/specs/jls/se7/html/...
    Ответ написан
    Комментировать
  • Разные методы для каждого потока или synchronized?

    Erik_Mironov
    @Erik_Mironov Автор вопроса
    Старые вопросы: *Dies from cringe*
    Я, похоже задал очень глупый вопрос и только сейчас сам понял что он глупый, ведь использование общего ресурса в разных методах не освобождает от необходимости использования synchronized, а если общего ресурса нет, то и synchronized не нужен.
    Ответ написан
    Комментировать