我有一个US-ASCII的文本文件,其中包含一个长行。我需要访问的文本项由不同数量的空格分隔,如下所示:
metadata1 attrib1 metadata2 attrib2 attrib2a trackstart attrib1 attrib2 trackstart attrib1 atrib2 attrib3
该文件最多可包含99个“轨道”条目,并且占用的内存很少。
我需要做什么
我必须将这些条目提取到内存结构中,我可以迭代,访问值和计算项目。例如,我需要获取“曲目”的数量(通过计算上面示例中的'trackstart',并将每个曲目的属性添加到object.track1.attribute1
这样的结构中。
我尝试了什么
我使用扫描仪读取文件并逐步浏览文本条目。这似乎工作正常。然后我创建了嵌套的HashMaps,如:
HashMap<String, String> overallMap = new HashMap<String, String>(); // contains the tracks map and some other metadata
HashMap<String, Map> tracks = new HashMap<String, Map>(); // contains a map of all tracks
HashMap<String, String> track = new HashMap<String, String>(); // contains an individual track
但问题是(我认为)HashMaps不会让我计算密钥(所以我不能,比如说,我的文本文件中的'track'数量)。我怀疑我会遇到这个数据结构的其他问题。
问题
答案 0 :(得分:0)
Java是一种OO语言,因此您应该创建自己的对象,而不是仅仅依赖于数据结构。这将使一切变得更容易,写作,阅读和维护。
因此,您应该拥有一个Track
类,其中包含List
或Set
个属性。选择取决于您是否关心属性的顺序,以及是否必须删除重复项。
Track类应该允许你添加和获取属性,因为这是你需要做的。而且,由于您似乎只对曲目感兴趣,而不是第一首曲目之前的线中的其他信息,您只需要一个曲目列表来保留所有曲目。
所以算法应该很简单:
List<Track>
trackstart
,则创建新的Track
,并将此新Track
实例分配给变量currentTrack
。将此曲目添加到曲目列表currentTrack
为空,您应该忽略令牌currentTrack
不为空,您应该通过调用currentTrack.addAttribute(token)
在算法结束时,您有一个List<Track>
个完整的Track实例,其顺序与该行中的轨道相同。每个Track实例都有List<String>
,其中包含轨道的属性。
答案 1 :(得分:0)
由于你有一些元数据对象和一些轨道,每个轨道都有可变数量的属性,我们可以有一个名为“MyObjects”的基类来代表它们
public class MyObject implements java.io.Serializable
{
String name;
ArrayList attributes;
public MyObject(String name)
{
this.name = name;
}
public void addAttribute(String attr)
{
this.attributes.add(attr);
}
}
然后有一个MyFile类代表你读过的每个文件。
public class MyFile
{
MyObject[] metadata;
MyObject[] track;
public int check(String s)
{
if(s.substring(0,s.length()-1).equals("metadata")) return 0;
if(s.equals("trackstart")) return 1;
return 2;
}
}
然后在main函数中你可以读取文件
File f = new File(filepath);
BufferedReader br = new InputStreamReader(f.getInputStream());
String line = "",content = "";
while((line = br.readLine())!=null) content += line;
MyFile myfile = new MyFile();
StringTokenizer t = new StringTokenizer(content," ");
int status;
String word = "";
while(t.hasMoreTokens())
{
word = t.nextToken();
status = myfile.check(word);
// add the attributes to the to metadata or tracks
}