【问题标题】:Is it possible to implement method analogical to subList(a,b) but that works when a>b?是否可以实现类似于 subList(a,b) 但在 a>b 时有效的方法?
【发布时间】:2014-12-22 18:17:52
【问题描述】:

我想实现一个类似于 subList(a,b) 的方法,但是当 a>b 时有效。 subList(a,b) 和 subList(b,a) 应该返回相同范围的列表视图,但迭代和编号方式不同。在 a>b 的情况下,view 应该被颠倒。有可能吗?

我现在的解决方案非常原始。第一个问题是 subList(a,b) 在 a>b 的情况下没有相应地调整编号(对于 removeget 方法的使用)。但更重要的是,反转的 List 视图实际上是这里的副本而不是实际视图,我什至不知道如何解决。

@SuppressWarnings("serial")
class ReverseLinkedList <T> extends LinkedList<T>
{
    ReverseLinkedList(final List<T> l)
    {
        super(l); // problem, I want a view not a copy
    }
    @Override
    public Iterator<T> iterator()
    {
        return new Iterator<T>()
        {
            ListIterator<T> listIter = listIterator(size());
            public boolean hasNext() 
            { 
                return listIter.hasPrevious(); 
            }
            public T next() 
            { 
                return listIter.previous(); 
            }
            public void remove() 
            { 
                listIter.remove(); 
            }  
        };
    }
}

@SuppressWarnings("serial")
class CleverList<T> extends LinkedList<T>
{
    @Override
    public List<T> subList(int fromIndex, int toIndex)
    {
        if ( fromIndex < toIndex )
        {
            return super.subList(fromIndex, toIndex);
        }
        else
        {
            return new ReverseLinkedList<T>(super.subList(toIndex-1,fromIndex-1));
        }
    }
}

目前如何运作:

    CleverList<Integer> list = new CleverList<Integer>();
    for ( int i=1; i<=10; ++i )
    {
        list.add(i);
    }
    List<Integer> listA = list.subList(2,8);
    printList(listA);
    // "3 4 5 6 7 8 " ok
    List<Integer> listB = list.subList(8,2);
    printList(listB);
    // "7 6 5 4 3 2 " ok

    listB.remove(2);
    printList(listB);
    // "7 6 5 3 2 " not ok, the point was to remove "5"
    printList(list);
    // "1 2 3 4 5 6 7 8 9 10 " not ok, nothing was removed

【问题讨论】:

  • 您的课程是否必须扩展 LinkedList 还是只实现 List
  • @user2040251 我认为 List 就足够了。不过,我对 LinkedList 扩展有点好奇。

标签: java data-structures collections


【解决方案1】:

一种可能的解决方案是使用组合而不是继承。它可能看起来像这样:

class ReverseLinkedList<T> implements List<T> {
    // A reference to the actual list.
    private final List<T> list;

    public ReverseLinkedList(final List<T> list) {
        // Does not create a copy.
        // Stores a reference to the original list instead.
        this.list = list;
    }

    @Override 
    public T get(int index) {
        // Adjusts the index and calls the method on an actual list.
        return list.get(list.size() - 1 - index);
    }

    //And so on for all the other methods declared in the List interface...

}

它完全满足您的需求:它不会创建传递给构造函数的列表副本,您可以控制所有方法(get、remove 等)来正确调整索引。这种方法的缺点是需要编写大量代码:在List 接口中声明的每个方法都必须在ReverseLinkedList 类中定义。

【讨论】:

  • 是的,这是最好的解决方案。它还使您可以完全控制是否要将其作为原始列表的只读视图或直写视图。如果您不需要视图,但可以使用副本,您可以选择List&lt;X&gt; reverse = original.clone(); Collections.reverse(reverse);
  • 那么 interator() 和 listIterator() 方法呢?你能建议他们的实现吗?
  • @infoholic_anonymous 与其他方法几乎相同:创建一个实际列表的迭代器,然后使用 previous 来实现 next(反之亦然), hasPrevious 用于 hasNext 并调整所有涉及的操作的索引索引。
猜你喜欢
  • 2020-03-03
  • 2014-03-29
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-22
  • 1970-01-01
相关资源
最近更新 更多