【问题标题】:Java: anonymous Set<T> inside a function callJava:函数调用中的匿名 Set<T>
【发布时间】:2020-06-13 15:10:53
【问题描述】:

正如在这个问题Anonymous arrays in Java 中发现的那样,我为java.utils.Set 尝试了相同的过程,但它不起作用。

如果我有

private HashMap<String, String[]> flags;

我可以轻松调用

this.flags.put("test", new String[]{"value"});

但是有

private HashMap<String, Set<String>> flags;

不起作用

this.flags.put("test", new Set<String>().add("value"));

在Java中将匿名Set传递给函数的正确方法是什么?

【问题讨论】:

  • Set.add() 不返回 Set。而Set 是一个接口,这意味着你不能像那样实例化它。
  • 那么没有.add() 有可能吗? – this.flags.put("test", new Set&lt;String&gt;()); 也不会编译。
  • 您首先需要从具体类创建一个集合,例如HashSet。然后你把那个集合,而不是add 的结果。 this.flags.put("test", new HashSet&lt;&gt;(Arrays.asList("value")); 之类的东西应该可以工作
  • Jup,这确实可以编译。谢谢! @ernest_k

标签: java arrays methods hashmap set


【解决方案1】:

试试这个:

第一次遇到时,它会添加HashSet 并添加值。下次遇到它会将值添加到 hashSet。

this.flags.computeIfAbsent("test", v-> new HashSet<>()).add("value");

【讨论】:

  • 坚果。我放错了括号。
【解决方案2】:

Set.of

如果您希望新设置为 non-modifiable,并且没有空值,请使用 Set.of

private Map< String , Set< String > > flags = new HashMap<>() ;
…
this.flags.put( "test" , Set.of( "value" ) );

【讨论】:

    【解决方案3】:

    如果您尝试添加匿名 Set,那么在这种情况下,您还需要完整地实现您的 Set-

    例如:

            HashMap<String, Set<String>> valueMap = new HashMap<>();
    
    
            valueMap.put("test", new Set<String>() {
    
                @Override
                public boolean add(String e) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public boolean addAll(Collection<? extends String> c) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public void clear() {
                    // TODO Auto-generated method stub
    
                }
    
                @Override
                public boolean contains(Object o) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public boolean containsAll(Collection<?> c) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public boolean isEmpty() {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public Iterator<String> iterator() {
                    // TODO Auto-generated method stub
                    return null;
                }
    
                @Override
                public boolean remove(Object o) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public boolean removeAll(Collection<?> c) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public boolean retainAll(Collection<?> c) {
                    // TODO Auto-generated method stub
                    return false;
                }
    
                @Override
                public int size() {
                    // TODO Auto-generated method stub
                    return 0;
                }
    
                @Override
                public Object[] toArray() {
                    // TODO Auto-generated method stub
                    return null;
                }
    
                @Override
                public <T> T[] toArray(T[] a) {
                    // TODO Auto-generated method stub
                    return null;
                }
            });
    
    
    

    更好更简单的方法是

    valueMap.put("test", new HashSet<String>(){{
                add("a");
                add("b");
                add("c");
            }});
    

    【讨论】:

    • 这些双括号{{}} 的作用是什么?
    • 那是一个双括号初始化。外大括号是 HashSet 的匿名类创建,第二个大括号用于初始化。
    • 这是一个块初始化器。但是这种技术在 Java 社区中已经失宠了。
    • 是的,我同意这是一项昂贵的操作
    【解决方案4】:

    我不建议以匿名方式创建集合,而是可以使用一些实用方法,例如 Collections.singleton 用于 java-8 版本代码,您可以使用 Set.of 用于 java-9 及更高版本

    一个只包含指定对象的不可变集合。

    this.flags.put("test", Collections.singleton("value"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-09-11
      • 2013-02-23
      • 1970-01-01
      • 2018-11-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多