从索引创建子列表

4

是否可以仅使用元素索引从另一个列表创建一个子列表? 我正在寻找简洁的解决方案,例如 Java 8 中的 Lambda 和 Stream。

例如(伪代码):

a = [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
b = a.getByIndices([0, 2, 4, 5, 3])
print(b) // [10, 8, 6, 5, 7]

当然是“可能的”。我可以想到如何使用for循环来实现,但对于流处理我没有什么可说的。 - Nayuki
5
你试过什么吗? - RealSkeptic
@RealSkeptic:我曾考虑使用过滤器,但是接下来我必须调用indexOf并检查索引是否在索引列表中。我认为这不是一个高效的解决方案。 - dragon7
4个回答

9
您可以使用以下方法:

您可以采用以下方法:

private static <T> List<T> getByIndices(List<T> list, List<Integer> indexes) {
    return indexes.stream().map(list::get).collect(toList());
}

这将从给定索引创建一个Stream,将其映射到列表中的元素,并将结果收集到一个列表中。

使用示例:

List<Integer> list = Arrays.asList(10, 9, 8, 7, 6, 5, 4, 3, 2, 1);
List<Integer> indexes = Arrays.asList(0, 2, 4, 5, 3);
System.out.println(getByIndices(list, indexes)); // prints [10, 8, 7, 6, 5]

6

对于整数数组,您可以使用以下方法:

int[] b = IntStream.of(0, 2, 4, 5, 3)
      .map(i -> a[i])
      .toArray();

1
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Alexis C.

2
扩展{{link1:AbstractList}}是快速启动列表实现的一种方法。像常规{{link2:List.subList}}方法一样,以下子列表由主列表支持,因此对子列表的更改将写入主列表(这可能是您想要的特性,但如果需要,您始终可以从子列表创建一个新的独立ArrayList)。通过子列表删除元素未实现;虽然可行,但需要更多的工作。
public static <E> List<E> sublistFromIndices(List<E> list, int... indices) {
    Objects.requireNonNull(list);
    Objects.requireNonNull(indices);
    return new AbstractList<E>() {
        @Override
        public int size() {
            return indices.length;
        }

        @Override
        public E get(int index) {
            return list.get(indices[index]);
        }

        @Override
        public E set(int index, E element) {
            return list.set(indices[index], element);
        }
    };
}

0
我写了一个能够实现你要求的函数。虽然我还不知道如何将它转换成 Lambda 函数,但我会继续努力的。
public static <E> void createSublist(List<E> oldList, List<E> newList, int[] indicies){
        for(int i = 0; i < indicies.length; i++)
             newList.add(oldList.get(indicies[i]));} //Adds indicies to new list

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接