黑马程序员技术交流社区

标题: 技术难题:带嵌套泛型的TreeSet如何实现自然排序? [打印本页]

作者: 徘徊消逝中    时间: 2014-6-19 13:30
标题: 技术难题:带嵌套泛型的TreeSet如何实现自然排序?
本帖最后由 徘徊消逝中 于 2014-6-25 22:21 编辑

情景如下:TreeSet<Point<String>> spSet = new TreeSet<Point<String>>();
如何才能实现自然排序,是不是需要这个Point类实现Comparable接口,但是现在这个Point是带泛型的,其声明如下:
class Point<T>{ --- }  ;
如果这样声明:class Point<T> implements Comparable<T> { --- },那么类中重写的compareTo方法如何实现呢?

有没有大神帮帮忙啊!!!!!!!!!!!
作者: 徘徊消逝中    时间: 2014-6-19 14:01
我自己尝试实现了,但是很别扭,感觉不通常,有没有人交流下
  1. package blog9;

  2. import java.util.TreeSet;

  3. /**
  4. * 泛型使用实例:
  5. * 1、定义一个表示点的类,包含横坐标和纵坐标值,且值具有三种形式,string、Integer、double。
  6. * 2、通过实现带泛型的comparable接口排序
  7. * 难题:如何让Point<T>实现comparable<T>接口,因为这里带了泛型,那么TreeSet的自然排序如何实现
  8. */
  9. public class TestGeneric {

  10.         public static void main(String[] args) {
  11.                 //坐标为String类型
  12.                 TreeSet<Point<String>> spSet = new TreeSet<Point<String>>();
  13.                 spSet.add(new Point<String>("10","20"));
  14.                 spSet.add(new Point<String>("5","30"));
  15.                 spSet.add(new Point<String>("100","20"));
  16.                 System.out.println(spSet);
  17.                 //输出:[Point [x=5, y=30], Point [x=10, y=20], Point [x=100, y=20]]
  18.                
  19.                 TreeSet<Point<Integer>> ipSet = new TreeSet<Point<Integer>>();
  20.                 ipSet.add(new Point<Integer>(40,60));
  21.                 ipSet.add(new Point<Integer>(20,60));
  22.                 ipSet.add(new Point<Integer>(330,60));
  23.                 ipSet.add(new Point<Integer>(5,60));
  24.                 System.out.println(ipSet);
  25.                 //输出:[Point [x=5, y=60], Point [x=20, y=60], Point [x=40, y=60], Point [x=330, y=60]]
  26.                
  27.                 TreeSet<Point<Double>> dpSet = new TreeSet<Point<Double>>();
  28.                 dpSet.add(new Point<Double>(5.5,62.1));
  29.                 dpSet.add(new Point<Double>(200.5,30.54));
  30.                 dpSet.add(new Point<Double>(0.7,6.0));
  31.                 dpSet.add(new Point<Double>(500.54,20.4));
  32.                 System.out.println(dpSet); //这里是以y升序的,在compareTo方法中实现
  33.                 //[Point [x=0.7, y=6.0], Point [x=500.54, y=20.4], Point [x=200.5, y=30.54], Point [x=5.5, y=62.1]]

  34.         }
  35. }

  36. class Point<T> implements Comparable<Point<T>>{

  37.         private T x;
  38.         private T y;
  39.        
  40.         public Point(T x,T y) {
  41.                 this.x = x;
  42.                 this.y = y;
  43.         }
  44.        
  45.         @Override
  46.         public String toString() {
  47.                 return "Point [x=" + x + ", y=" + y + "]";
  48.         }

  49.         @Override
  50.         public int hashCode() {
  51.                 final int prime = 31;
  52.                 int result = 1;
  53.                 result = prime * result + ((x == null) ? 0 : x.hashCode());
  54.                 result = prime * result + ((y == null) ? 0 : y.hashCode());
  55.                 return result;
  56.         }

  57.         @SuppressWarnings("rawtypes")
  58.         @Override
  59.         public boolean equals(Object obj) {
  60.                 if (this == obj)
  61.                         return true;
  62.                 if (obj == null)
  63.                         return false;
  64.                 if (getClass() != obj.getClass())
  65.                         return false;
  66.                 Point other = (Point) obj;
  67.                 if (x == null) {
  68.                         if (other.x != null)
  69.                                 return false;
  70.                 } else if (!x.equals(other.x))
  71.                         return false;
  72.                 if (y == null) {
  73.                         if (other.y != null)
  74.                                 return false;
  75.                 } else if (!y.equals(other.y))
  76.                         return false;
  77.                 return true;
  78.         }

  79.         @Override
  80.         public int compareTo(Point<T> o) {
  81.                 if(o.x instanceof String){
  82.                         String s = (String)this.x;
  83.                         return Integer.parseInt(s) - Integer.parseInt((String)o.x);
  84.                         //感觉好麻烦,两个强转,失去了泛型的意义了
  85.                 }
  86.                 if(o.x instanceof Integer){
  87.                         Integer i = (Integer)this.x;
  88.                         return i.compareTo((Integer)o.x);
  89.                 }
  90.                 if(o.x instanceof Double){//当Point的类型为double时,用y值排序
  91.                         Double d = (Double)this.y;
  92.                         return d.compareTo((Double)o.y);
  93.                 }
  94.                 return 0;
  95.         }
  96. }
