Считаем зарплаты

  • 12
  • Недоступна
В метод main первым параметром приходит имя файла. В этом файле каждая строка имеет следующий вид: имя значение где [имя] - String, [значение] - double. [имя] и [значение] разделены пробелом. Для каждого имени посчитать сумму всех его значений. Все данные вывести в консоль, предварительно отсортиро
Вы не можете решать эту задачу, т.к. не залогинены.
Комментарии (257)
  • популярные
  • новые
  • старые
Для того, чтобы оставить комментарий вы должны авторизоваться
Игорь 20 уровень, Москва
19 января, 19:00
1 цикл, 1 коллекция:
Булат 24 уровень, Москва
2 января, 22:14
Надо же, первые задачи в этом скоупе, которые удалось сделать самостоятельно за вменяемое время, крутяк! Сделалось так (да потом глянув в решение понял, что можно было проще, грамотно используя механизм добавления в мапу, но получилось как получилось):
if(args.length == 0)
	return;

String path = args[0];
BufferedReader reader = new BufferedReader(new FileReader(path));
Map<String, List<Double>> tree = new TreeMap<String, List<Double>>();
List<Double> list;

while (reader.ready()) {
	String line = reader.readLine();
	String name = line.split(" ")[0];
	Double amount = Double.parseDouble(line.split(" ")[1]);

	if (tree.get(name) == null) {
		list = new ArrayList<Double>();
		list.add(amount);
		tree.put(name, list);
	} else {
		tree.get(name).add(amount);
	}
}
reader.close();

