A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 胥文 中级黑马   /  2013-1-23 20:52  /  2160 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 胥文 于 2013-1-24 22:20 编辑

TreeSet集合有 两种排序方式,一种是让元素自身具备比较性:定义一个类实现comparable的接口,覆盖compareTo(T o)
的方法,而第二种是让容器自身具备比较性:定义一个比较器,实现comparetor接口覆盖 compare(T o1,To2)
第一种方法中的o表示集合中已经存在的对象,我们往里面添加元素的时候就要拿添加的元素和这个对象比,但是第二种方法是o1和o2比,o2为集合中已经存在的对象,O1为要传进去的对象,这里是不是先将o1这个对象添加到集合里面,然后再和O2比,如果相同集合是不是在把它删掉啊,如果不同就存放在集合
我的理解是第一种方式是先拿元素和集合中已经存在的元素比,如果相同,就存不进去,如果不同就存进去
而第二种方式是不管相不相同先把这个元素存进去,然后再和里面的元素比
不知大家是怎么理解的?

11 个回复

倒序浏览
我发的帖子怎么成这样了
我只不过复制了APIl里面的方法
oh my god
回复 使用道具 举报
自动合并行啦。。你可以用代码的方式发
回复 使用道具 举报
为了方便大家看,我把题目又写了一遍:希望大家谅解,原来复制API中的文字会有这种效果,见识了
TreeSet集合有 两种排序方式,一种是让元素自身具备比较性:定义一个类实现comparable的接口,覆盖compareTo(T o)的方法,而第二种是让容器自身具备比较性:定义一个比较器,实现comparetor接口覆盖compare(T o1,T o2)方法,
第一种方法中的o表示集合中已经存在的对象,我们往里面添加元素的时候就要拿添加的元素和这个对象比,
但是第二种方法是o1和o2比,o2为集合中已经存在的对象,O1为要传进去的对象,这里是不是先将o1这个对象添加到集合里面,然后再和O2比,如果相同集合是不是在把它删掉啊,如果不同就存放在集合
我的理解是第一种方式是先拿元素和集合中已经存在的元素比,如果相同,就存不进去,如果不同就存进去
而第二种方式是不管相不相同先把这个元素存进去,然后再和里面的元素比
不知大家是怎么理解的?

评分

参与人数 1技术分 +1 收起 理由
Rancho_Gump + 1 赞一个!

查看全部评分

回复 使用道具 举报
public class TreeSetTest2 implements Comparator{
//按姓名进行排序
        @Override
        public int compare(Object o1, Object o2) {
                // TODO Auto-generated method stub
                Student s1=(Student)o1;
                Student s2=(Student)o2;
                int num=s1.getName().compareTo(s2.getName());
                if(num==0){//若姓名相同,让其根据年龄来排序
                        //new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
                        if(s1.getAge()>s2.getAge())
                                return 1;
                        if(s1.getAge()==s2.getAge())
                        return 0;
                        return -1;
                }
                return num;
        }
        public static void main(String[] args) {
       
                TreeSet t=new TreeSet(new TreeSetTest2());
                t.add(new Student("lisi01",22));
       
                t.add(new Student("lisi01",21));
                                Iterator it=t.iterator();
                while(it.hasNext()){
                        Object obj=it.next();
                        Student stu=(Student)obj;
                        System.out.println(stu.getName()+"....."+stu.getAge());
                }
                                  本来这道题的输出结果应该是lisi01.....22在第一行,现在的输出结果却是lisi01.....21在第一行,造成这样的结果
                的原因就是lisi01.....22先存入TreeSet集合,之后与准备存入的lisi01.....21比较,由于年龄不相同,所以lisi01.....21
                就存入到TreeSet集合中,这也就充分说明了lisi01.....21是先和集合中的lisi01.....22比较之后再存入的。才造成先打印的结果。并不是楼主理解的第二种方式不管相不相同先把这个元素存进去,然后再和里面的元素比。这是我的理解方式,也许其他人有更好的解释方法。
       
        }

}

点评

第二种比较方式中,O2为已经存在对象,o1为要传进去的对象,如果没有存进集合,那01就还不存在,怎么和02比了  发表于 2013-1-24 12:48

评分

参与人数 1黑马币 +9 收起 理由
Rancho_Gump + 9 赞一个!

查看全部评分

回复 使用道具 举报
/**按照字符串长度排序.

字符串本身具备比较性.但是它的比较方式不是所需求的.

这时就只能使用比较器.
*/


