【问题标题】:Java Beginner: How do I link one linked list to another?Java 初学者:如何将一个链表链接到另一个链表?
【发布时间】:2011-01-18 16:01:06
【问题描述】:

如果我有:linkedlist1= 1,2,3,4;linkedlist2= 5,6,7;

如果我调用:linkedlist2.set(0,9999) 是否可以将linkedlist2 附加到linkedlist1 的末尾,它会更改为linkedlist2 = [999,6,7]linkedlist1 变为[1,2,3,4,9999,7,8];

这可能吗?或者我确实需要另一个结构?

以下代码不起作用:

 List<Double> l1 = new LinkedList<Double>(Arrays.asList(1.0,2.0));
 List<Double> l2 = new LinkedList<Double>(Arrays.asList(3.0,4.0));
 l1.addAll(l2);
 System.out.println(l1);
 l2.set(0, 9.0);
 System.out.println(l1);

输出:

 [1.0, 2.0, 3.0, 4.0]
 [1.0, 2.0, 3.0, 4.0]

【问题讨论】:

  • 提问时永远不要说“代码不起作用”。相反,请解释您期望的结果和得到的结果。否则真的很混乱,因为从技术上讲,代码的工作方式不是你想要的。
  • 为什么要这样做?与使用两种完全不同的方法来修改同一个对象相比,可能有一种更好的设计方法。

标签: java linked-list


【解决方案1】:

Java 提供的标准 LinkedList 类缺少此功能。

在 Donal Boyle 的帖子中,您可以将一个列表的内容添加到另一个列表,但这并不能保持您所描述的链接。

【讨论】:

  • 那么哪种数据结构确实提供了这种能力?
  • 我不知道有人提供。您可以编写一个符合 LinkedList 接口但为这种类型的拼接提供一些新方法的方法。
【解决方案2】:

您不能,但作为替代方案,您可以拥有一个列表列表,但我不知道这是否可以满足您的需要:

import java.util.*;
import static java.lang.System.out;
class ListOfLists { 
  public static void main( String ... args ) { 

    List<Integer> a = new LinkedList<Integer>(Arrays.asList(1,2,3,4));
    List<Integer> b = new LinkedList<Integer>(Arrays.asList(5,6,7));  

    List<List> list = new LinkedList<List>();
    list.add( a );
    list.add( b );

    out.println("Before : " + list );
    b.set( 0, 999 );

    out.println("After  : " + list );

  }
}

Before : [[1, 2, 3, 4], [5, 6, 7]]
After  : [[1, 2, 3, 4], [999, 6, 7]]

【讨论】:

    【解决方案3】:

    addAll() 只是从第二个链表中获取值。对第二个列表中的索引和设置值的更改不会影响第一个。 (注意:对对象本身的更改将保留,因为它们都指向同一个对象)。

    如果您正在寻找,您可以制作一个列表列表。

    【讨论】:

    • 不,我已经有一个列表的列表,并且正在使用 addall 添加列表,但现在我只需要平面链表,其中最后一个元素连接到另一个的第一个元素跨度>
    • 然后用 AddAll() 组合列表。列表中的对象是相同的,所以如果你使用不可变的东西,这不是问题。
    【解决方案4】:

    要回答有关更新一个列表并查看另一个列表中反映的更新的问题,答案视情况而定。

    如果您更新第一个列表中的对象,您将看到更改。但是如果您替换对象,您将看不到更改。在第一个列表上调用 .set() 正在替换列表中的对象。不幸的是,如果不替换原语(或其类表示形式,在本例中为 Float),就无法更新它的值。

    要追加两个列表,假设你使用的是java.util.LinkedList,你可以调用addAll

    【讨论】:

    • 我在回答中添加了更多信息,说明为什么这不适用于您放入列表中的对象。
    【解决方案5】:

    实现这一点的最简单方法是为您的项目设置一个适当的类,并让此类 MyInt 的实例相互链接,而不是依赖 LinkedList,即向自定义类添加 MyInt next; 字段保存你的整数。 然后按照描述链接它们。 然后可以在不触及列表结构的情况下完成对一个实例的更改,并在通过 next 引用迭代此列表时相应地反映出来。

    【讨论】:

      【解决方案6】:

      这个问题似乎是subList(int, int) 方法的一个很好的应用:

      List<Double> l1 = new LinkedList<Double>(Arrays.asList(1.0, 2.0, 3.0, 4.0));
      List<Double> l2 = l1.subList(2, 4);
      

      唉,subList 的 JavaDoc 声明:

      返回的列表的语义 如果 后备名单(即这个名单)是 结构修改 而不是通过返回的列表。 (结构修改是那些 更改此列表的大小,或 否则以这种方式扰乱它 正在进行的迭代可能会产生 结果不正确。)

      因此,如果您想在 l1 上使用 .add 之类的方法,那么您可能不走运。事实上,对于所有从AbstractList(如LinkedList)派生的fail-fast列表类,subList 应该在subList 的父列表被结构修改后抛出一个ConcurrentModificationException

      但是,如果您远离父列表中的结构修改(或者如果您在此类修改后重新创建子列表),那么一切都会按预期工作。

      【讨论】:

        猜你喜欢
        • 2021-01-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多