使用TreeSet,TreeMap,Treexxx集合的正确打开方式

目录

来个class的定义: 

简单的小demo(error):

运行结果输出:

分析: 

正确打开方式:实现compare方法


来个class的定义: 

public class Member {
    private String id;
    private String username;
    private short age;

	/**
	 * @return the id
	 */
	public String getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(String id) {
		this.id = id;
	}

	/**
	 * @return the username
	 */
	public String getUsername() {
		return username;
	}

	/**
	 * @param username the username to set
	 */
	public void setUsername(String username) {
		this.username = username;
	}

	/**
	 * @return the age
	 */
	public short getAge() {
		return age;
	}

	/**
	 * @param age the age to set
	 */
	public void setAge(short age) {
		this.age = age;
	}

	public Member(String id, String username, short age) {
		this.id = id;
		this.username = username;
		this.age = age;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	@Override
	public int hashCode() {
		return Objects.hash(id, username);
	}

	
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object obj) {
		if (obj == this) {
			return true;
		}
		if (!(obj instanceof Member)) {
			return false;
		}
		Member other = (Member) obj;
		
		return this.id.equals(other.id);
	}
}

 

简单的小demo(error):

public static void main(String[] args) {
        // 定义一个比较器先
        Comparator<Member> c = new Comparator<Member>() {
            @Override
            public int compare(Member o1, Member o2) {
                return o1.getAge() > o2.getAge() ? 1 : -1;
            }
        };

        Set<Member> set = new TreeSet<Member>(c);
        Member o = new Member("1001","t",(short) 21);
		
        set.add(new Member("1002","t",(short) 22));
        set.add(new Member("1003","t",(short) 23));
        set.add(o);
		
        System.out.println(set.size());
        System.out.println(set.contains(o));
}

运行结果输出:

size:3
false

 嗯嗯嗯??,size为3可以理解,但是这个false就有点尴尬了,同一个对象明明已经加到了容器中,你和我说没有??

分析: 

难道和比较器的compare()方法有关??是滴,你的猜测煤油错,真相只有一个!

其实对于Tree数据结构的集合判断元素唯一性的方式:就是根据compare()的返回结果是否是0,是0,就是相同元素。

相信大家应该都知道TreeSet对象它里边使用的就是TreeMap的key来存储对象,

打个断点来一探究竟: 

将id为1001的member对象作为参数调用contains()方法,

跟着断点进入TreeSet的contains()方法里边,可以看到它其实调用的就是一个Map对象的containsKey()方法,

继续跟进到TreeMap里边,它又调用了getEntry()方法:

外部比较器不为空,继续调用getEntryUsingComparator(key)方法 ,

 root的值是存储到集合中id为1002的member对象,然后开始调用比较器的compare方法来对两个对象进行比较,

比较返回的结果是-1,小于0,把p的左边节点给p来引用,通过debug可以看到左节点就是id为1001的节点,

继续while循环,调用比较方法,返回还是-1(21不大于21),左节点为null,赋值给p,p为null,循环结束,返回null,

getEntry(key)!=null;表达式不成立,返回值false,不包含这个key,最后的输出结果为false;

正确打开方式:正确实现compare方法

Comparator<Member> c2 = new Comparator<Member>() {
    @Override
    public int compare(Member o1, Member o2) {
        int j1 = o1.getUsername().compareTo(o2.getUsername());
        int j2 = o1.getId().compareTo(o2.getId());
		
        return j1 == 0 ? j2 : j1;
    }
};

 嗯,一切都是那么的安逸!!

写的是啰唆了点,也可以看看大佬的。

一个传送门:Java Map的正确使用方式

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值