import java.util.*
class  TreeSetTest
{
        public static void main(String[] args)
        {
                TreeSet ts=new TreeSet(new StrLenComparator());
                ts.add("abced");
                ts.add("aed");
                ts.add("abd");
                ts.add("c");
                ts.add("ad");

                Iterator it=ts.iterator();

                while (it.hasNext())
                {
                        System.out.println(it.next());
                }
        }
}

class StrlenComparator implements Comparator
{
        public int compare(Object o1,Object o2)//我觉得这里的o1是集合中已经存在的元素,o2是要添加的元素,比较完后如果是满足需求的就会添加进去,如果不是不管它就扔掉了,然后再取下个元素进行比较。
        {
                String s1=(String)o1;
                String s1=(String)o2;

                /*
                if(s1.length()>s2.length())
                        return 1;
                if(s1.length()==s2.length())
                        return 0;
                return -1;
                */
                int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
                if(num==0)
                        return s1.compareTo(s2);
                return num;


        }
}

评分

参与人数 1黑马币 +9 收起 理由
Rancho_Gump + 9 赞一个!

查看全部评分

回复 使用道具 举报
本帖最后由 张向辉 于 2013-1-24 11:06 编辑

都是先比较后不同则存入
第一个元素 不需要做比较。  也就是说:只有一个元素要存入的话,这个元素可以没有自然顺序,或者比较器顺序。
如果有第二个元素要存入,则按照自然顺序或者比较器进行比较,不同就存入,相同舍弃。
按你的例子: 其中o2为已存入元素,o1为新加元素
回复 使用道具 举报
这段代码相信会有帮助:
public class NewTest {
        public static void main(String[] args) throws Exception {
                TreeSet ts = new TreeSet(new MyComparator());
                ts.add(new Parent("parent1"));
                ts.add(new Child("child"));
                ts.add(new Parent("parent2"));
                System.out.println(ts);
                for (Iterator it = ts.iterator(); it.hasNext();) {
                        Parent p = (Parent) it.next();
                        System.out.println(p.name);
                }
        }
}
class Parent {
        public String name;
        public Parent(String name) {
                this.name = name;
        }
}
class Child extends Parent {
        public Child(String name) {
                super(name);
        }
}
class MyComparator implements Comparator {
        public int compare(Object o1, Object o2) {
                if (o1.getClass() == Child.class) {                 //通过查看o1的类型来了解到底哪个对象传递给了o1,哪个传递给了o2
                        System.out.println(o1.getClass().getName());
                        System.out.println(o2.getClass().getName());
                        return 1;
                }
                return -1;
        }
}
我这里的打印结果为:
junit.test.Child
junit.test.Parent
[junit.test.Parent@19360e2, junit.test.Parent@bdb503, junit.test.Child@b6e39f]
parent2
parent1
child
程序中给集合传递了一个Child两个Parent,根据打印结果可以几个结论:
1.比较器的compare(Object o1,Object o2)方法在进行比较的时候,是把将要加入集合的对象作为o1,集合中原有的对象作为o2进行比较。
2.TreeSet集合中的元素永远是小的在前面,大的在后面(就是说compare返回-1,元素就往前放,返回1就往后放)
至于楼主的问题我认为是先比较再存入。因为TreeSet有顺序,如果先存入的话不进行比较那么该把它放在哪呢?

个人分析,不一定正确啊,大家一起讨论下。
回复 使用道具 举报
胥文 中级黑马 2013-1-24 13:30:32
9#
我之所以有这个疑问是因为毕老师讲第一个方法的时候要说传进去的对象没有存进集合,就还不存在。
我由此想到第二个方法中如果要传的元素不先在集合中存在,那么这个对象就不存在,就不会有Object o1这种写法了(我是从写法上来判断的)
本来想在源代码中找找实现该接口的类怎么覆盖该方法的,有没有解释,但是好像唯一一个实现的类既然没有覆写该方法
回复 使用道具 举报
问题是否已解决,如果已解决麻烦楼主将帖子改为已解决
回复 使用道具 举报
金鑫 发表于 2013-1-24 14:26
问题是否已解决,如果已解决麻烦楼主将帖子改为已解决

请问怎么改成已解决啊
我没有改过
回复 使用道具 举报
胥文 发表于 2013-1-24 18:32
请问怎么改成已解决啊
我没有改过

编辑自己的帖子,左边有个分类,将未解决改为已解决就行了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马