【问题标题】:How to implement generic comparator for user-defined class如何为用户定义的类实现通用比较器
【发布时间】:2019-06-07 06:29:14
【问题描述】:

我想对包含一些数据成员的用户定义类进行排序。 在这里,我创建了名为 Universal & Showroom 的类,它们都包含 common 的价格标签。我想创建通用的 Comparator compare(),这对于两个类来说都是通用的,两个类都具有具有不同值的相同字段。 两个值都按升序排序。

public class Showroom  {
    String phone_vendor;int price,ram,storage;

    public Showroom(String phone_vendor, int price, int ram, int storage) {
        this.phone_vendor = phone_vendor;
        this.price = price;
        this.ram = ram;
        this.storage = storage;
    }

}
public class Universal {
    String phone_vendor;
    int price,ram,storage;

    public Universal(String phone_vendor, int price, int ram,int storage) {
        this.phone_vendor = phone_vendor;
        this.price = price;
        this.ram = ram;
        this.storage=storage;
    }
}

【问题讨论】:

  • 我没有得到设计的完整背景。但是您可以拥有一个声明了这些字段和构造函数的抽象类。您可以在 Showrrom 和 Universal 中扩展该抽象类。之后可以轻松编写通用比较器
  • 您的类需要实现一个通用接口(或扩展一个通用类),该接口提供访问价格属性的方法。

标签: java generics comparator


【解决方案1】:

只是我之前给出的评论示例。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public abstract class Parent {
    String phone_vendor;int price,ram,storage;

    public Parent(String phone_vendor, int price, int ram, int storage) {
        this.phone_vendor = phone_vendor;
        this.price = price;
        this.ram = ram;
        this.storage = storage;
    }

    public static void main(String[] args) {
        Universal us = new Universal("Samsung", 51, 5, 11);
        Showroom sr = new Showroom("Nokia", 50, 4, 10);

        List<Parent> lst = new ArrayList<Parent>();
        lst.add(us);
        lst.add(sr);
        Collections.sort(lst, new PriceComparator());

        for(Parent p:lst) {
            System.out.println(p.price);
        }

    }
}


class Showroom extends Parent {

    public Showroom(String phone_vendor, int price, int ram, int storage) {
        super(phone_vendor, price, ram, storage);
    }

}
class Universal extends Parent {
   public Universal(String phone_vendor, int price, int ram, int storage) {
       super(phone_vendor, price, ram, storage);
   }
}

class PriceComparator implements Comparator<Parent> {
    @Override
    public int compare(Parent o1, Parent o2) {
        return o1.price - o2.price;
    }
}

【讨论】:

    【解决方案2】:

    泛型的另一种选择:

        import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class GenericComparator<T> implements Comparator<T> {
    
        @Override
        public int compare(T o1, T o2) {
            int price1 = 0;
            int price2 = 0;
            try {
                Method m1 = o1.getClass().getDeclaredMethod("getPrice", o1.getClass().getClasses());
                price1 = (int) m1.invoke(o1);
                Method m2 = o2.getClass().getDeclaredMethod("getPrice", o1.getClass().getClasses());
                price2 = (int) m2.invoke(o2);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (SecurityException e) {
                e.printStackTrace();
            }
            return price1 - price2;
        }
    
        public static void main(String[] args) {
            List<Showroom> showRoomList = new ArrayList<Showroom>();
            showRoomList.add(new Showroom("IPHONE", 9000, 4, 4));
            showRoomList.add(new Showroom("SAMSUNG", 5000, 4, 4));
            showRoomList.add(new Showroom("MOTO", 8000, 4, 4));
            showRoomList.add(new Showroom("SONY", 7000, 4, 4));
    
            List<Universal> universalList = new ArrayList<Universal>();
            universalList.add(new Universal("IPHONE", 100000, 4, 4));
            universalList.add(new Universal("SAMSUNG", 222222, 4, 4));
            universalList.add(new Universal("MOTO", 44444, 4, 4));
            universalList.add(new Universal("SONY", 7055500, 4, 4));
            System.out.println("Showroom");
            Collections.sort(showRoomList, new GenericComparator<Showroom>());
            for (Showroom s : showRoomList) {
                System.out.println(s.getPrice());
            }
            System.out.println("Universal");
            Collections.sort(universalList, new GenericComparator<Universal>());
            for (Universal s : universalList) {
                System.out.println(s.getPrice());
            }
        }
    
    }
    

    输出:

    Showroom
    5000
    7000
    8000
    9000
    Universal
    44444
    100000
    222222
    7055500
    

    注意:确保为 Universal 和 Showroom Pojos 中的属性创建 setter/getter。

    【讨论】:

      【解决方案3】:

      有几种方法可以解决这个问题。

      一种方法是定义一个接口,该接口可以访问您需要的信息,并为此接口实现比较器,以便可以比较实现它的每个类。

      interface Offer {
      
          String phoneVendor();
      
          int price();
      
          int ram();
      
          int storage();
      
      }
      
      class OfferComparator implements Comparator<Offering> {
      
          @Override
          public int compare(Offering o1, Offering o2) {
              // Compare
              return 0;
          }
      
      }
      

      第二个选项是......如果它们看起来相同,你真的需要这两个类吗?您能否通过赋予它类型属性来概括它?合并的类可以实现可比较的。像这样的:

      public class Offer implements Comparable<Offer> {
      
          enum Type {
              Showroom, Universal;
          }
      
          Type type;
          String phone_vendor;
          int price, ram, storage;
      
          public Showroom(String phone_vendor, int price, int ram, int storage) {
              this.phone_vendor = phone_vendor;
              this.price = price;
              this.ram = ram;
              this.storage = storage;
          }
      
          @Override
          public int compareTo(Offer o) {
              // Compare
              return 0;
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-07
        相关资源
        最近更新 更多