Java:展平列表或对象的列表,保留类

Posted

技术标签:

【中文标题】Java:展平列表或对象的列表,保留类【英文标题】:Java: flatten a list of lists OR objects, preserving class 【发布时间】:2021-07-06 09:56:54 【问题描述】:

我想在类FunctionalList<E> implements List<E> 中编写一个方法flatten()。然而,实际上扁平化列表并不是问题。我需要保留原始列表的最深包含的类。

我假设原始列表包含一些元素,因此存在一些 <T> 类,使得类型为 T 的扁平列表的每个元素。我想要返回FunctionalList<T> 的方法。但是,我想不出获得这个类的方法,因为我正在使用泛型,所以这个问题变得特别困难。

我编写了一个简单的递归算法来展平列表:

public <T> FunctionalList<T> flatten()
    FunctionalList<T> l = new FunctionalList<T>();
    for(E e : this)
        if(e instanceof FunctionalList)
            l.addAll(((FunctionalList<?>)e).flatten());
        else
            l.add((T)e);
    
    return l;

但看起来这总是返回FunctionalList&lt;Object&gt;,这并不理想。有什么方法可以将[1, 2, [3, 4, 5, [6], 7], [8, 9], 10] 展平为[1, 2, 3, 4, 5, 6, 7, 8, 9, 10],同时将结果存储为List&lt;Integer&gt;(或类似)?

【问题讨论】:

FunctionalList 应该是泛型的,而不仅仅是本例中的方法。 所以 E 是 T 的超类,你试图找到最特化的 T?还是就像在方法中重用 E 一样简单,当然不再声明它? @Sebastian E 在这种情况下很可能是 Object,因为这是我所知道的包含 T 和 List 的唯一方法。 【参考方案1】:

我想出了一个解决方案......各种各样的。

创建一个接口Listable&lt;E&gt;,它充当实现类EList&lt;E&gt; 的契约。即FunctionalList&lt;E&gt; implements Listable&lt;E&gt;。然后写方法:

public static <L extends Listable<L>> FunctionalList<L> flatten(FunctionalList<? extends Listable<L>> l)
    FunctionalList<L> r = new FunctionalList<L>();
    for(Listable<L> e : l)
        if(e instanceof FunctionalList)
            r.addAll(flatten((FunctionalList<? extends Listable<L>>)e));
        else
            r.add((L)e);
    
    return r;

最后,创建一些类以包含在实现 Listable 的扁平化列表中,例如public class MyInteger implements Listable&lt;MyInteger&gt;。静态 flatten 方法现在可以根据需要返回 FunctionalList&lt;MyInteger&gt;

然而,这有点限制,因为该方法现在只适用于实现接口Listable 的元素。我想知道是否有更通用的解决方案。

【讨论】:

以上是关于Java:展平列表或对象的列表,保留类的主要内容,如果未能解决你的问题,请参考以下文章

R(purrr)展平命名列表列表以列出并保留名称

如何在保留列表名称和值的同时展平一列列表? [r] [重复]

python 展平一系列Excel列,这些列在单元格中包含列表,同时保留行。允许为不可打印的U设置错误级别

使用 jq 保留键名展平 JSON

如何删除列表中重复的构造对象,同时保留顺序并在飞镖中返回列表?

将列表加入 Pandas 框架 - 我是不是保留了订单?