Java: 如何以有序的方式迭代LinkedList?
Java: how to iterate on a LinkedList in a sorted way?
是否可以在不排序的情况下检索链表的对象?
class MyClass<T> implements Iterable<T> {
private LinkedList<T> myList = new LinkedList<>();
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public T next() {
// SHOULD RETURN THE ELEMENTS OF MYLIST IN A SORTED WAY
return null;
}
};
}
}
在这种情况下,我们可以假设类型 T 的对象具有用于排序的 Integer 字段
这是不可能的,除非您创建额外的方法来排序 'on-the-fly' 或将预先排序的列表存储在另一个对象中(我假设您不想更改原始列表顺序)。
两种方法都有成本:
- 您可以保留 'current' 索引的索引并查找整个列表中的下一个索引,但这会花费 CPU
- 您可以创建列表的私有副本并对其进行排序,return 这个新列表,但它会占用更多内存,并且您必须保持新列表的更新,以防原始列表有值改变了。
简答:否
排序有点像查找 运行 minimum/maximum,如果不遍历列表中的每个元素,您将无法找到它,因此您需要以某种方式对所有元素进行排序这样做是通过 Heap
这意味着如果您不想对列表本身进行排序,则需要额外的内存。
@Override
public Iterator<T> iterator() {
PriorityQueue<T> heap = new PriorityQueue<>(list);
return new Iterator<T>() {
@Override
public boolean hasNext() {
return !heap.isEmpty();
}
@Override
public T next() {
return heap.poll();
}
};
}
如果类型 T
实现了 Comparable<T>
,你可以这样做。
static class MyClass<T extends Comparable<T>> implements Iterable<T> {
private LinkedList<T> myList = new LinkedList<>();
@Override
public Iterator<T> iterator() {
return myList.stream().sorted().iterator();
}
}
public static void main(String[] args) {
MyClass<Integer> obj = new MyClass<>();
obj.myList.add(2);
obj.myList.add(0);
obj.myList.add(1);
for (int i : obj)
System.out.println(i);
System.out.println(obj.myList);
}
输出:
0
1
2
[2, 0, 1]
或者,您可以通过构造函数传递一个比较器。
static class MyClass<T> implements Iterable<T> {
private LinkedList<T> myList = new LinkedList<>();
private final Comparator<T> comparator;
public MyClass(Comparator<T> comparator) {
this.comparator = comparator;
}
@Override
public Iterator<T> iterator() {
return myList.stream().sorted(comparator).iterator();
}
}
是否可以在不排序的情况下检索链表的对象?
class MyClass<T> implements Iterable<T> {
private LinkedList<T> myList = new LinkedList<>();
@Override
public Iterator<T> iterator() {
return new Iterator<T>() {
@Override
public boolean hasNext() {
return false;
}
@Override
public T next() {
// SHOULD RETURN THE ELEMENTS OF MYLIST IN A SORTED WAY
return null;
}
};
}
}
在这种情况下,我们可以假设类型 T 的对象具有用于排序的 Integer 字段
这是不可能的,除非您创建额外的方法来排序 'on-the-fly' 或将预先排序的列表存储在另一个对象中(我假设您不想更改原始列表顺序)。
两种方法都有成本:
- 您可以保留 'current' 索引的索引并查找整个列表中的下一个索引,但这会花费 CPU
- 您可以创建列表的私有副本并对其进行排序,return 这个新列表,但它会占用更多内存,并且您必须保持新列表的更新,以防原始列表有值改变了。
简答:否
排序有点像查找 运行 minimum/maximum,如果不遍历列表中的每个元素,您将无法找到它,因此您需要以某种方式对所有元素进行排序这样做是通过 Heap
这意味着如果您不想对列表本身进行排序,则需要额外的内存。
@Override
public Iterator<T> iterator() {
PriorityQueue<T> heap = new PriorityQueue<>(list);
return new Iterator<T>() {
@Override
public boolean hasNext() {
return !heap.isEmpty();
}
@Override
public T next() {
return heap.poll();
}
};
}
如果类型 T
实现了 Comparable<T>
,你可以这样做。
static class MyClass<T extends Comparable<T>> implements Iterable<T> {
private LinkedList<T> myList = new LinkedList<>();
@Override
public Iterator<T> iterator() {
return myList.stream().sorted().iterator();
}
}
public static void main(String[] args) {
MyClass<Integer> obj = new MyClass<>();
obj.myList.add(2);
obj.myList.add(0);
obj.myList.add(1);
for (int i : obj)
System.out.println(i);
System.out.println(obj.myList);
}
输出:
0
1
2
[2, 0, 1]
或者,您可以通过构造函数传递一个比较器。
static class MyClass<T> implements Iterable<T> {
private LinkedList<T> myList = new LinkedList<>();
private final Comparator<T> comparator;
public MyClass(Comparator<T> comparator) {
this.comparator = comparator;
}
@Override
public Iterator<T> iterator() {
return myList.stream().sorted(comparator).iterator();
}
}