java 使用Stream将列表中的元素移动到第一个位置

2guxujil  于 2023-01-01  发布在  Java
关注(0)|答案(1)|浏览(1436)

我已经写了这段代码,我想把它转换成stream和,同时保持相同的行为。

List<String> str1 = new ArrayList<String>();
str1.add("A");
str1.add("B");
str1.add("C");
str1.add("D");

int index = str1.indexOf("C");

if ((str1.contains("C")) && (index != 0)) {
    str1.remove("C");
    str1.add(0, "C");
}
wfveoks0

wfveoks01#

您可以简化:

int index = str1.indexOf("C");

if ((str1.contains("C")) && (index != 0)) {
    str1.remove("C");
    str1.add(0, "C");
}

作为

if (str1.remove("C")) { 
    str1.add(0, "C"); 
}

(检查javadoc中的remove(Object)。它删除它找到的对象的第一个示例,如果对象被删除,则返回true。不需要查找和测试对象的索引。)
在这一点上,你可能应该停止。

  • 一个小问题是,如果"C"是第一个元素,那么您将删除它并再次添加它......这是不必要的。
int index = str1.index("C");
if (index > 1) {
    str1.add(0, str1.remove(index));
}
  • 您可以进一步优化以避免删除和添加的重复复制。例如(感谢@Holger):
Collections.rotate(str1.subList(0, str1.indexOf("C") + 1), 1);

(But如果你说那很简单,一个普通的Java程序员可能会抛给你一些东西。它需要仔细阅读Javadoc才能理解这实际上是高效的。)

  • 你可以把它重写为两个流操作,但是这样做没有意义。两个操作(先移除和插入到流中)效率都很低,而且实现起来很棘手。棘手的实现意味着很难阅读。

注意:使用流来解决每个问题并不是一个明智的目标。流的 * 要点 * 是用一种比传统循环更容易阅读和维护的方式来表达复杂的转换。如果一个问题的唯一基于流的解决方案实际上比非流解决方案更 * 难阅读和维护,那就清楚地表明你不应该尝试使用流来解决 * 那个 * 问题!
注意,上面的解决方案是针对 * 所述 * 的问题的。然而,如果元素的对象标识实际上很重要,那么上面的解决方案中唯一一个实际上将对象 * 移动 * 到列表开头的解决方案是使用rotate的解决方案。

相关问题