【问题标题】:Rank ArrayList<String> with int in java在 java 中使用 int 对 ArrayList<String> 进行排名
【发布时间】:2014-07-29 22:07:19
【问题描述】:

我想用字符串出现的次数在 java 中对 ArrayList&lt;String&gt; 进行排名。 像这样:如果我有一个

ArrayList&lt;String&gt;= [French, English, German, French, French, Belgium, English, Belgium]

我数了"French", "English", "Belgium",etc.出现的次数。所以法语出现了 3 次,英语出现了 2 次,比利时出现了 2 次,德语出现了 1 次。然后我想根据数字对ArrayList&lt;String&gt; 进行排名。

结果将是:

French 3
English 2 
Belgium 2
German 1

我该怎么做?如何关联整数和字符串?

【问题讨论】:

标签: java string integer


【解决方案1】:

你需要先创建一个语言类:

public class Language {
  private String name;
  private int count;

  public Language(String name) { this.name = name; this.count = 0; }
  public String getName() { return this.name; }
  public int getCount() { return this.count; }
  public void setCount(int count) { this.count = count; }
}

然后,从 ArrayList 创建一个语言列表:

List<String> languageNames = // your language names
Map<String, Language> map = new HashMap<String, Language>();

for (String languageName : languageNames) {
  Language language = map.get(languageName);
  if (language == null) {
    language = new Language(languageName);
  } else {
    language.setCount(language.getCount() + 1);
  }
  map.put(languageName, language);
}

List<Language> languages = new ArrayList<Language>(map.values());

之后,我们对语言进行排序并打印:

Collections<Language>.sort(languages, new Comparator<Language>() {
  public int compare(Language l1, Language l2) {
    return l1.getCount() - l2.getCount();
  }
});

System.out.println(languages);

【讨论】:

  • 如何在 Jeff Gohlke 的代码上使用这个?因为他的代码在我的 ArrayList 上工作,而你的代码和我需要的不一样,所以我必须让你的代码适应我的。但是怎么做?我应该只看Collection的第三部分吗?
  • OP 想要 在 Java 中使用 int 对 List 进行排名,这大致转化为使用地图。你不觉得用一堂课来做这件事有点太僵硬了吗?
  • 我们可以避免使用类。但是,我们需要以某种方式将语言名称与其频率(出现次数)绑定。 Language 类用于此目的。
【解决方案2】:

不要重新发明轮子,使用Collections类的frequency方法:

public static int frequency(Collection<?> c, Object o)

返回指定集合中的元素个数等于 指定的对象。更正式地,返回元素的数量 e 在集合中使得 (o == null ? e == null : o.equals(e))。

如果您需要计算所有元素的出现次数,请巧妙地使用 Map 和循环 :) 或者将您的列表放入 Set 并使用上面的 frequency 方法在集合的每个元素上循环。高温

EDIT / Java 8:如果您想要一个功能更强大的 Java 8 单行 lambda 解决方案,请尝试:

Map<String, Long> occurrences = 
  list.stream().collect(Collectors.groupingBy(w -> w, Collectors.counting()));

然后按值对地图进行排序。

【讨论】:

  • 我不会赞成 frequency 评论,因为它仍然需要编码器遍历 List 并以某种方式存储/关联值。但是对于生病的 Java 8 技能 +1。 :)
  • 我不明白你的答案...当我尝试列表中的 .stream() 时,此方法不存在...
  • @momo70 升级到Java 8,享受功能接口!你还有什么不明白的吗?
  • 我找到了解决方案here 但是@okiharaherbst w -&gt; w 是什么?
  • @momo70,w -&gt; w 被称为 lambda 表达式,并在其第 8 版中被引入 Java,以带来一些 函数式编程 结构到语言。如果您有兴趣并需要有关该主题的入门知识,请查看docs.oracle.com/javase/tutorial/java/javaOO/…oracle.com/webfolder/technetwork/tutorials/obe/java/…。 HTH。
【解决方案3】:

任何时候你需要关联数据,你应该一直想MapHashMap 是用于此的基本类。因此,您可以遍历您的列表并在 Map&lt;String, Integer&gt; 中创建您的关联。

List<String> stuff = new ArrayList<String>();
// ...populate it

Map<String, Integer> map = new HashMap<String, Integer>();    
for(String string : stuff) {
    if(map.containsKey(string)) {
        map.put(string, map.get(string) + 1);
    }
    else {
        map.put(string, 1);
    }
}

查看完整的HashMap API here

【讨论】:

  • 谢谢,这就是我想要的。但是如何对地图进行排名呢?
  • @user3590882 很高兴它对您有所帮助。 :) 至于订购HashMap,您通常不会。 HashMap 基本上是无序的。如果你想根据键排序,你可以使用TreeMap,但是如果你想对值进行排序,正如我怀疑的那样,它变得有点困难,特别是因为可以有相同的值(而键是独特)。您可以查看this Q&A for more information
  • 我做了这个 map=new TreeMap(map);我有按字符串排序的地图,但是如何按键值排序呢?我试过 map=new TreeMap(map.values);但是不识别... PS:如何在本论坛写出像代码一样的文字?
猜你喜欢
  • 2019-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-19
  • 2016-08-28
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多