【问题标题】:Java, Lambda: How to pick a List from a Class with several Lists of different Types? [duplicate]Java,Lambda:如何从具有多个不同类型列表的类中选择一个列表? [复制]
【发布时间】:2017-10-24 10:11:03
【问题描述】:

在 Java 8 中,从具有多个不同类型 {List<Type1>, List<Type2>, List<Type3>, ..} 的列表的对象列表(记录)中挑选和收集 Lists<T> 的最佳方法是什么?

Type1、Type2、Type3 等互不相关。 T = Type1,Type2,Type3 ...

List<Records> allRecords;

class Records {
    List<Type1> listOfType1; // can be empty or null
    List<Type2> listOfType2; // can be empty or null
    List<Type3> listOfType3; // can be empty or null
}

List<T> getAllOccurrencesForType(T t, List<Records> allRecords) {
    return ?all occurrences of List<t> from all Records collected to one List? 
}

【问题讨论】:

  • 如果您的代码是这样的,那么每种类型恰好出现一次,您可以使用 record.getListOfType1()。也许您将这些列表动态添加到记录类中?
  • 我同意@luk2302 - 看起来你又在问同样的问题。也许我错了 - 但请解释为什么需要第二个问题以及它与您之前提出的不同之处?!
  • Veselin Davidov,感谢您的评论。该列表可以有多个记录,并且每个记录的每种类型都有一个列表。
  • @luk2302, @GhostCat:谢谢你的提示。我会尽快检查这个。昨天我请我的一位同事尝试为这项任务找到解决方案,他在我的电脑上工作,而我正在开会。我假设他使用我的帐户发布了相同的问题。如果是这样,我会将其标记为重复。再次感谢!

标签: java lambda filter prediction


【解决方案1】:

我相信传递一个返回所需List 的getter Function 可以工作:

static <T> List<T> getAllOccurrencesForType(Function<Records,List<T>> getter, List<Records> allRecords) {
    return allRecords.stream()
                     .flatMap(r->getter.apply(r).stream())
                     .collect(Collectors.toList());
}

然后你调用它:

List<Type1> getAllOccurrencesForType (Records::getListOfType1,allRecords);

这是一个完整的例子:

class Records {
    List<String> listOfType1;
    List<Integer> listOfType2;
    List<Double> listOfType3;
    public Records (List<String> l1, List<Integer> l2, List<Double> l3) {
      listOfType1 = l1;
      listOfType2 = l2;
      listOfType3 = l3;
    }
    public List<String> getListOfType1() {
      return listOfType1;
    }
    public List<Integer> getListOfType2(){
      return listOfType2;
    }
    public List<Double> getListOfType3(){
      return listOfType3;
    }
}

一些main方法:

 List<Records> recs = new ArrayList<> ();
 recs.add (new Records (Arrays.asList ("a","b"), Arrays.asList (1,2), Arrays.asList (1.1,4.4)));
 recs.add (new Records (Arrays.asList ("c","d"), Arrays.asList (4,3), Arrays.asList (-3.3,135.3)));
 List<String> allStrings = getAllOccurrencesForType(Records::getListOfType1,recs);
 List<Integer> allIntegers = getAllOccurrencesForType(Records::getListOfType2,recs);
 List<Double> allDoubles = getAllOccurrencesForType(Records::getListOfType3,recs);
 System.out.println (allStrings);
 System.out.println (allIntegers);
 System.out.println (allDoubles);

输出:

[a, b, c, d]
[1, 2, 4, 3]
[1.1, 4.4, -3.3, 135.3]

【讨论】:

  • 嗨,Eran,很好的答案,非常感谢 :-) 我收到以下编译错误,因为 r-&gt;getter.apply(r) 来自方法 getAllOccurrencesForType()Cannot infer type argument(s) for &lt;R&gt; flatMap(Function&lt;? super T,? extends Stream&lt;? extends R&gt;&gt;)
  • @ThomasMuller 我发布的代码通过了编译并在 Eclipse Neon 上运行。您使用的是什么 IDE?
  • Eran,我正在使用 eclipse Oxygen,面向 Web 开发人员的 Java EE IDE
  • @ThomasMuller 您确定您使用的代码与我的回答中的完全相同吗?我发现 Java 8 错误消息经常具有误导性。一个简单的错字可能会给您一条错误消息,但无法帮助您找到它。
  • @Eran:感谢您的宝贵时间。我将您的方法放入以下类:public class Utility&lt;T&gt; { static &lt;T&gt; List&lt;T&gt; getAllOccurrencesForType(Function&lt;Records,List&lt;T&gt;&gt; getter, List&lt;Records&gt; allRecords) { return allRecords.stream().flatMap(r-&gt;getter.apply(r).stream()).collect(Collectors.toList()); } }
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-06
相关资源
最近更新 更多