【问题标题】:How to merge two unmodifiable Sets in Java? [duplicate]如何在 Java 中合并两个不可修改的 Set? [复制]
【发布时间】:2020-08-03 10:02:54
【问题描述】:

如何合并两个unmodifiable static final 集合?

public static final Set<Long> ORG_SUBSCRIBER_ALLOWED_NUMBER_CD = Set.of(COMPANY_GST, GOVERNMENT_BODY_GST);

public static final Set<Long> INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD = Set.of(BUSINESS_PAN, INDIVIDUAL_PAN);

我想把上面的静态最终集合合并成一个集合(单语句初始化),因为它是一个Class变量

public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = ?

【问题讨论】:

  • 创建另一个集合@Thirumal
  • SUBSCRIBER_ALLOWED_NUMBER_CD = Stream.concat(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD.stream(),INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD.stream()) .collect(Collectors.toSet());
  • 为什么这被否决了?看看弱答案 - 这个微不足道的问题没有简洁的 JDK-only 解决方案。

标签: java merge java-stream java-11 unmodifiable


【解决方案1】:

Stream#concat 也很有用

Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD  =  
         Stream.concat(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD.stream(),
                       INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD.stream())
                .collect(Collectors.toSet());

【讨论】:

    【解决方案2】:

    只是指出,Guava 仍然比仅 JDK 的解决方案更易读(并且可能性能更高):

    public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = ImmutableSet.builder()
        .addAll(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD)
        .addAll(INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
        .build();
    

    【讨论】:

      【解决方案3】:

      如果你想使用流:

      public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD =
          Stream.of(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD, INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
              .flatMap(Set::stream)
              .collect(Collectors.toSet());
      

      或者,在你的情况下,正如评论中提到的,你可以使用Collectors.toUnmodifiableSet():

      public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD =
          Stream.of(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD, INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
              .flatMap(Set::stream)
              .collect(Collectors.toUnmodifiableSet());
      

      【讨论】:

      • 我最喜欢这个,但改进了Collectors.toImmutableSet()(Java 10 中引入)
      • 我的意思是Collectors.toUnmodifiableSet()
      • 谢谢@drekbour,这也很有趣:)
      【解决方案4】:

      单语句初始化,如果愿意的话:

      public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = 
           Collections.unmodifiableSet(
              Stream.of(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD, 
                        INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD)
                    .flatMap(Set::stream)
                    .collect(Collectors.toSet()));
      

      或者,也许更具可读性:

      public static final Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD;
      static {
          Set<Long> all = new HashSet<>();
          all.addAll(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD);
          all.addAll(INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD);
          
          SUBSCRIBER_ALLOWED_NUMBER_CD = Collections.unmodifiableSet(all);
      }
      

      如果预计第三组不是不可修改的,则忽略 Collections.unmodifiableSet 调用。

      【讨论】:

      • 由于这是连接通过Set.of(…) 创建的两个集合,OP 可能希望使用收集器Collectors.toUnmodifiableSet() 而不是Collectors.toSet(),以获得具有相同语义的集合(将其包装在@ 987654327@ 就变得不必要了)。同样,替代方案可能使用Set.copyOf(…) 而不是Collections.unmodifiableSet(…)。它可能会导致稍长的初始化时间,这可以通过后续运行时可能更高的性能来补偿。
      【解决方案5】:

      您为什么不能创建第三个集合而只添加两个最终集合?

      Set<Long> SUBSCRIBER_ALLOWED_NUMBER_CD = new HashSet<>();
      SUBSCRIBER_ALLOWED_NUMBER_CD.addAll(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD);
      SUBSCRIBER_ALLOWED_NUMBER_CD.addAll(INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD);
      

      前两个集合是final 只是意味着您不能修改那些 集合。它不会阻止您将集合读入另一个新集合。

      【讨论】:

      • Set&lt;Long&gt; SUBSCRIBER_ALLOWED_NUMBER_CD = new HashSet&lt;&gt;(ORG_SUBSCRIBER_ALLOWED_NUMBER_CD);SUBSCRIBER_ALLOWED_NUMBER_CD.addAll(INDIVIDUAL_SUBSCRIBER_ALLOWED_NUMBER_CD);
      猜你喜欢
      • 2020-07-15
      • 2017-08-12
      • 1970-01-01
      • 2021-01-15
      • 2013-05-07
      • 2020-09-05
      • 2017-01-31
      • 2014-09-12
      • 2014-02-05
      相关资源
      最近更新 更多