匿名对象的Distinct

在使用linq distinct集合的时候,匿名对象和非匿名对象的区别非常有趣。 匿名对象自动实现了GetHashCode和Equals方法,Distinct可以自动去重。

如果使用非匿名对象,则需要该类override GetHashCode()和Equals(object obj)方法, 或者添加一个实现IEqualityComparer<T>的辅助类,作为Distinct参数。


参考下面的例子:

 #region anonymous object

            var anonymousObj1 = new
            {
                Time1 = new DateTime(2016, 10, 1),
                Time2 = new DateTime(2016, 10, 2)
            };
            var anonymousObj2 = new
            {
                Time1 = new DateTime(2016, 10, 1),
                Time2 = new DateTime(2016, 10, 2)
            };            

            Trace.WriteLine(anonymousObj1 == anonymousObj2);  // false
            Trace.WriteLine(Object.ReferenceEquals(anonymousObj1, anonymousObj2));    // false
            Trace.WriteLine(anonymousObj1.GetHashCode() == anonymousObj2.GetHashCode());  // true
            Trace.WriteLine(anonymousObj1.Equals(anonymousObj2)); // true

            #endregion

            #region non-anonymous object

            var classObj1 = new Class1
            {
                Time1 = new DateTime(2016, 10, 1),
                Time2 = new DateTime(2016, 10, 2)
            };
            var classObj2 = new Class1
            {
                Time1 = new DateTime(2016, 10, 1),
                Time2 = new DateTime(2016, 10, 2)
            };
            Trace.WriteLine(classObj1 == classObj2);  // false
            Trace.WriteLine(Object.ReferenceEquals(classObj1, classObj2));    // false
            Trace.WriteLine(classObj1.GetHashCode() == classObj2.GetHashCode());  // false
            Trace.WriteLine(classObj1.Equals(classObj2)); // false

            #endregion
            
            // distinct
            IList<Class1> list = new List<Class1>()
            {
                new Class1() {SerialNo =1, Time1 = new DateTime(2016, 10, 1),  Time2 = new DateTime(2017, 10, 1) },
                new Class1() {SerialNo =1, Time1 = new DateTime(2016, 10, 1),  Time2 = new DateTime(2017, 10, 1) },
                new Class1() {SerialNo =1, Time1 = new DateTime(2016, 10, 3),  Time2 = new DateTime(2017, 10, 10) },
                new Class1() {SerialNo =1, Time1 = new DateTime(2016, 10, 4),  Time2 = new DateTime(2017, 10, 10) }
            };

            // Count: 4. Class1 must overide GetHashCode and Equals method.
            var result1 = list.Select(p => new Class1 { Time1 = p.Time1, Time2 = p.Time2 }).Distinct();
            // Count: 3.
            var result2 = list.Select(p => new { Time1 = p.Time1, Time2 = p.Time2 }).Distinct();


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java 8 中的 Stream API可以使用 distinct() 方法来对对象进行去重。 例如: ``` List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 3, 2); list = list.stream().distinct().collect(Collectors.toList()); ``` 这将对列表中的对象进行去重,并返回一个新的列表。 需要注意的是,这只会去重相同的对象,如果对象重写了equals和hashcode方法则可以根据对象的属性去重。 ### 回答2: Stream流是Java 8中新增的功能,能够以非常优雅的方式进行集合操作,处理大量的数据,并且能够提高工作效率。其中,Stream流的distinct()方法就是用来去除Stream流中的重复元素的。 在Stream流中调用distinct()方法时,会自动进行去重操作,并且会生成一个新的Stream流对象。在去重操作结束后,我们就可以对新生成的Stream流对象进行下一步的操作了。 具体来说,我们可以采用以下的方式来去重Stream流中的元素: 1. 对于简单数据类型,比如整数、字符等,直接使用distinct()方法即可。 例如,如果我们有一个Integer类型的Stream流对象,代码如下: ``` Stream<Integer> stream = Stream.of(1, 2, 3, 2, 4, 5, 4); Stream<Integer> distinctStream = stream.distinct(); ``` 这段代码中,我们使用Stream.of()方法创建一个整数类型的Stream流,其中包含了一些重复的元素。接着,我们调用distinct()方法,生成了一个去重后的新Stream流对象。 2. 如果要去重的是自定义类型的对象,我们需要在该对象中重写equals()和hashCode()方法。这样,才能确保可以使用distinct()方法去重。 例如,我们有以下的Student类: ``` public class Student { private int id; private String name; // 构造函数和getter/setter方法省略 @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof Student)) return false; Student student = (Student) o; return getId() == student.getId() && Objects.equals(getName(), student.getName()); } @Override public int hashCode() { return Objects.hash(getId(), getName()); } } ``` 在这个类中,我们重写了equals()和hashCode()方法,实现了基于id和name字段的自定义对象的比较。 然后,我们可以使用以下的方式去重该对象类型的Stream流: ``` List<Student> list = new ArrayList<>(); list.add(new Student(1, "Jack")); list.add(new Student(2, "Tom")); list.add(new Student(3, "Jerry")); list.add(new Student(2, "Tom")); Stream<Student> stream = list.stream(); Stream<Student> distinctStream = stream.distinct(); ``` 这段代码中,我们创建了一个Student类型的List集合,并且包含了一些重复的元素。然后,我们将该List集合转换成了一个Stream流对象,并且使用distinct()方法对其进行去重操作。最终,我们得到了一个去重后的新Stream流对象。 综上所述,Stream流的distinct()方法可以方便地对Stream流对象进行去重操作,并且可以适用于简单类型和自定义对象类型。但是,在使用自定义对象类型时,需要在该对象中重写equals()和hashCode()方法。 ### 回答3: Stream流是Java 8中新增的一种数据处理方式,它可以通过一系列的操作对集合中的数据进行筛选、映射、过滤、去重等操作,大大提高了数据处理的效率和代码的可读性。而Stream中的distinct()方法可以对流中的元素进行去重操作,返回一个去重后的新流。 那么如何使用Stream流的distinct()方法进行去重呢?我们可以通过以下的步骤来实现: 1.创建一个包含重复元素的数据集合,我们假设这个集合叫做list。 2.将这个集合转化为一个流,使用Stream的静态方法of()和concat()可以实现多个集合的合并为一个流。 3.使用distinct()方法对这个流进行去重操作,返回一个去重后的新流。 4.使用foreach()方法遍历这个新流,对去重后的元素进行相应的操作。比如我们可以使用Lambda表达式来输出。 下面是一个示例代码: ```java List<String> list = Arrays.asList("a", "b", "c", "a", "b", "d"); Stream<String> stream = Stream.concat(list.stream(), list.stream()); Stream<String> distinctStream = stream.distinct(); distinctStream.forEach(s -> System.out.println(s)); ``` 这段代码将会输出去重后的元素a、b、c和d。其中concat()方法用于将两个流合并为一个流,在这里我们使用的是同一个集合的两个流。 需要注意的是,distinct()方法是根据元素的hashCode()方法和equals()方法来判断两个元素是否相同,所以如果我们的元素类没有重写这两个方法,则默认使用Object类的方法,不会进行正确的去重操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值