![](/img/trans.png)
[英]How to create object based off .txt file information and assign to an arraylist?
[英]How to read strings off of .txt file and sort them into an ArrayList based on the number of occurrences?
我有一个程序可以读取.txt文件,创建一个包含每个唯一字符串及其出现次数的HashMap,并且我想创建一个ArrayList,以按出现次数的降序显示这些唯一字符串。
目前,我的程序从字母的角度来看按降序排序(我使用的是ASCII值)。
如何按照出现次数从高到低排序?
这是代码的相关部分:
Scanner in = new Scanner(new File("C:/Users/ahz9187/Desktop/counter.txt"));
while(in.hasNext()){
String string = in.next();
//makes sure unique strings are not repeated - adds a new unit if new, updates the count if repeated
if(map.containsKey(string)){
Integer count = (Integer)map.get(string);
map.put(string, new Integer(count.intValue()+1));
} else{
map.put(string, new Integer(1));
}
}
System.out.println(map);
//places units of map into an arrayList which is then sorted
//Using ArrayList because length does not need to be designated - can take in the units of HashMap 'map' regardless of length
ArrayList arraylist = new ArrayList(map.keySet());
Collections.sort(arraylist); //this method sorts in ascending order
//Outputs the list in reverse alphabetical (or descending) order, case sensitive
for(int i = arraylist.size()-1; i >= 0; i--){
String key = (String)arraylist.get(i);
Integer count = (Integer)map.get(key);
System.out.println(key + " --> " + count);
}
在Java 8中:
public static void main(final String[] args) throws IOException {
final Path path = Paths.get("C:", "Users", "ahz9187", "Desktop", "counter.txt");
try (final Stream<String> lines = Files.lines(path)) {
final Map<String, Integer> count = lines.
collect(HashMap::new, (m, v) -> m.merge(v, 1, Integer::sum), Map::putAll);
final List<String> ordered = count.entrySet().stream().
sorted((l, r) -> Integer.compare(l.getValue(), r.getValue())).
map(Entry::getKey).
collect(Collectors.toList());
ordered.forEach(System.out::println);
}
}
首先使用Files.lines
方法读取文件,该方法为您提供了Stream<String>
的各行。
现在Map<String, Integer>
使用Map.merge
方法将这些行收集到Map<String, Integer>
中,该方法接受一个键和一个值,以及一个lambda,该lambda应用于旧值和新值(如果键已经存在)。
您现在有了计数。
现在,获取Map
的entrySet
的Stream
,并按每个Entry
的value
进行排序,然后获取key
。 将其收集到List
。 现在,您具有按计数排序的值List
。
现在只需使用forEach
打印它们。
如果仍在使用Java 7,则可以使用Map
提供排序顺序:
final Map<String, Integer> counts = /*from somewhere*/
final List<String> sorted = new ArrayList<>(counts.keySet());
Collections.sort(sorted, new Comparator<String>() {
@Override
public int compare(final String o1, final String o2) {
return counts.get(o1).compareTo(counts.get(o2));
}
});
您没有显示地图的声明,但是出于这个答案的目的,我假设您的地图是这样声明的:
Map<String,Integer> map = new HashMap<String,Integer>();
您需要在调用中使用Comparator
进行排序,但是在记住字符串的同时需要按计数进行比较。 因此,您需要将同时具有字符串和计数的对象放入列表中。 提供此功能并且可以从Map.entrySet
方法轻松获得的一种类型是Map.Entry
类型。
最后一部分用Map.Entry
和Comparator
重写:
ArrayList<Map.Entry<String,Integer>> arraylist = new ArrayList<Map.Entry<String,Integer>>(map.entrySet());
Collections.sort(arraylist, new Comparator<Map.Entry<String,Integer>>() {
@Override
public int compare(Entry<String, Integer> e1, Entry<String, Integer> e2) {
// Compares by count in descending order
return e2.getValue() - e1.getValue();
}
});
// Outputs the list in reverse alphabetical (or descending) order, case sensitive
for (Map.Entry<String,Integer> entry : arraylist) {
System.out.println(entry.getKey() + " --> " + entry.getValue());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.