Tos*_*vos 6 java generics iterator list wildcard
我想创建一个迭代器类,它允许我遍历具有泛型类型(例如lst1 integer,lst2 string)的列表.为此,我必须考虑以下给定的情况.
该接口是通用迭代器.这部分代码无法修改.
interface Iterator<E> {
E next ();
boolean hasNext();
}
Run Code Online (Sandbox Code Playgroud)
列表类也定义如下.最重要的是,列表对象可以使用方法getIterator()返回迭代器对象.这部分代码无法修改.
class List<T> {
class ListNode {
T val;
ListNode next;
ListNode (T v) {
val = v; next = null;
}
}
ListNode head;
List (ListNode hd) { head = hd; }
List () { this(null); }
void prepend (T val) {
ListNode p = new ListNode(val);
p.next = head;
head = p;
}
//some other methods
class ListIterator implements Iterator<T> {
ListNode pos;
ListIterator () {
pos = head;
}
public T next () {
T res = pos.val;
pos = pos.next;
return res;
}
public boolean hasNext () {
return pos != null;
}
}
Iterator<T> getIterator () {
return this.new ListIterator();
}
}
Run Code Online (Sandbox Code Playgroud)
让我们假设两个列表具有相同的类型,现在它们也具有相同的长度.我尝试使用两个迭代器对象创建一个类,并使用迭代器对象的方法来实现接口Iterator.这部分代码是由我创建的,可以修改.
class ZipIterator<T> implements Iterator<T>
{
int counter;
Iterator<T> first;
Iterator<T> second;
ZipIterator (Iterator<T> f, Iterator<T> s)
{
first = f;
second = s;
counter = 0;
}
public T next ()
{
if (counter % 2 == 0)
{
counter++;
return first.next();
}
else
{
counter++;
return second.next();
}
}
public boolean hasNext ()
{
if (counter % 2 == 0)
return first.hasNext();
else
return second.hasNext();
}
}
Run Code Online (Sandbox Code Playgroud)
这适用于具有相同类型的两个列表.这是我用于测试的代码和输出:
class IteratorUtils
{
public static void main (String[] args)
{
List<Integer> lst1 = new List<>();
List<Integer> lst2 = new List<>();
lst1.prepend(3);
lst1.prepend(2);
lst1.prepend(1);
lst2.prepend(8);
lst2.prepend(9);
lst2.prepend(10);
Iterator<Integer> it1 = lst1.getIterator();
Iterator<Integer> it2 = lst2.getIterator();
ZipIterator<Integer> zit = new ZipIterator<>(it1, it2);
while (zit.hasNext())
{
System.out.println(zit.next());
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出:
1
10
2
9
3
8
Run Code Online (Sandbox Code Playgroud)
现在我想以通用方式实现ZipIterator,因此我可以使用两个具有不同类型项的列表(例如整数和字符串).我知道我必须更改ZipIterator类,所以方法next()返回泛型类型,但我不知道如何.这是我必须要做的大学任务,教授已经留下了一个提示"使用如下的外卡:?扩展T,?超级T,?extends Object".但是通过外卡,我只能指定继承方向中的类型或对抗继承方向的类型,对吧?这是否可以以这种方式更改ZipIterator类,以便它接受两个具有不同类型的迭代器对象?
我不会给出完整的解决方案(从你的努力来看,你并不想要它),但我会尝试以一种让你自己找到它的方式进行解释。
首先,一个不相关的注释:您正在指定特定的迭代顺序。我认为这很好,我不会碰它。
你的教授给了你使用有界泛型的提示。让我们了解为什么需要它们(另请参阅此处和/或此处的教程)。如果您被要求编写一个接受两种未知类型中任意一种参数的方法,您的解决方案将是找到并采用它们的共同超类 - Object
。
在泛型中,情况类似 - 找到最常见的分母,只是语法有点棘手。如果你要写构造函数
ZipIterator(Iterator<Object> f, Iterator<Object> s) {...}
Run Code Online (Sandbox Code Playgroud)
并尝试初始化
List<Integer> lst1 = new List<>();
List<String> lst2 = new List<>();
new ZipIterator(it1, it2);
Run Code Online (Sandbox Code Playgroud)
你会得到一个编译错误(阅读它)。这是因为 aList<String>
不是 a List<Object>
,尽管 aString
是 an Object
。正确的方法是
ZipIterator(Iterator<? extends Object> f, Iterator<? extends Object> s) {...}
Run Code Online (Sandbox Code Playgroud)
其中? extends Object
表示“任何扩展的类型Object
”(这是所有类型,因为Object
......)。
所以你有了构造函数,你需要对你的类进行更改才能适应它。你甚至不需要实现给定的Iterator<E>
,你只需像你已经做的那样持有其中的两个。最后,类本身不需要具有泛型类型:因为它的next
方法必须能够返回任何类型,所以它总是返回Object
。
如果您在以后尝试解决此问题时有任何疑问,或者您发现此解决方案不符合作业要求,请随时发表评论。
归档时间: |
|
查看次数: |
607 次 |
最近记录: |