在Java中使用映射和集合作为数据结构
我有一个程序,可以记录曲目以及播放和输出的次数。。简单。。但我无法按降序进行计数。我的第二个问题是,如果有多个曲目的计数相同,它应该查看曲目的名称并按字母顺序打印。。我已经达到了这样一个地步,我可以不按顺序打印所有内容,因为我使用的是地图,每当我使用列表进行排序时,它都会按升序排序 这是我的代码和输出在Java中使用映射和集合作为数据结构,java,set,maps,Java,Set,Maps,我有一个程序,可以记录曲目以及播放和输出的次数。。简单。。但我无法按降序进行计数。我的第二个问题是,如果有多个曲目的计数相同,它应该查看曲目的名称并按字母顺序打印。。我已经达到了这样一个地步,我可以不按顺序打印所有内容,因为我使用的是地图,每当我使用列表进行排序时,它都会按升序排序 这是我的代码和输出 import java.util.*; import java.io.*; import java.lang.*; import lab.itunes.*; public class Music
import java.util.*;
import java.io.*;
import java.lang.*;
import lab.itunes.*;
public class Music {
public static void main(String[] args) throws Exception {
try {
Scanner input = new Scanner(System.in);
PrintStream output = new PrintStream(System.out);
Map<String,Integer> mapp = new HashMap<String,Integer>();
List<Integer> list1 = new ArrayList<Integer>();
output.print("Enter the name of the iTunes library XML file:");
String entry = input.nextLine();
Scanner fileInput = new Scanner(new File(entry));
Library music = new Library(entry); // this class was given to us.
Iterator<Track> itr = music.iterator(); // scan through it
while (itr.hasNext())
{
Track token = itr.next(); // get the tracks
mapp.put(token.getName(),token.getPlayCount()); // fill our map
list1.add(token.getPlayCount()); // fill our list too
}
for(Map.Entry<String,Integer> testo : mapp.entrySet()) {
String keys = testo.getKey();
Integer values = testo.getValue();
output.printf("%d\t%s%n",values,keys); // printing the keys and values in random order.
}
} catch (FileNotFoundException E) {
System.out.print("That file does not exist");
}
}
你能给我一个提示吗?我至少工作了4个小时才走到这一步。。谢谢我想你的问题是:如何根据值而不是键对地图进行排序 如果是这样的话,下面是一些示例代码以帮助您开始:
map.entrySet().stream()
.sorted(Map.Entry.comparingByValue())
.map(entry -> entry.getKey() + "\t + entry.getValue())
.forEach(output::println);
如果需要按相反顺序排序,只需更改comparingByValue比较器:
.sorted(Map.Entry.comparingByValue((val1, val2) -> val2 - val2))
要按值排序,然后按字母顺序排序:
.sorted((entry1, entry2) -> entry1.getValue() == entry2.getValue() ? entry1.getKey().compareTo(entry2.getKey())) : entry2.getValue() - entry1.getValue())
您可以将比较器放在一个单独的方法中,使其更整洁
private Comparator<Map.Entry<String, Integer>> songComparator() {
return (entry1, entry2) -> {
int difference = entry2.getValue() - entry1.getValue();
if (difference == 0) {
return entry1.getKey().compareTo(entry2.getKey()));
} else {
return difference;
}
}
}
专用比较器songComparator(){
返回(入口1,入口2)->{
int difference=entry2.getValue()-entry1.getValue();
如果(差==0){
返回entry1.getKey().compareTo(entry2.getKey());
}否则{
收益差;
}
}
}
然后您将使用
songparator
为sorted
生成比较器库
类是否有sort()方法?如果没有,您可以添加一个并在库music
上调用sort(),然后再请求它提供其迭代器()
公共类库
{
//…现有代码。。。
公共无效排序()
{
类TrackPlayCountComparator实现Comparator
{
@凌驾
公共整数比较(轨道t1、轨道t2){
int compare=t2.getPlayCount()-t1.getPlayCount();
如果(比较==0){
返回t1.getName().compareTo(t2.getName());
}
返回比较;
}
}
Collections.sort(this.tracks,新的TrackPlayCountComparator());
}
}
将代码简化为:
public static void main(String[] args) throws Exception
{
Scanner input = new Scanner(System.in);
System.out.print("Enter the name of the iTunes library XML file: ");
String entry = input.nextLine();
try {
input = new Scanner(new File(entry));
input.close();
Library music = new Library(entry); // this class was given to us.
music.sort(); // sort the tracks
PrintStream output = new PrintStream(System.out)
for (Iterator<Track> itr = music.iterator(); itr.hasNext(); ) {
Track track = itr.next();
output.printf("%d\t%s%n", track.getPlayCount(), track.getName());
}
} catch (FileNotFoundException E) {
System.out.print("That file does not exist");
}
}
publicstaticvoidmain(字符串[]args)引发异常
{
扫描仪输入=新扫描仪(System.in);
System.out.print(“输入iTunes库XML文件的名称:”);
String entry=input.nextLine();
试一试{
输入=新扫描仪(新文件(条目));
input.close();
图书馆音乐=新图书馆(条目);//这门课是给我们的。
music.sort();//对曲目进行排序
PrintStream输出=新的PrintStream(System.out)
for(迭代器itr=music.Iterator();itr.hasNext();){
Track Track=itr.next();
output.printf(“%d\t%s%n”,track.getPlayCount(),track.getName());
}
}catch(filenotfounde异常){
System.out.print(“该文件不存在”);
}
}
使用Collections.sort()按集合的属性对集合进行排序,或定义一个集合并将其作为第二个参数传递
首先,您必须更改列表以采用“轨迹”类型,并且您不再需要地图:
// the list will store every track
List<Track> tracks = new ArrayList<Track>();
String entry = input.nextLine();
Scanner fileInput = new Scanner(new File(entry));
Library music = new Library(entry); // this class was given to us.
Iterator<Track> itr = music.iterator(); // scan through it
while (itr.hasNext()) {
tracks.add(itr.next()); // add each track
}
// you can define classes anonymously:
Collections.sort(tracks, new Comparator<Track>()
{
@Override
public int compare(Track t1, Track t2) {
int diff = t2.getPlayCount() - t1.getPlayCount();
// if there is no difference in play count, return name comparison
return (diff == 0 ? t1.getName().compareTo(t2.getName()) : diff);
}
});
//列表将存储每个曲目
List tracks=new ArrayList();
String entry=input.nextLine();
扫描仪文件输入=新扫描仪(新文件(条目));
图书馆音乐=新图书馆(条目);//这门课是给我们上的。
迭代器itr=music.Iterator();//浏览一下
while(itr.hasNext()){
tracks.add(itr.next());//添加每个曲目
}
//您可以匿名定义类:
Collections.sort(tracks,newcomparator()
{
@凌驾
公共整数比较(轨道t1、轨道t2){
int diff=t2.getPlayCount()-t1.getPlayCount();
//如果播放计数没有差异,则返回名称比较
返回(diff==0?t1.getName().compareTo(t2.getName()):diff);
}
});
有关更多信息,请参阅。将TreeMap与自定义比较器一起使用不是有意识的决定吗?Hashmap文档:“这个类不保证映射的顺序”请参见-但是,您可以使用列表中的Collections.sort()按字母顺序排序,然后遍历列表(这是Hashmap的键)并检索每个字符串的整数。您还可以创建一个类-我称之为Track
-使用两个字段实现Comparable
:Name
和PlayCount
。实现接口方法(包括equals
和hashCode
),然后制作列表
,并使用Collections.sort()
。您的比较器将能够按播放次数排序,并按字母顺序打破平局,就像您希望的那样。@adamdc78我尝试使用树形图,但得到了相同的结果,不确定您所说的比较器是什么意思。。。但是谢谢:)谢谢兄弟,但是这个方法对我来说有点高级,我不允许在类库中添加任何方法。。一定有更简单的办法。。多谢,多谢!添加一个比较器是正确的答案;如果您无法添加新方法,请查看下面我的答案,了解如何将比较器添加为匿名类。谢谢兄弟,但我还无法将方法添加到该类中。。如果有其他方法,我可以使用comparator对我的曲目播放计数进行排序?…是的,您可以创建自己的comparator(单独的类或匿名类)。
public static void main(String[] args) throws Exception
{
Scanner input = new Scanner(System.in);
System.out.print("Enter the name of the iTunes library XML file: ");
String entry = input.nextLine();
try {
input = new Scanner(new File(entry));
input.close();
Library music = new Library(entry); // this class was given to us.
music.sort(); // sort the tracks
PrintStream output = new PrintStream(System.out)
for (Iterator<Track> itr = music.iterator(); itr.hasNext(); ) {
Track track = itr.next();
output.printf("%d\t%s%n", track.getPlayCount(), track.getName());
}
} catch (FileNotFoundException E) {
System.out.print("That file does not exist");
}
}
// the list will store every track
List<Track> tracks = new ArrayList<Track>();
String entry = input.nextLine();
Scanner fileInput = new Scanner(new File(entry));
Library music = new Library(entry); // this class was given to us.
Iterator<Track> itr = music.iterator(); // scan through it
while (itr.hasNext()) {
tracks.add(itr.next()); // add each track
}
// you can define classes anonymously:
Collections.sort(tracks, new Comparator<Track>()
{
@Override
public int compare(Track t1, Track t2) {
int diff = t2.getPlayCount() - t1.getPlayCount();
// if there is no difference in play count, return name comparison
return (diff == 0 ? t1.getName().compareTo(t2.getName()) : diff);
}
});