【问题标题】:How to add to an arraylist of linkedlists?如何添加到链表的arraylist?
【发布时间】:2014-04-21 20:25:28
【问题描述】:

如果这是一个愚蠢的问题,我很抱歉,但我是 Java 链表和数组表的新手。

我想做的是: 我有一个逐字逐句运行的文本文件。我想创建一个链表的 Arraylist,文本中的每个 uniqye 单词在链表中后跟它在文本中的单词。

考虑这段文字:猫走到红树前。

我希望 LinkedLists 的 Arraylist 是这样的:

那-猫-红色

|

猫 - 走路

|

到 -

|

红色 - 树

我现在拥有的是这样的:

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;
   }

它给了我很多错误。 我怎样才能做到最好? (使用链表,我知道哈希表和二叉树更好,但我需要使用链表)

【问题讨论】:

  • 忘记使用LinkedListArrayList,因此也忘记了这种类型转换。将您的变量声明为List 接口,并在初始化时确定正确的类实现。
  • 那我该怎么做呢?我很困惑。

标签: java arraylist linked-list add


【解决方案1】:

ArrayList 不是用于您的外部列表的最佳数据结构,并且至少您的部分困难源于不正确地使用列表列表。

在您的实现中,大概follows 是这样声明的 LinkedLists 的 ArrayList:

ArrayList<LinkedList<String>> follows = new ArrayList<>();

follows.contains(firstWord) 的结果永远不会为真,因为follows 包含 LinkedList 类型的元素,而不是 String。 firstWord 是一个字符串,因此不会是 follows 的元素,而是 ArrayList 的第一个元素,它是 follows 的元素

下面提供的解决方案使用Map,或更具体地说是HashMap,作为外部列表follows。 Map 更可取,因为在搜索第一个单词时,使用 map 的平均查找时间为 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() 将所有字符串转为小写,以便“the”和“The”被同等对待。 (请确保您也将其应用于 firstWord 的初始值,它不会出现在您提供的代码中。)

请注意,此解决方案和您最初的尝试都假定标点符号已被删除。

【讨论】:

    【解决方案2】:

    您不应该使用直接类实现,而是使用它们的接口来简化开发(以及其他原因)。因此,请改为每次和现在进行类型转换,将变量声明为 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]
    

    请注意,现在您可以将任何listOnelistTwo 的实现更改为LinkedList

    List<String> listOne = new LinkedList<>();
    //...
    List<String> listTwo = new LinkedList<>();
    

    而且代码的行为也是一样的。无需进行任何类型转换即可使其正常工作。

    相关:

    【讨论】:

    • 但是如果我在 while 循环中执行此操作(如在我的示例代码中)并且我希望列表 (listOne, listTwo) 等有一个动态名称我可以找到它们(比如命名它们与字符串 firstWord) 相同?
    • @user3439407 while 循环不会影响问题的行为,只是提供代码作为示例。如果你想通过他们的名字找到他们,你应该使用Map&lt;String, List&lt;String&gt;&gt;,所以你使用了错误的方法......
    • 那不是哈希图吗?我必须使用链表。 :(
    • @user3439407 Map 是接口,有几个实现:HashMapLinkedHashMapTreeMapConcurrentHashMap... 看起来你还是不明白编程到接口。
    猜你喜欢
    • 2015-01-28
    • 1970-01-01
    • 2020-11-08
    • 1970-01-01
    • 2015-03-30
    • 1970-01-01
    • 2017-09-19
    • 1970-01-01
    • 2019-05-29
    相关资源
    最近更新 更多