我如何在Java中实现自己的通用功能列表实现协变?
我主要是在Java中实现自己的链接列表,主要是为了学习语法。我在Scala有一些经验,并且正在尝试实现功能性,不可变的链接列表。我很难理解如何制作协变量的串联方法。我希望能够与(to)a list< super>
相连(附加)a list< sub>
。
public abstract List<T> {
public abstract T head();
public abstract List<T> tail();
public abstract boolean isEmpty();
// ... more methods
public List<T> concat(List<? extends T> that) {
if (this.isEmpty()) return (List<T>) that; // Gross
else return new Cons<>(this.head(), this.tail().concat(that));
}
}
public class Cons<T> extends List<T> {
private final T head;
private final List<T> tail;
public boolean isEmpty() {return false;}
public Cons(T head, List<T> tail) {this.head = head; this.tail = tail;}
public T head() {return head;}
public List<T> tail() {return tail;}
}
public class Nil<T> extends List<T> {
public T head() {throw new NoSuchElementException();}
public List<T> tail() {throw new NoSuchElementException();}
public boolean isEmpty() {return true;}
}
我似乎只能通过将子类型的列表明确地投入到看起来很丑陋的超级类型列表中来做到这一点。我本质上是在尝试模仿Scala的列表[+T]
协方差形式主义。干杯。
I am implementing my own linked list in Java mainly as an attempt to learnt the syntax. I have some experience in Scala, and am trying to implement a functional, immutable linked list. I'm having trouble understanding how to make a covariant concatenation method. I want to be able to concatenate (append) a List<Sub>
with (to) a List<Super>
.
public abstract List<T> {
public abstract T head();
public abstract List<T> tail();
public abstract boolean isEmpty();
// ... more methods
public List<T> concat(List<? extends T> that) {
if (this.isEmpty()) return (List<T>) that; // Gross
else return new Cons<>(this.head(), this.tail().concat(that));
}
}
public class Cons<T> extends List<T> {
private final T head;
private final List<T> tail;
public boolean isEmpty() {return false;}
public Cons(T head, List<T> tail) {this.head = head; this.tail = tail;}
public T head() {return head;}
public List<T> tail() {return tail;}
}
public class Nil<T> extends List<T> {
public T head() {throw new NoSuchElementException();}
public List<T> tail() {throw new NoSuchElementException();}
public boolean isEmpty() {return true;}
}
I seem to only be able to do this by explicitly casting the list of subtypes to a list of supertypes which seems ugly. I'm essentially trying to mimic Scala's List[+T]
covariance formalism. Cheers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
就java而言,
list&lt; subclass&gt;
不是list&lt; superClass&gt;
,否则就没有办法告诉它。不支持协方差和违反。我可以在这里想到一些选项:
concat
作为返回list&lt;?扩展了T&gt;
,而不是承诺它将完全返回list&lt; t&gt;
。list
类是不可变的,因此可以安全地重新诠释list&lt; subclass&gt;
作为一个list&lt; superClass&gt;
,因此您可以施放它,再加上适当的@suppresswarnings
带有注释的注释。 (您可能需要将其集中在私有upcast
方法中。)cons.tail
为具有类型list&lt;?扩展了T&gt;
,并且只要您需要从列表转换时?将superclass&gt;
扩展到list&lt; superClass&gt;
,您可以通过破坏和重建来做到这一点 - 创建一个新的cons&lt&lt; superclass&gt;
or ; 具有相同的字段。 (声明cons.tail
为列表&lt;? )(与#2一样,您可能需要将其集中在私有
upcast
方法中,nil
andcons
每个人都可以适当地实现)As far as Java is concerned, a
List<Subclass>
isn't aList<Superclass>
, and there's no way to tell it otherwise. Neither covariance nor contravariance is supported.I can think of a few options here:
concat
as returningList<? extends T>
, rather than promising that it will return exactlyList<T>
.List
class is immutable, it's safe to reinterpret aList<Subclass>
as aList<Superclass>
, so you can just cast it, plus an appropriate@SuppressWarnings
annotation with a comment. (You'll probably want to centralize this in a privateupcast
method.)Cons.tail
as having typeList<? extends T>
, and whenever you need to convert fromList<? extends Superclass>
toList<Superclass>
, you can do so by destructuring and reconstructing — creating a newCons<Superclass>
orNil<Superclass>
with the same fields. (The reason to declareCons.tail
asList<? extends T>
is so that you don't need to copy the whole list over, but just the first cons.) (As with #2, you'll probably want to centralize this in a privateupcast
method, whichNil
andCons
can each implement appropriately.)