如何在没有像Postgres这样的数据库工具的情况下,从many-to-many
到fileID
以及从Words
到word
实现高效fileIDs
关联在Java?
我有以下课程。
从fileID
到words
的关系很便宜,但并非相反,因为我需要三个for
-loops。
alt text http://img191.imageshack.us/img191/4077/oliorakenne1.png
我的解决方案显然效率不高。
其他选项可能是创建一个额外的类,word
作为ArrayList
fileID
的ID。
回复JacobM的回答
MyFile的构造函数的相关部分是:
/**
* Synopsis of data in wordToWordConutInFile.txt:
* fileID|wordID|wordCount
*
* Synopsis of the data in the file wordToWordID.txt:
* word|wordID
**/
/**
* Getting words by getting first wordIDs from wordToWordCountInFile.txt and then words in wordToWordID.txt.
*/
InputStream in2 = new FileInputStream("/home/dev/wordToWordCountInFile.txt");
BufferedReader fi2 = new BufferedReader(new InputStreamReader(in2));
ArrayList<Integer> wordIDs = new ArrayList<Integer>();
String line = null;
while ((line = fi2.readLine()) != null) {
if ((new Integer(line.split("|")[0]) == currentFileID)) {
wordIDs.add(new Integer(line.split("|")[6]));
}
}
in2.close();
// Getting now the words by wordIDs.
InputStream in3 = new FileInputStream("/home/dev/wordToWordID.txt");
BufferedReader fi3 = new BufferedReader(new InputStreamReader(in3));
line = null;
while ((line = fi3.readLine()) != null) {
for (Integer wordID : wordIDs) {
if (wordID == (new Integer(line.split("|")[1]))) {
this.words.add(new Word(new String(line.split("|")[0]), fileID));
break;
}
}
}
in3.close();
this.words.addAll(words);
Word的构造函数位于the paste。
答案 0 :(得分:1)
在您知道Word在文件中时,更有效的方法是不是将Word中的链接分配给MyFile吗?也就是说,如何在MyFile对象中构建单词列表?如果您正在读取文件系统中的文件中的文件,而不是读取每个单词中的文件,则将其MyFile分配给当前文件。
//within MyFile constructor or setter for Words
while (//there's another word to add) {
Word newWord = new Word(//read word from file);
words.add(newWord);
newWord.setMyFile(this);
}
这类似于管理双向父子关系的典型方法:
//in Parent
public void addChild(Child child) {
myChildren.add(child);
child.setParent(this);
}
如果您向我们展示如何构建MyFile对象,可能会有所帮助。
在您添加构建单词列表的代码后编辑:
好的,所以看到构建你的单词的代码,我不认为建立关系是你效率低下的根源。看起来你正在按照我建议的方式设置关系(当你添加每个单词时,你给这个单词指定相应文件的fileID)。
看起来效率低下的根源在于,对于每个单词,您必须将它与当前在一组文件中的各种内容(例如WordToWordId)进行匹配。因此,对于每个单词,您必须循环遍历该文件的每一行,并找到匹配项。这当然效率低下。
更好的方法是将这些配对放在HashMap的内存中,在启动时初始化。这样,如果你有一个特定的单词并需要相应的ID,反之亦然,你可以在你的HashMap中查找它,这是一个恒定时间的操作。同样,对于每个单词,您循环遍历每个文件;再次,执行循环ONCE,并将结果存储在HashMap中。然后查找成为恒定时间。
答案 1 :(得分:1)
两个类都应该覆盖hashCode和equals。因此,你将决定什么是平等的。
然后你将在每个班级中创建一个集合。
public class MyFile implements Comparable<MyFile> {
//your fields here
Set<Word> words = new HashSet<Word>(0);
//Remember to override hashCode and equals
}
public class Word implements Comparable<Word> {
//your fields here
Set<MyFile> words = new HashSet<MyFile>(0);
//Remember to override hashCode and equals
}
在你的套装中你现在将拥有所有的MyFiles.words和其他方面,所有的Words.myFile
答案 2 :(得分:0)
我认为你希望文件知道它的单词并且单词知道使用它的文件。
public class File {
private List<Word> words;
public File(){
words=new Vector<Word>();
}
/**
*The method add word to word list.
**/
public addWord(Word word){
this.words.add(word);
word.addFile(this);
}
}
public class Word{
List<File> files;
public addFile(File file){
this.files.add(file);
}
}
反之亦然...但你应该质疑GRASP设计模式。也许你的数据类型是错误的(我不会说错,因为这是你的设计,所以我尊重)。