Проблемы с использованием лямбда-выражения - PullRequest
1 голос
/ 24 февраля 2020

У меня проблема с сортировкой букв слова по количеству вхождений букв, и если буквы появляются одинаковое количество раз, они будут отсортированы хотя бы лексикографически. У меня есть код, но я получаю ошибку компиляции на сайте и 0 баллов, потому что они используют java 7, и я не знаю, как решить последнюю часть проблемы без "лямбды".

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;

public class prog {
    public static void main(String[] args) throws IOException {
        String testString = " ";
        BufferedReader rd = new BufferedReader(new InputStreamReader(System.in));
        testString = rd.readLine();
        Map < Character, List < Character >> map = new HashMap < > ();
        for (int i = 0; i < testString.length(); i++) {
            char someChar = testString.charAt(i);
            if (someChar == ' ') {
                continue;
            }
            char ch = testString.charAt(i);
            List < Character > characters =
                map.getOrDefault(Character.toLowerCase(ch), new ArrayList < > ());
            characters.add(ch);
            map.put(Character.toLowerCase(ch), characters);
        }
        List < Map.Entry < Character, List < Character >>> list =
            new ArrayList < > (map.entrySet());

        list.sort((o1, o2) - > {
            if (o1.getValue().size() == o2.getValue().size()) {
                return o1.getKey() - o2.getKey();
            }
            return o2.getValue().size() - o1.getValue().size();
        });
        list.forEach(entry - > entry.getValue().forEach(System.out::print));
    }
}

Ответы [ 2 ]

2 голосов
/ 24 февраля 2020

Вы можете использовать Collections.sort(List<T> list, Comparator<? super T> c):

Collections.sort(list, new Comparator<Map.Entry<Character, List<Character>>>() {
    @Override
    public int compare(Map.Entry<Character, List<Character>> o1, Map.Entry<Character, List<Character>> o2) {
        if (o1.getValue().size() == o2.getValue().size()) {
            return o1.getKey() - o2.getKey();
        }
        return o2.getValue().size() - o1.getValue().size();
    }
});

for (Map.Entry<Character, List<Character>> characterListEntry : list) {
    System.out.println(characterListEntry);
}

Map#getOrDefault(Object key, V defaultValue) также было введено в Java 8. вам нужно изменить его на что-то вроде:

char cKey = Character.toLowerCase(ch);
List<Character> characters = map.containsKey(cKey) ? map.get(cKey) : new ArrayList<>();
0 голосов
/ 24 февраля 2020

Чтобы построить map с Java 7, вы можете сделать это следующим образом.

        // convert to lower case from the start
        testString = rd.readLine().toLowerCase();

        Map<Character, List<Character>> map = new HashMap<>();
        for (int i = 0; i < testString.length(); i++) {
            char someChar = testString.charAt(i);
            if (someChar == ' ') {
                continue;
            }
            // try and get the list
            List<Character> characters = map.get(someChar);
            if (characters == null) {
                // otherwise, create it
                characters = new ArrayList<>();
                // and put it in the map
                map.put(someChar, characters);
            }
            // add characters to the obtained list.
            characters.add(someChar);
        }

Для Comparator и других подобных реализаций я предпочитаю использовать `локальные классы. Imo они чище анонимных классов, но требуют дополнительного синтаксиса. Если вы не знакомы с ними, это будет go внутри вашего основного класса.


    static class CountThenLex implements
                Comparator<Entry<Character, List <Character>>> {
        public int compare(
            Entry<Character, List<Character>> a,
            Entry<Character, List <Character>> b) {
            int asize = a.getValue().size();
            int bsize = b.getValue().size();
            // note that b is sorted first for descending count order.

            int aTob = bsize > asize ? 1 :
                bsize < asize ? -1 : 0;
            if (aTob != 0) {
                return aTob;
            }

            // if the counts are equal, then sort lexically.  Since the Character
            // class implements `Comparable` you can use the natural ordering.
            return a.getKey().compareTo(b.getKey());
        }
    }

Тогда вы просто вызываете sort с экземпляром класса.

    Collections.sort(list, new CountThenLex());

You Также придется изменить ваш метод печати, а также другие методы, так как присутствуют другие функции Java 8. Вот базовое c решение для печати. ​​

    for(Entry<?,List<Character>> e : list) {
        for (char c : e.getValue()) {
            System.out.print(c);
        }
    }
    System.out.println();
...