for (Map.Entry<String, List<Double>> pair : tree.entrySet()) {
	String key = pair.getKey();
	List<Double> listTmp = pair.getValue();
//            System.out.print(key + " " + list.toString() + " " + list.stream().mapToDouble(Double::doubleValue).sum() + "\n");
	System.out.print(key + " " + listTmp.stream().mapToDouble(Double::doubleValue).sum() + "\n");
Понял, что таким образом можно сделать таки аналог Multimap (String, List), где каждому Васе добавлять в список его числа, если он уже есть в списке. Ну и создать ему список в противном случае. Далее немного магии с лямбдой и сумма для i-го name находится и выводится сразу. А ну и TreeMap за нас отсортирует вывод по ключу.
Е К 20 уровень, Краснодар
25 декабря 2020, 13:24
Нагородил немного огород для проверки заполненной мапы. Но потом здесь увидел классную подсказку:
if(result.get(splitted[0]) == null)
... где result - это TreeMap, а splitted - массив из слов исходной строки, разделённых по пробелу. И так мой код усох до 30 строчек(начиная с объявления пакета)
Филипп 23 уровень
9 января, 15:08
Нуу, так то можно и в 1 строчку все записать... Или классную подсказку IntelliJ Idea тыкнуть не глядя и вся логика в 9 строчках окажется. А потом сидишь и думаешь, что же, например, тут теперь написано. С учётом того что объявленным только TreeMap и BufferedReader остался.
читалка.lines().map(строка -> строка.split(" ")).forEach(пара -> {
    if (список.containsKey(пара[0]))
        список.put(пара[0], Double.sum(Double.parseDouble(пара[1]), список.get(пара[0])));
    else список.put(пара[0], Double.parseDouble(пара[1]));
});
Причем все эти стрелочки и не объявленные переменные нормально работают и валидатор не ругается.
Филипп 23 уровень
9 января, 23:20
Судя по поиску это try-with-resources, а валидатор на такую конструкцию без .close() не ругается?
Е К 20 уровень, Краснодар
10 января, 12:24
не ругается. пишу все задачки здесь в try-with-resources - валя пока помалкивает)
Филипп 23 уровень
10 января, 12:49
Уже разобрался с утра 😅 я в другой уже задаче написал так:
try ( BufferedReader br = new BufferedReader
              (new InputStreamReader(System.in)  ){
BufferedReader fr = new BufferedReader(new FileReader(br.readLine())
// всякое
} catch // всякое
и в результате получается fr внутри сам не закрывался, и валидатор не пропускал. Оказывается нужно их оба заключать в скобки в try, тогда все нормально.
try ( BufferedReader br = new BufferedReader
            (new InputStreamReader(System.in);
BufferedReader fr = new BufferedReader
             (new FileReader(br.readLine())){
// всякое
} catch // всякое
Может кому тоже пригодится, чтобы -1 попытку не получить :)
Е К 20 уровень, Краснодар
10 января, 12:52
Да Валидатор иногда дело говорит)
Андрей 22 уровень, Волгоград
25 декабря 2020, 11:51
такой вывод валидатор не пропустил:
System.out.printf("%s : %s\n", key, value);
принял вот такой:
System.out.println(key + " " + value);
Филипп 23 уровень
9 января, 14:36
Конечно не пропустит, так список выведется: Иванов : 1.35 Петров : 5.1 Сидоров : 6.0 В примере же требуют через 1 пробел.
printf("%s %s\n", Key, Value);
Андрей 24 уровень, Москва Expert
18 декабря 2020, 14:20
Очень странно... Решение короче решения JR, но валя его пропустилас первого раза. Если ранее того не делали, то изучите тему TreeMap и как там всё сортируется по умолчанию. Очень полезен метод containsKey().
gen 23 уровень, Москва
17 декабря 2020, 12:56
Хорошая практика, дважды решать одну задачу. Сначала как знаешь, потом как хочет от тебя валидатор. Если сразу заглядывать в обсуждение или правильное решение, теряется элемент творчества.
Kes Чайник в Банк
24 декабря 2020, 02:55
И что самое важное теряется элемент геморроя! ☝
andrew-bc 35 уровень, Варшава
1 декабря 2020, 15:25
У кого не проходило решение с первой строкой. Есть такая штука как невидимые символы BOM в начале каждой строки в UTF-8. Воспользовался такой функцией:
private static String removeUTF8BOM(String s) {
    if (s.startsWith("\uFEFF")) {
        s = s.substring(1);
    }
    return s;
}
Потом каждую фамилию прогонял через эту функцию:
String key=removeUTF8BOM(tmp[0]);
Kes Чайник в Банк
24 декабря 2020, 02:57
У тебя видать локальный файл был с BOM, при проверке его нет.
Павел студент на стероидах в Java Syntax Pro beta
1 декабря 2020, 06:58
Воу-воу! Я думал что после трёх хардов это задача просто на набор текста, хавевэ заглянул в коменты и узнал про merge()
map.merge(name, value, Double::sum);
Вывод на печать я и так уже давно ленился делать иначе как forEach()-ем. Но приятно было узнать что ТриМап ещё и сортировку по умолчанию делает.
Kes Чайник в Банк
24 декабря 2020, 02:57
Double::sum О. Что-то новое. Мерси
RomanSmoll Backend Developer в CoverApps
29 ноября 2020, 14:46
немного суммируя комменты снизу и добавляя свое: 1.(от себя) - помните статью :хватит писать циклы? ? Так вот , там если покопаться и выбрать 3 правильные функции то тогда весь функционал от добавления до вывода в консоль- 3 строчки! главное , чтобы последовательность этих 3 была правильная. 2. (из комментов снизу) вероятно, еще можно решать через метод merge() но если вы пользуетесь 1 пунктом то он или не нужен или его можно влупить туда 3.(Важное из комментов снизу!!) Не забывайте про Treemap/ помимо +1 попытки, это еще и позволяет обходить стороной сортировку через подобную дьявольщину:
String[] sorted =new String[map.size()];
            int i=0;
            for(Map.Entry<String,Double> entry: map.entrySet()){
                sorted[i]= entry.getKey()+" "+String.valueOf(entry.getValue());
                i++;
            }
            Arrays.sort(sorted);
            for(String z:sorted){
                System.out.println(z);
            }
Aleksandr 28 уровень
19 ноября 2020, 12:24
файл в лист. каждый элемент листа сплитом в массив. создаем treemap , каждый первый элемент массива проверяем на содержание в имеющейся мапе. если есть - складываем value, если нет - добавляем новый элемент мапы. после решения в комменты полез, узнал про merge .
RomanSmoll Backend Developer в CoverApps
29 ноября 2020, 14:49
зачем файл в лист. каждый элемент листа сплитом в массив, если можно просто ридер научить читать по строчке и сразу в treemap ? мне кажется, это лишние действия