Comparartor使用(有坑)

Comparartor使用(有坑)

首先虽然说是说Comparartor使用,但其实更多的是一个double类型精度的问题(哈哈,有点挂羊头卖狗肉的意思,虽然double类型精度的问题很常见,但当和Comparartor使用两个碰到一起就不那么容易发现了,所以在这里我们还是讲讲吧)。好了,先说问题,下面是问题代码:

  1. Person.java(这是一个用来存储数据的javaBean类)
import java.util.Objects;

/*
 * Person类,遵从Comparable<T>接口, 要求实现对应 compareTo方法
 */
public class Person {
	private int id;
	private String name;
	//关键就是这个double类型变量(工资)
	private double salary;
	
	public Person() {
	}

	public Person(int id, String name, double salary) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", salary=" + salary + "]";
	}
}

  1. Demo.java(使用TeerSet添加数据,也就是Person对象)
package com.qfedu.b_set;

import java.util.Comparator;
import java.util.Map.Entry;
import java.util.TreeSet;

public class Demo5 {
	public static void main(String[] args) {
		/*
		 * 匿名内部类的匿名对象作为方法参数
		 */
		TreeSet<Person> set = new TreeSet<Person>(new Comparator<Person>() {

			@Override
			public int compare(Person o1, Person o2) {
				int ret = (int) ( (o1.getSalary() - o2.getSalary())*100 );
				return ret;
			}
		});
		Person p1 = new Person(1, "余晖", 10.01);
		Person p2 = new Person(2, "将夜", 10.03);
		Person p3 = new Person(3, "朔鼠", 10.05);
		Person p4 = new Person(4, "邶风", 10.07);
		Person p5 = new Person(5, "柏州", 10.00);
		Person p6 = new Person(6, "与归", 11.00);
		
		set.add(p1);
		set.add(p2);
		set.add(p3);
		set.add(p4);
		set.add(p5);
		set.add(p6);
		for(Person p : set) {
			System.out.println(p);
		}
	}
}

好了, 坑来了,请问现在set里用几个Person对象?
(还要问吗,当然是六个)
嗯,我刚开始也是这样以为的,然后。。。。。我错了,不信?看下面截图
在这里插入图片描述
额。。。。“柏州”哪去了?

首先我们要知道TreeSet是一个基于二叉树实现的,有序,不可重复,即当有两个相同的对象(TreeSet
的比较器决定)就不会重复添加,TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false;或者通过CompareTo方法比较条件判断结果是相同,返回0;我们上面采用的是第二种方式通过CompareTo方法比较,问题就出在这了,因为在比较过程中我们根据 salary 来进行判定,在比较过程中 p1 和 p2 它们的工资比较 CompareTo 方法返回的是 0 ,相同。。。。。。
(骗人,( 10.01 - 10)*100 = 1,你别蒙我 明明返回的是1)
好吧还是来张图:
在这里插入图片描述
(什么鬼?不该是0.1吗?)
好了,讲到这里其实大家也都明白了为什么 set 里就5个Person 吧;然后出现这种问题主要还是double精度的问题,因为有些小数它无法用二进制表示出来,即比方十进制(0.1),你试试看,你写完我请你喝茶,哈哈,你会发现二进制表示是这样的(0.000110011001100…),它只能是一个近似值,

(那怎么解决呢?)
不乘100了,改成1000就好了
(…)

哈哈,不开玩笑,在这里我们只须使用BigDecimal(String value) 这个方法,把double转成字符后使用该方法将double 类型转为BigDecimal类型进行操作就好了
下面是改后的结果:
在这里插入图片描述
ps:(以后做开发如果碰到要求精度很高的计算千万别用double)

发布了4 篇原创文章 · 获赞 10 · 访问量 714

猜你喜欢

转载自blog.csdn.net/LioTomcat/article/details/104502691
今日推荐