【问题标题】:Problems using lambda expression使用 lambda 表达式的问题
【发布时间】:2020-06-08 03:54:35
【问题描述】:

我在对单词的字母进行排序时遇到问题,按字母出现的次数,如果字母出现相同的次数,它至少会按字典顺序排序。 我有一个代码,但我在网站上得到编译错误和 0 分,因为他们使用 java 7,我不知道如何在没有“lambda”的情况下解决问题的最后一部分。

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));
    }
}

【问题讨论】:

  • 什么网站?你就不能选择你要使用的java版本吗?
  • 无论如何,您必须实现自己的Comparator,使用Collections.sort() 并将forEach 重写为一个简单的循环。并用map.getOrDefault 更改部分。
  • Java 8 现在已经过时了。你应该向网站报告。他们不支持它和未来的稳定版本,这是在伤害他们的顾客。
  • @STRKLok 您可能需要重新考虑在您的comparator 实现中返回减去的值。它并不总是有效,并且可能导致陷阱。最好根据需要返回显式值 1、-1 或 0。

标签: java algorithm lambda bufferedreader bufferedwriter


【解决方案1】:

你可以使用Collections.sort(List&lt;T&gt; list, Comparator&lt;? super T&gt; 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<>();

【讨论】:

  • @OleV.V.没问题,实际上我喜欢按照你的方式做,并尽可能连接比较器。
  • 正如我在对问题的评论中所说,map.getOrDefault 也需要更改。我认为在您的回答中也可能值得一提。
  • @WJS 问题是关于 Java 8 和 7 的兼容性。
  • @M.S.这个网站是关于帮助的。有时,帮助超出了手头的问题。但我将建议转发给 OP,因为这是他们的代码。
【解决方案2】:

要使用 Java 7 构建 map,您可以按照以下方式进行。

        // 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 和其他类似的实现,我更喜欢使用`local classes。 Imo 它们比匿名类更干净,但确实需要额外的语法。如果你不熟悉这些,这将放在你的主类中。


    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());

您还必须修改您的打印方法以及其他方法,因为还存在其他 Java 8 功能。这是基本的打印解决方案。

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

【讨论】:

    猜你喜欢
    • 2011-05-09
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多