【问题标题】:Fewest lines of code for creating a new collection of predicated values in a collection [closed]在集合中创建新的谓词值集合的最少代码行[关闭]
【发布时间】:2012-12-09 07:28:02
【问题描述】:

我正在编写一些有时需要但不经常需要的代码,我想知道为什么它需要这么多行代码。我需要使用从另一个集合的对象中的方法返回的字符串创建一个新集合。我可能会在该类的三种不同方法上执行此操作三次。我想番石榴中可能有一些东西可以帮助我。比如:

collection = Iterators.collectNotNull( myCollection, new Function...{
    public String apply( MyObject input ) {
        String value = input.getStringValue();
        if ( StringUtils.isEmpty( value )
            return null;
        return value; } );

我的意思是这对我来说甚至是太多的代码行。但无论哪种方式,我基本上都是在需要的时候写上面的。

所以问题是,谁能用更少的代码更简单地做到这一点?您可以使用现有的主流库,例如 Apache commons 或 Guava。如果您想消除创建匿名内部以获取将返回值的方法的需要,则反射是可以的。以上是我最好的尝试,但我必须编写可重用的“collectNotNull”方法。我宁愿不必这样做。

【问题讨论】:

  • 我不明白你想要完成什么。您需要将空字符串转换为 null 吗?
  • 你为什么关心它有多少行代码?如果这是您反复做的事情,请创建一个可以重复使用的方法。
  • 没有理由。我只是注意到我在这方面做了很多变化,而且在 Java 中它比在其他语言中更麻烦。想知道是否有比 Ruby、Python 或 Smalltalk 更简单但特定于 Java 的习语。
  • 当然是在 Jahroy 方法中。

标签: java collections


【解决方案1】:

如果您的目标是 代码,那么显而易见的方法是最好的。

 List<String> list = Lists.newArrayList();
 for (MyObject input : myCollection) {
   String value = input.getStringValue();
   if (!value.isEmpty()) {
     list.add(value);
   }
 }

Guava wiki page on functional idioms:他们通常是矫枉过正。

【讨论】:

  • 这基本上是我最终得到的,但我使用匿名内部来获取字符串值。我这样做只是因为我必须调用它三次才能生成 IN CLAUSES 我正在 OR'ing 一起为一个对象的三个方法。基本上就像#getName 的一个IN 子句,#getAlternativeName 的另一个IN 子句,等等。在这个例子中#getName 是#getStringValue。
  • 使用上述但为#getName1、#getName2 和#getName3 复制的另一个问题是,如果我现在需要检查#getStringValue == null 以及“”,那么我必须记得用三种方法更新它。这就是为什么我只是将三个迭代放在一个函数中,该函数采用匿名内部进行值提取。
  • 如果您真的担心 空值是可能的,那么只需考虑一个方法或使用例如Strings.emptyToNull。但更现实的是,您永远不应该将空字符串和空字符串混为一谈:从一开始就使用空字符串。
  • 我仍然不明白为什么匿名类比仅仅分解出一个普通的日常方法更可取。
  • 我喜欢 Guava wiki 页面! ... “当你竭尽全力让你的代码“单行”时,Guava 团队会哭泣。”
【解决方案2】:

这个:

 myCollection.removeAll(Arrays.asList(null, ""));

例子:

List<String> myCollection = new LinkedList<String>(Arrays.asList("a", "", "b", null, "c"));
System.out.println(myCollection);
myCollection.removeAll(Arrays.asList(null, ""));
System.out.println(myCollection);

生产:

[a, , b, null, c]
[a, b, c]

更新: 虽然这不是很笼统,但您可以保留或删除所有与此相同的元素。

在 Java 8(可预览版)中,您可以这样做:

myCollection.filter(s -> s != null && !s.isEmpty())

然后对结果做一些事情(add into() 以将它们添加到列表或 map() 进一步等)。

【讨论】:

  • 对,在 Java 8 中有很多更好的方法可以做到这一点。顺便说一句,这里的问题是从输入集合中每个对象的方法的非空调用中获取新集合。
  • 如果它只是一个新集合,那么剩下的问题就很容易了。 collection = new ArrayList&lt;String&gt;(myCollection).removeAll(...)
【解决方案3】:

如果 Java 有高阶函数……

好吧,我们不要走那条路。

在 Java 中更接近这一点的一种方法是使用 foreach

for (Collect<Type> each: ForEach.collect(input)) 
    each.yield = each.value.method(); 
for (Reject<String> each: ForEach.reject(ForEach.result())) 
    each.yield = each.value.isEmpty(); 
result = ForEach.result()

【讨论】:

    猜你喜欢
    • 2019-03-17
    • 1970-01-01
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 2011-04-16
    • 1970-01-01
    • 2021-08-22
    相关资源
    最近更新 更多