复制代码




作者: 徘徊消逝中    时间: 2014-6-19 16:05
哎妈呀,半天没人鸟,来个人啊,咱们讨论学术呗
作者: 来自沙沙的我    时间: 2014-6-19 16:48
你的比较方法中的元素是泛型的,自己的不知道是什么,那么怎么比较呢?
我认为有两个方法解决,一个是建立比较器comparator,根据确定类型后在判定

另一个是在构造方法中添加一个元素
public Point(T x,T y,String comparaName) {
                this.x = x;
                this.y = y;
                 this.comparaName=comparaName;
        }
也就是说构造方法时此成员变量只做为comparable方法中的比较元素使用。
上面的两种方法应该没有问题吧?我也是看到你的题目后才想到的。
作者: HF_Opticalix    时间: 2014-6-19 17:08
来自沙沙的我 发表于 2014-6-19 16:48
你的比较方法中的元素是泛型的,自己的不知道是什么,那么怎么比较呢?
我认为有两个方法解决,一个是建立 ...

题主意思可能是 三种Point参数类型 都要写出比较方法
其中String类的方法比较麻烦 要强转 如何简写或者统一?
作者: HF_Opticalix    时间: 2014-6-19 17:16
point的String类参数,要按照阿拉伯数字排序 我觉得只能用parseInt了吧。。
这三者(尤其String)想通过一个compareTo泛到一起去 恐怕不能更简便

作者: 来自沙沙的我    时间: 2014-6-19 17:41
HF_Opticalix 发表于 2014-6-19 17:08
题主意思可能是 三种Point参数类型 都要写出比较方法
其中String类的方法比较麻烦 要强转 如何简写或者统 ...

恩,刚刚没有看到后面还有题目,那么这样应该可以吧

class Point implements Comparable<Point>{

    private Integer x;
    private Integer y;
    private String a;
    private String b;
    private Double i;
    private Double j;

   
     Point(Integer x,Integer y) {
            this.x = x;
            this.y = y;
    }
     Point(String a,String b) {
        this.a = a;
        this.b = b;
    }
     Point(Double i,Double j) {
        this.i = i;
        this.j = j;
    }
}

直接定义6个成员变量,三个构造方法
那么comparable的比较方法就不用进行强转了。
作者: HF_Opticalix    时间: 2014-6-19 18:06
来自沙沙的我 发表于 2014-6-19 17:41
恩,刚刚没有看到后面还有题目,那么这样应该可以吧

class Point implements Comparable{

这样Point就不带泛型了,支持一下 看楼主怎么说
作者: 来自沙沙的我    时间: 2014-6-19 18:10
HF_Opticalix 发表于 2014-6-19 18:06
这样Point就不带泛型了,支持一下 看楼主怎么说

这位同学,我刚刚写的东西你看到了?我自己怎么没有看到呢。被删了?
作者: 来自沙沙的我    时间: 2014-6-19 18:11
HF_Opticalix 发表于 2014-6-19 18:06
这样Point就不带泛型了,支持一下 看楼主怎么说

没事了,原来刚写的东西跑前面去了,论坛的规矩搞不懂。。。
作者: HF_Opticalix    时间: 2014-6-19 18:17
来自沙沙的我 发表于 2014-6-19 18:11
没事了,原来刚写的东西跑前面去了,论坛的规矩搞不懂。。。

{:3_59:}{:3_59:}额
作者: 徘徊消逝中    时间: 2014-6-19 23:43
来自沙沙的我 发表于 2014-6-19 17:41
恩,刚刚没有看到后面还有题目,那么这样应该可以吧

class Point implements Comparable{

Point也需要是带泛型的啊
作者: 徘徊消逝中    时间: 2014-6-19 23:46
来自沙沙的我 发表于 2014-6-19 18:10
这位同学,我刚刚写的东西你看到了?我自己怎么没有看到呢。被删了?

还是没有找到特别精巧的办法,让Point带泛型,同时实现comparable接口,comparable接口带嵌套泛型
作者: 徘徊消逝中    时间: 2014-6-21 16:00
不知道是不是没有合适答案也必须结贴啊,或者,来个大神指教下




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2