如果这是一个愚蠢的问题,我很抱歉,但我是Java链接列表和arraylists的新手。
我想做的是: 我有一个文字文件,我逐字逐句地运行。我想创建一个链接列表的Arraylist,文本中的每个uniqye单词都在链接列表中跟随文本后面的单词。
考虑这段文字:猫走向红树。
我希望LinkedLists的Arraylist是这样的:
The - cat - red
|
猫 - 走路
|
到 -
|
红树 -
我现在拥有的是:
while(dataFile.hasNext()){
secondWord = dataFile.next();
nWords++;
if(nWords % 1000 ==0) System.out.println(nWords+" words");
//and put words into list if not already there
//check if this word is already in the list
if(follows.contains(firstWord)){
//add the next word to it's linked list
((LinkedList)(firstWord)).add(secondWord);
}
else{
//create new linked list for this word and then add next word
follows.add(new LinkedList<E>().add(firstWord));
((LinkedList)(firstWord)).add(secondWord);
}
//go on to next word
firstWord = secondWord;
}
它给了我很多错误。 我怎么能以最好的方式做到这一点? (使用链表,我知道哈希表和二叉树更好,但我需要使用链表)
答案 0 :(得分:0)
您不应该使用直接类实现,而是使用它们的接口来简化开发(以及其他原因)。因此,相反,每次都进行类型转换,将变量声明为List
,并在初始化时定义类。由于您尚未发布相关代码以重新定义它,我可以举例说明:
List<List<String>> listOfListOfString = new LinkedList<>(); //assuming Java 7 or later used
List<String> listOne = new ArrayList<>();
listOne.add("hello");
listOne.add("world");
listOfListOfString.add(listOne);
List<String> listTwo = new ArrayList<>();
listTwo.add("bye);
listTwo.add("world");
listOfListOfString.add(listTwo);
for (List<String> list : listOfListOfString) {
System.out.println(list);
}
这将打印:
[hello, world]
[bye, world]
请注意,现在您可以将listOne
或listTwo
中任意一项的实施更改为LinkedList
:
List<String> listOne = new LinkedList<>();
//...
List<String> listTwo = new LinkedList<>();
代码的行为也一样。无需进行任何类型转换即可使其正常工作。
相关:
答案 1 :(得分:0)
ArrayList
不是用于外部列表的最佳数据结构,并且至少部分困难源于错误使用列表列表。
在您的实现中,大概follows
是LinkedLists的ArrayList,声明如下:
ArrayList<LinkedList<String>> follows = new ArrayList<>();
follows.contains(firstWord)
的结果永远不会成立,因为follows
包含LinkedList类型的元素,而不是String。 firstWord
是一个String,因此不是follows
的元素,而是是ArrayList的第一个元素,它是follows
的元素。
下面提供的解决方案为外部列表Map
使用HashMap
或更具体的follows
。地图是可取的,因为在搜索第一个单词时,使用地图的摊销时间将为O(1),而对于列表则为O(n)。
String firstWord = dataFile.next().toLowerCase();
Map<String, List<String>> follows = new HashMap<>();
int nWords = 0;
while (dataFile.hasNext())
{
String secondWord = dataFile.next().toLowerCase();
nWords++;
if (nWords % 1000 == 0)
{
System.out.println(nWords + " words");
}
//and put words into list if not already there
//check if this word is already in the list
if (follows.containsKey(firstWord))
{
//add the next word to it's linked list
List list = follows.get(firstWord);
if (!list.contains(secondWord))
{
list.add(secondWord);
}
}
else
{
//create new linked list for this word and then add next word
List list = new LinkedList<String>();
list.add(secondWord);
follows.put(firstWord, list);
}
//go on to next word
firstWord = secondWord;
}
地图将如下所示:
the: [cat, red]
cat: [walks]
to: [the]
red: [tree]
walks: [to]
我还对您的实施做了以下更改:
不要将重复项添加到以下单词列表中。请注意,Set
对于此任务来说是更合适的数据结构,但您明确指出要求是使用LinkedList
。
使用String.toLowerCase()
将所有字符串移动到小写字母,以便&#34;&#34;&#34;和&#34;&#34;&#34;被等同地对待。 (请务必将此值应用于firstWord
的初始值,该值不会出现在您提供的代码中。)
请注意,此解决方案和原始尝试都假定标点已被删除。