加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 了解从HashSet生成的流中元素的顺序

发布时间:2020-12-15 00:51:32 所属栏目:Java 来源:网络整理
导读:我读了这篇 Java 8官方文档: Streams may or may not have a defined encounter order. Whether or not a stream has an encounter order depends on the source and the intermediate operations. Certain stream sources (such as List or arrays) are in
我读了这篇 Java 8官方文档:

Streams may or may not have a defined encounter order. Whether or not
a stream has an encounter order depends on the source and the
intermediate operations. Certain stream sources (such as List or
arrays) are intrinsically ordered,whereas others (such as HashSet)
are not.
If a stream is ordered,repeated execution of identical
stream pipelines on an identical source will produce an identical
result; if it is not ordered,repeated execution might produce
different results.

试图通过此代码了解上述行为

public class StreamOrderValidator
{
    public static void main( String[] args )
    {
        String[] colors=new String[] {"red","green","blue","orange"};
        List<String> colorsList=Arrays.asList(colors);

        HashSet<String> colorsSet=new HashSet<>();
        colorsSet.addAll(colorsList);
        System.out.println(colorsSet);            // [red,orange,green,blue]

        List<String> processedColorsSet = processStream(colorsSet.stream());
        System.out.println(processedColorsSet);   // [RED,ORANGE,GREEN,BLUE]
    }

    private static List<String> processStream(Stream<String> colorStream) {
        List<String> processedColorsList = colorStream.filter(s->s.length()<=6).
                map(String::toUpperCase).collect(Collectors.toList());
        return processedColorsList;
    }
}

我多次运行此代码,结果流中的元素顺序始终相同(显示为注释).我无法弄清楚这是如何证明以上引用的文字有关“命令不被保留为无序集合”.

我绝对误解了来自javadocs的提取文本.

解决方法

确实存在一些误解. HashSet或任何Set不是关于顺序的,除非基于Comparator排序的TreeSet.

目前,在java-8下,一旦你将元素放入一个HashSet(并且不改变它),就会有一个如何布局元素的顺序;但同样,在你不添加或删除任何一个的情况下.这可以随时改变,所以不要依赖它.

例如运行这个:

String[] colors = new String[] { "red","orange" };
 List<String> colorsList = Arrays.asList(colors);

 HashSet<String> colorsSet = new HashSet<>();
 colorsSet.addAll(colorsList);
 System.out.println(colorsSet);

无论在java-8下多少次,你总会获得相同的输出:

[red,blue]

但是一旦你做了一些内部重新洗牌:

for (int i = 0; i < 1000; ++i) {
        colorsSet.add("" + i);
    }

    for (int i = 0; i < 1000; ++i) {
        colorsSet.remove("" + i);
    }   


    System.out.println(colorsSet); // [blue,red,orange]

您可以看到输出更改,因为集合没有订单.
要点是没有顺序,事实上你确实看到订单不是每次都发生的保证 – 在java-8中可能会有一个破坏这个顺序的构建.事实上,例如java-9很容易观察到 – 其中有新的集合的随机化模式.

如果多次运行,结果会有所不同:

Set<String> set = Set.of("red","orange");
 System.out.println(set);

很明显,你从这样一个Set中流,订单将无法保证,因此你确实会看到不同的运行结果.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读