我正在尝试编写一个subList方法,该方法返回一个由当前对象列表组成的列表,包含在索引fromIndex
和toIndex
之间。
例如,如果我有由
组成的列表3 5 7 9 11 20 23
我打电话给subList(0,3)
,我应该得到一个新的
3 5 7 9
返回。
我正在使用辅助方法来帮助编写方法。我编写此方法的逻辑是,我将头节点指定为索引fromIndex
处的节点,同时将列表中的最后一个节点分配给索引toIndex
处的节点,但不会返回任何内容。任何帮助表示赞赏!
编辑:我创建了一个添加方法,将节点添加到列表中。我仍在尝试编写自己的subList方法。
EDIT2:我更新了一些代码,可以在底部看到(忽略上面的旧代码)。 fromIndex和toIndex包含在新子列表中。
private class Node<N extends Comparable<N>> {
private N data;
private Node<N> next;
}
private Node<L> head;
public List() {
head=null;
}
public void add(Node<L> node) {
Node<L> add = new Node<L>();
add.data = node.data;
add.next = null;
getFinal().next = add;
}
public Node<L> getFinal(){
Node<L> node = head;
while (node.next != null) {
node = node.next;
}
return node;
}
public int size() {
if (head == null) return 0;
int counter = 0;
for (Node<L> curr = head; curr != null; curr = curr.next)
counter++;
return counter;
}
public List<L> subList(int fromIndex, int toIndex)
throws IndexOutOfBoundsException {
List<L> n=new List<L>();
Node<L> tail= new Node<L>();
n.head=nthItem(fromIndex);
tail=n.getFinal();
tail=nthItem(toIndex);
return n;
}
public Node<L> nthItem(int index) {
if (index < 0 || index >= size())
throw new IndexOutOfBoundsException();
Node<L> ptr = head;
int i = 0;
while (ptr != null) {
if (i == index) return ptr;
i++;
ptr = ptr.next;
}
throw new IndexOutOfBoundsException();
}
更新代码
private void add(Node<L> node) {
if(head==null){
head=node;
} else {
getFinal().next = node;
}
}
public List<L> subList(int fromIndex, int toIndex)
throws IndexOutOfBoundsException {
if(fromIndex<0 || fromIndex>size()-1 || toIndex<0 || toIndex>size()-1){ //size() is 1 bigger than max index so I subtract 1 from size() to equal them out
throw new IndexOutOfBoundsException();
}
List<L> n=new List<L>();
Node<L> startNode = head;
int counter=0;
while(startNode!=null){
if(counter>=fromIndex && counter<=toIndex){ //fromIndex and toIndex are inclusive so I've added the equals to them. However, it enters an infinite loop, which I do not understand why.
n.add(startNode);
}
startNode=startNode.next;
counter++;
}
return n;
}
答案 0 :(得分:1)
问题1 - 你为什么要这样做? LinkedList很好,不需要重写......
第2点(或b) - 您的子列表函数创建一个新列表,设置其头部,然后设置一个临时变量以包含子列表的所需尾部...
在链接列表中,如果您有一个节点,那么该节点将表示从该点开始的该列表的其余部分。要解决您的问题,您需要克隆所有节点以创建子列表,将最后一个克隆的尾部设置为null。
但为什么呢?
---编辑 - 澄清答案
public List<L> subList(int fromIndex, int toIndex) {
Node<L> currentInOriginal = nthItem(fromIndex);
int count = (toIndex - fromIndex) + 1;
List<L> newSubList = new List<L>();
newSubList.head = new Node<L>(current.data);
Node<L> lastItemInList = newSubList.head;
int soFar = 1;
currentInOriginal = currentInOriginal.next;
while(currentInOriginal!=null && soFar<count) {
lastItemInList.next = new Node<L>(currentInOriginal.data);
listItemInList = lastItemInList.next;
currentInOriginal=currentInOriginal.next;
soFar++;
}
return newSubList;
}
答案 1 :(得分:0)
你的方法不正确你必须从头开始循环并返回所有值,如果fromIndex和toIndex之间的索引。在开始之前,还需要验证提供的索引是否有效。
这一行
public List<L> subList(int fromIndex, int toIndex)
throws IndexOutOfBoundsException {
if(fromIndex<0 || fromIndex>size() || toIndex<fromIndex || toIndex>size()){
throw new IndexOutOfBoundsException();
}
List<L> n=new List<L>();
Node<L> startNode = head;
int counter=0;
while(startNode!=null){
if(counter>fromIndex && counter<toIndex){
n.add(startNode);
}
startNode=startNode.next;
counter++;
}
return n;
}
在这里我们检查fromIndex和toIndex是否有效,如果没有,那么它会抛出异常。 我们遍历整个列表&amp;放入仅在提供的索引之间的元素。
根据评论
是的,您的添加也不正确。 你想要做的是先设置头节点。
public void add(Node<L> node) {
if(head==null){
head=node;
} else {
getFinal().next = node;
}
}
答案 2 :(得分:0)
也许你已经知道了,但是,你试过LinkedList.sublist()
吗?这里有一个例子:
import java.util.LinkedList;
import java.util.List;
public class GetSubListLinkedListJavaExample {
public static void main(String[] args) {
//create LinkedList object
LinkedList lList = new LinkedList();
//add elements to LinkedList
lList.add("1");
lList.add("2");
lList.add("3");
lList.add("4");
lList.add("5");
System.out.println("LinkedList contains : " + lList);
/*
* To get a sublist from Java LinkedList, use
* List subList(int start, int end) method.
*
* This method returns portion of list containing element from start index
* inclusive to end index exclusive.
*/
List lst = lList.subList(1,4);
System.out.println("Sublist contains : " + lst);
/*
* Please note that sublist is backed by the original list, so any changes
* made to sublist will also be reflected back to original LinkedList
*/
//remove element from sublist
lst.remove(2);
System.out.println("Sublist now contains : " + lst);
System.out.println("Original LinkedList now contains : " + lList);
}
}
/*
Output would be
LinkedList contains : [1, 2, 3, 4, 5]
Sublist contains : [2, 3, 4]
Sublist now contains : [2, 3]
Original LinkedList now contains : [1, 2, 3, 5]
*/
希望它有所帮助。
Clemencio Morales Lucas。
答案 3 :(得分:0)
使用Java 8 Stream函数,您可以从任何给定类型的列表中获取子列表
如果要使用特定类型的List而不是List <>,则可以将方法中的返回类型转换为该特定类型的List
获取任何类型的给定列表的子列表,例如ArrayList,LinkedList,ArrayDeque 下面的方法可以用来获取任何类型的子列表
package com.techsqually.datastructure.collections.lists.linkedlist;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;
public class LinkedListTest {
public static void main(String[] args) {
LinkedList<Integer> giveString = new LinkedList<>();
giveString.add(1);
giveString.add(2);
giveString.add(3);
giveString.add(4);
giveString.add(3);
giveString.add(5);
System.out.println(giveString);
System.out.println(getSubList(giveString,0,3));
}
public static List getSubList(LinkedList<Integer> givenList, int startIndexInclusive, int endIndexExclusive){
return givenList.stream().collect(Collectors.toList()).subList(startIndexInclusive,endIndexExclusive);
}
}
输出:
[1、2、3、4、3、5]
[1、2、3]