Как напечатать количество вхождений определенной строки в порядке убывания?

Я хочу использовать String[] журналов с подробным описанием пользователей, которые подключались к веб-сайту, чтобы распечатать в порядке убывания количество подключений каждого пользователя. Каждый журнал содержит некоторую информацию, но уникальный идентификатор пользователя всегда находится в пределах первого индекса массива.

Я пытаюсь просмотреть массив за время O(N), подсчитать, сколько раз каждый пользователь подключался, добавляя их в HashMap, а затем распечатывать подключенных пользователей в порядке убывания в зависимости от того, сколько раз они подключались. Как это может быть сделано? Я готов переключить всю свою реализацию, если есть более простой способ отслеживать количество вхождений в String[]. Я прикрепил пример ниже:

 // Connection logs in the form [Username, Location, time]
String[] logs = {
    "name1,Chicago,8pm",
    "name2,New York,6pm",
    "name3,Los Angeles,2am",
    "name1,Chicago,3pm",
    "name1,Chicago,12pm",
    "name4,Miami,3pm"
    "name4,Miami,6pm"
};

printConnections(logs);

/* Desired output:
    name1: 3
    name2: 2
    name4: 2
    name3: 1
*/

public static void printConnections(String[] connections){
    HashMap<String, Integer> hashmap = new HashMap<String, Integer>();
    for (String log : connections){
        String name = log.split(",")[0];
        if (hashmap.containsKey(name)){
            hashmap.replace(name, hashmap.get(name) + 1);
        }
        else{
            hashmap.put(name, 1);
        }
    }
    // Print all key/values in descending order of value
}

Итак, что за вопрос точный? Вы хотите знать, как сортировать HashMap по значению? Или вы просите кого-нибудь разработать решение вашей проблемы с журналированием?

MarsAtomic 07.05.2022 06:02

Либо действительно, я просто ищу решение этой проблемы. Меня спросили во время стартового интервью, и я испортил это, поэтому я надеюсь извлечь из этого уроки в будущем, но я изо всех сил пытаюсь придумать элегантное решение.

AHR 07.05.2022 06:04

Отвечает ли это на ваш вопрос? Как отсортировать LinkedHashMap по значению в порядке убывания в потоке Java?

Kai-Sheng Yang 07.05.2022 08:19
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
48
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

TLDR:

// Print all key/values in descending order of value
var sorted = hashmap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()));
sorted.forEach(pair->System.out.println(pair.getKey() + ": " + pair.getValue()));

Выход:

name1: 3
name4: 2
name3: 1
name2: 1

Как это устроено?

hashmap.entrySet() вернет набор Map.Entry объектов .stream() вернет поток этих объектов .sorted() сортирует поток по значению объектов Map.Entry

Полный:

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;

public class Main {

    public static void printConnections(String[] connections) {
        HashMap<String, Integer> hashmap = new HashMap<String, Integer>();
        for (String log : connections) {
            String name = log.split(",")[0];
            if (hashmap.containsKey(name)) {
                hashmap.replace(name, hashmap.get(name) + 1);
            } else {
                hashmap.put(name, 1);
            }
        }
        // Print all key/values in descending order of value
        var sorted = hashmap.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()));
        sorted.forEach(pair->System.out.println(pair.getKey() + ": " + pair.getValue()));
    }

    public static void main(String[] args) {

        // Connection logs in the form [Username, Location, time]
        String[] logs = {
                "name1,Chicago,8pm",
                "name2,New York,6pm",
                "name3,Los Angeles,2am",
                "name1,Chicago,3pm",
                "name1,Chicago,12pm",
                "name4,Miami,3pm",
                "name4,Miami,6pm"
        };

        printConnections(logs);
    }
}
Ответ принят как подходящий

Прежде всего, я предполагаю, что под O(n) вы подразумеваете O(n), где n = количество уникальных пользователей (т.е. hashmap.keySet().size()). К сожалению, ваша проблема связана с сортировкой, которая в лучшем случае является сложностью O (n * log (n)), поэтому я не думаю, что это возможно сделать за время O (n). Тем не менее, у меня есть код, чтобы выполнить работу:

ArrayList<Entry<String, Integer>> logList = new ArrayList<>(hashMap.entrySet());
Collections.sort(logList, new Comparator<Entry<String, Integer>>() {
    @Override
    public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
        return o2.getKey().compareTo(o1.getKey());
    }
});

Вы должны использовать API потока Java для решения этой проблемы.

hashmap.entrySet()
       .stream()
       // "Map.Entry.comparingByValue())" is convert HashMap value into ascending order by default
       // "Collections.reverseOrder()" is convert HashMap value into reverse of ascending order(descending)
       .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
       // print the hashmap
       .forEach(entry -> System.out.println(entry.getKey()  + ": " + entry.getValue()));

Другие вопросы по теме