java - 将信息读取到地图

  显示原文与译文双语对照的内容

我正在学习关于Java编程入门版的集合和地图 Daniel Daniel 。 我的教授在章节后面指派了一个问题,要求我创建一个程序:

  • 查询用户输入的名称
  • 查询用户的性别

使用这两个条件,以及这些 website(s):

http://cs.armstrong.edu/liang/data/babynamesranking2001.txt 
... http://cs.armstrong.edu/liang/data/babynamesranking2010.txt

我必须能得到排名。

我应该把这些信息get为张地图 。 每个映射对应一个. txt 文件/年份。 这就是我遇到 Having 问题的地方。 我该怎么做?

学生的( Int ) 等级是地图的价值,关键是婴儿的NAME ( 字符串) 。

我想的方式是创建一个地图 array 或者它们的列表。 这样:

List<Map<Int, String>> 或者 <Map<Int, String>[] myArray;

尽管如此,我从. txt 文件中获取这些信息到地图的问题是一个艰难的问题。

这是我到目前为止的结果。 我不觉得我对它很满意。 当我尝试开始阅读信息时,它甚至不工作,因为我没有指定 array的大小。


public class BabyNamesAndPopularity
{
 public static void main (String[] args) throws IOException
 {
 Map<Integer, String>[] arrayOfMaps;
 String myURL ="cs.armstrong.edu/liang/data/babynamesranking2001.txt";
 java.net.URL url = new java.net.URL(myURL);
 Scanner urlInput = new Scanner (url.openStream());
 while(urlInput.hasNext())
 {
. . .
 }
 }
}

能不能把一组地图? 我觉得最好是做一组映射,因为在需要的( 根据负荷系数) 中设置了扩展的事实。 我只需要一些常规的指导。 不幸的是,我大学(,的,大学)的程序非常的小,而且我们没有任何关于这个东西的导师。

时间: 作者:

由于问题的广泛性质,这个答案相当模糊,而且它可能更适合于 programmers SE site 。 不过,你可能会发现这两点值得。

  1. 不考虑'原始'复合集,例如集合地图列表,试着用适当的Java集合或者数组来实现这些类型。

  2. 单元测试 和增量优化,而不是立即开始访问远程数据( 通过 java.net.URL ),从 static 来源开始。 Idea'可靠'/o input可以使用,它允许你使用上的域类型轻松地编写单元测试,也可以使用w/o 访问网络,甚至是文件系统。 编写单元测试时,可以在单元测试中创建必要的域类型/方法名称,然后实现这些类型/方法,然后执行单元测试,然后通过单元测试。


例如你可以通过编写以下( 假设你知道如何在IDE中组织Java项目,这样 单元测试 就可以正常运行了) 来启动


public class SingleFileProcessingTest {

 private static String[] fileRawData;

 @BeforeClass
 public static void fillRawData() {
 fileRawData = new String[2];
//values are from my head, resembling format from links you've posted
 fileRawData[0] ="Jacobt20000tEmilyt19999";
 fileRawData[1] ="Michaelt18000tMadisont17000";
 }

 @Test
 public void test() {
 Rankings rankings = new Rankings();
 rankings.process(fileRawData);
 assertEquals("Jacob", rankings.getTop().getName());
 assertEquals("Madison", rankings.getScorerOfPosition(4).getName());
 assertEquals(18000, rankings.getScoreOf("Michael"));
 assertEquals(4, rankings.getSize());
 }
}

当然,这甚至不会编译--需要输入 Rankings 类代码。getTop() 或者 getScorerOfPosition(int) 返回的类代码等等。 在进行编译之后,你将需要进行测试传递。 但是你在这里获得了--域类型和增量优化的主要思想。 对文件系统或者网络的w/o 依赖性的易于验证的代码。 只是普通的java对象( pojo ) 。 以后可以添加使用外部数据源的代码,在获得pojo并进行测试的过程中,通过了大部分。


实际上,我已经在上面的代码中混合了的抽象级别: 适当的Rankings 类不应该处理原始数据,这最好是在单独的类中完成,例如 RankingsDataParser 。 使用 单元测试,重命名为 RankingsProcessingTest,将为:


public class RankingsProcessingTest {

 @Test
 public void test() {
 Rankings rankings = new Rankings();

 rankings.addScorer(new Scorer("Jacob", 20000));
 rankings.addScorer(new Scorer("Emily", 19999));
 rankings.addScorer(new Scorer("Michael", 18000));
 rankings.addScorer(new Scorer("Madison", 17000));

 assertEquals("Jacob", rankings.getTop().getName());
//assertEquals("Madison", rankings.getScorerOfPosition(4).getName());
//implementation of getScorerOfPosition(int) left as exercise :)
 assertEquals(18000, rankings.getScoreOf("Michael"));
 assertEquals(4, rankings.getSize());
 }

}

使用 RankingsScorer的初始实现后,实际上会编译并传递:


class Scorer {
 private final String name;
 private final int rank;

 Scorer(String name, int rank) {
 this.name = name;
 this.rank = rank;
 }

 public String getName() {
 return name;
 }

 public int getRank() {
 return rank;
 }
}

class Rankings {

 private final HashMap<String, Scorer> scorerByName = new HashMap<>();

 private Scorer topScorer;

 public Scorer getTop() {
 return topScorer;
 }

 public void addScorer(Scorer scorer) {
 if (scorerByName.get(scorer.getName())!= null)
 throw new IllegalArgumentException("This version does not support duplicate names of scorers!");
 if (topScorer == null || scorer.getRank()> topScorer.getRank()) {
 topScorer = scorer;
 }
 scorerByName.put(scorer.getName(), scorer);
 }

 public int getSize() {
 return scorerByName.size();
 }

 public int getScoreOf(String scorerName) {
 return scorerByName.get(scorerName).getRank();
 }
}

用于解析原始数据的单元测试 将从以下( 下载原始数据应该负责另一个类,要进行开发和单独测试) 开始:


public class SingleFileProcessingTest {

 private static String[] fileRawData;

 @BeforeClass
 public static void fillRawData() {
 fileRawData = new String[2];
//values are from my head
 fileRawData[0] ="Jacobt20000tEmilyt19999";
 fileRawData[1] ="Michaelt18000tMadisont17000";
 }

 @Test
 public void test() {
//uncomment, make compile, make pass
/*
 RankingsDataParser parser = new RankingsDataParser();
 parser.parse(fileRawData);
 Rankings rankings = parser.getParsedRankings();
 assertNotNull(rankings);
*/
 }
}

作者:
...