当前位置: 首页 > 面试题库 >

基于条件和顺序的Java 8 Lambda过滤

张鸿志
2023-03-14
问题内容

我试图根据多个条件对列表进行排序。

class Student{
        private int Age;
        private String className;
        private String Name;

        public Student(int age, String className, String name) {
            Age = age;
            this.className = className;
            Name = name;
        }

        public int getAge() {
            return Age;
        }

        public void setAge(int age) {
            Age = age;
        }

        public String getClassName() {
            return className;
        }

        public void setClassName(String className) {
            this.className = className;
        }

        public String getName() {
            return Name;
        }

        public void setName(String name) {
            Name = name;
        }
    }

现在,如果我有一个清单,说

List<Student> students = new ArrayList<>();
        students.add(new Student(24, "A", "Smith"));
        students.add(new Student(24, "A", "John"));
        students.add(new Student(30, "A", "John"));
        students.add(new Student(20, "B", "John"));
        students.add(new Student(24, "B", "Prince"));

我怎样才能得到一个名字不同的最老的学生名单?在C#中,使用System.Linq
GroupB进行比较非常简单,然后将其与select进行比较,然后进行展平,我不太确定如何在Java中实现相同的目标。


问题答案:

使用toMap收集器:

Collection<Student> values = students.stream()
                .collect(toMap(Student::getName,
                        Function.identity(),
                        BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))))
                .values();

说明

我们正在使用以下重载toMap

toMap​(Function<? super T,? extends K> keyMapper,
      Function<? super T,? extends U> valueMapper,
      BinaryOperator<U> mergeFunction)
  • Student::getName上面的keyMapper函数用于提取映射键的值。
  • Function.identity()上面的valueMapper函数用于提取地图值的值,其中Function.identity()简单地返回源中它们本身即Student对象的元素。
  • BinaryOperator.maxBy(Comparator.comparingInt(Student::getAge))上面的合并函数用于“确定在键冲突时要返回哪个Student对象,即当两个给定的学生具有相同的名称时”,在这种情况下采用最早的Student
  • 最后,调用values()返回给我们一批学生。

等效的C#代码为:

var values = students.GroupBy(s => s.Name, v => v,
                          (a, b) => b.OrderByDescending(e => e.Age).Take(1))
                      .SelectMany(x => x);

说明 (针对那些不熟悉.NET的人)

我们正在使用以下扩展方法GroupBy

System.Collections.Generic.IEnumerable<TResult> GroupBy<TSource,TKey,TElement,TResult> 
       (this System.Collections.Generic.IEnumerable<TSource> source, 
         Func<TSource,TKey> keySelector, 
         Func<TSource,TElement> elementSelector, 
     Func<TKey,System.Collections.Generic.IEnumerable<TElement>,TResult> resultSelector);
  • s => s.Name上面的keySelector函数用于提取要分组的值。
  • v => v上面的elementSelector函数用于提取值,即Student它们所拥有的对象。
  • b.OrderByDescending(e => e.Age).Take(1)以上是resultSelector给出的IEnumerable<Student>代表年龄b最大的学生的。
  • 最后,我们申请.SelectMany(x => x);将结果折叠IEnumerable<IEnumerable<Student>>IEnumerable<Student>


 类似资料:
  • 如果我有一个清单,比如说 我如何才能获得一个名字不同的年龄最大的学生名单?在C#中,使用system.linq GroupBy然后比较,然后用select进行扁平化,这将非常简单,我不太确定如何在Java中实现同样的功能。

  • 此问题与几天前发布的问题类似,将行从0折叠到0 与前一个问题不同的是,我们如何根据Id折叠那些时间差小于或等于60的行。 例如,使用相同的数据集 这将通过ID计算时差 这将导致如下所示的新列差异 现在只按< code >事件折叠行。身份证明..其中时间差小于或等于60,即< code>diff 正在寻找有关如何创建这种折叠数据集的帮助。提前谢谢。

  • 我想根据两个属性对列表进行排序,但要满足一定的条件。下面的类有两个属性--memberid和membernumber。其值如下所示。

  • 我有以下数据框: 我想根据以下条件对其进行过滤: 创建的角度=范围(87-92) GDT 1和GDT 2之间的距离 到目前为止我尝试了这个(最后一个方法): 此代码的输出是一个没有错误的空数据库。

  • 问题内容: 数据库中列类型的顺序是否对查询时间有影响? 例如,具有混合顺序(INT,TEXT,VARCHAR,INT,TEXT)的表的查询是否比具有连续类型(INT,INT,VARCHAR,TEXT,TEXT)的表的查询慢? 问题答案: 答案是肯定的,这确实很重要,并且可能很重要,但 通常 并不重要。 所有I / O都在页面级别完成(根据您的操作系统,通常为2K或4K)。行的列数据彼此相邻存储,除

  • 问题内容: 我有一个带参数的SQL Server 2005存储proc :。 我想根据此参数控制一个子句。 我想获取所有项目(不包括where子句),何时。否则,请包含where子句。 问题答案: