Java,如何添加“比较器”类以提高代码的可重用性

发布于 2024-08-09 18:59:10 字数 831 浏览 3 评论 0原文

前言:我是代表一位朋友发布的(他显然害羞自己发布),我浏览了相关问题,但似乎没有发现任何重复的内容。但请注意,我不知道Java,所以如果这是重复的,我提前道歉!

这是代码的一部分:

public class ElencoEsami implements Comparable{
    private ArrayList<EsameMedico>  a = new ArrayList<EsameMedico>();
    private Comparable comparatore;
    public ElencoEsami() {
    }
    public void addEsame(EsameMedico e) {
        if (a.isEmpty()) {
            a.add(0,e);
            return;
        }

        for(int i=0;i<a.size();i++) {
            if (a.get(i).getData().after(e.getData())) {
                a.add(i,e);
                break;
            }
        }
        a.add(e);
    }
    public int compareTo(Object o) {
// ?????
    }

}

我的朋友想要实现“addEsame”,以便最大限度地提高代码的可重用性,特别是他希望能够通过添加新的列表来更改列表的排序方式(现在是按名称排序)类(我相信是一个比较器类?或者至少我在 C++ 中会这样做)。

谢谢你!

Preface: I'm posting this on behalf of a friend (who's apparently to shy to post it himself), I browsed through the related questions and I didn't seem to find any duplicate.. But do note that I don't know Java at all so I apologize in advance if this is a duplicate!

This is part of the code:

public class ElencoEsami implements Comparable{
    private ArrayList<EsameMedico>  a = new ArrayList<EsameMedico>();
    private Comparable comparatore;
    public ElencoEsami() {
    }
    public void addEsame(EsameMedico e) {
        if (a.isEmpty()) {
            a.add(0,e);
            return;
        }

        for(int i=0;i<a.size();i++) {
            if (a.get(i).getData().after(e.getData())) {
                a.add(i,e);
                break;
            }
        }
        a.add(e);
    }
    public int compareTo(Object o) {
// ?????
    }

}

My friend wants to implement "addEsame" so that it maximizes code reusability, in particular he wants to be able to change the way the list is ordered (right now it's ordered by name) simply by adding a new class (a comparator class I believe? Or at least that's how I would do it in C++).

Thank you!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

谷夏 2024-08-16 18:59:10

首先,使用 Collections.sort(List list, Comparator c)

然后,根据需要排序顺序编写尽可能多的 Comparator

就这样了。

First of all, use Collections.sort(List list, Comparator c)

And then, code as many Comparator as you need sorting orders

That's it.

酒与心事 2024-08-16 18:59:10

如果我想以可重用的方式实现多个比较器,我喜欢将它们实现为枚举(基于 旧技术 Per):

public class EsameMedico {
    ...

    /** Enumeration of {@link Comparator}s for {@code EsameMedico}. */
    public static enum Comparators implements Comparator<EsameMedico> {
        /** Compares by name. */
        BY_NAME {
            public int compare(final EsameMedico em1, final EsameMedico em2) {
                return em1.name.compareTo(em2.name);
            }

            public void sort(final List<EsameMedico> l) {
                Collections.sort(l, BY_NAME);
            }
        },
        /* Compares by whatever. */
        BY_WHATEVER {
            public int compare(final EsameMedico em1, final EsameMedico em2) {
                return /* compare by "whatever" */;
            }

            public void sort(final List<EsameMedico> l) {
                Collections.sort(l, BY_WHATEVER);
            }
        };

        /** Sorts the list by this criterion. */
        public abstract void sort(List<EsameMedico> l);
    }

    ...
}

但请注意,对于列表,您必须自己在插入时维护列表的顺序。如果您想自动对集合进行排序, SortedSet 可能会有所帮助。 TreeSetSortedSet 接口,在其构造函数中采用一个 Comparator 并对其元素本身进行排序。

If I want to implement a number of comparators in a reusable way, I like to implement them as enums (based on ideas from Old Tech Per):

public class EsameMedico {
    ...

    /** Enumeration of {@link Comparator}s for {@code EsameMedico}. */
    public static enum Comparators implements Comparator<EsameMedico> {
        /** Compares by name. */
        BY_NAME {
            public int compare(final EsameMedico em1, final EsameMedico em2) {
                return em1.name.compareTo(em2.name);
            }

            public void sort(final List<EsameMedico> l) {
                Collections.sort(l, BY_NAME);
            }
        },
        /* Compares by whatever. */
        BY_WHATEVER {
            public int compare(final EsameMedico em1, final EsameMedico em2) {
                return /* compare by "whatever" */;
            }

            public void sort(final List<EsameMedico> l) {
                Collections.sort(l, BY_WHATEVER);
            }
        };

        /** Sorts the list by this criterion. */
        public abstract void sort(List<EsameMedico> l);
    }

    ...
}

Note though, that with lists you have to maintain the order of the list yourself on inserts. If you want to keep your collections sorted automagically, SortedSet may be helpful. TreeSet, an implementation of the SortedSet interface, takes a Comparator in its constructor and sorts its elements itself.

小苏打饼 2024-08-16 18:59:10

Sun has a page in the Java interfaces trail about Object Ordering. It gives a brief overview of Comparators and how to write them.

扭转时空 2024-08-16 18:59:10

如果您希望在使用 addEsame 添加对象时对对象进行排序,而不调用 Collections.sort(),请使用带有键的 TreeMap你想要排序依据。如果您的对象不同,请使用TreeSet

还有一件事:

像这样声明你的列表:(

private List<EsameMedico> a;

或者 MapSet,无论你选择什么)

并在构造函数中初始化它:(

a = new ArrayList<EsameMedico>();

或者 TreeMap > ...)

因为如果你扩展类 ElencoEsami 你会得到一些奇怪的结果。

If you want to have your objects sorted while you add them with addEsame, without calling Collections.sort(), use a TreeMap with a key you want to sort by. If your objects are distinct, use a TreeSet.

And another thing:

declare your list like this:

private List<EsameMedico> a;

(Or Map, Set, whatever you choose)

And initialize it in the constructor:

a = new ArrayList<EsameMedico>();

(Or TreeMap ...)

Because if you would extend the class ElencoEsami you would have some strange results.

可是我不能没有你 2024-08-16 18:59:10

如果要更改列表的顺序,可以使用 Collections.sort() 方法,采用 比较器 作为参数。

根据您的代码,您似乎在 ComparableComparator 接口之间存在一些混淆。实现 Comparable 接口的类意味着它具有某种自然顺序(例如 Integer 类自然是根据它所代表的 int 进行排序的)。使用比较器,您可以根据其他一些排序标准对对象进行排序。

从您发布的代码来看,我想问您是否真的打算订购 ElencoEsami 类,或者您是否打算订购 EsameMedico 对象?

如果应该订购 EsameMedio 类,那么它应该实现 Comparable 接口的 EsameMedico 类。假设您在 addEsame() 方法中进行的比较是 EsameMedico 类的自然顺序,您可以在 EsameMedico 中实现compareTo() 方法,如下所示:

public class EsameMedico implements Comparable<EsameMedico>{
  ...
  public int compareTo(Object o) {
    EsameMedico e = (EsameMedico)o;
    if(getData().after(e.getData())) {
        return 1;
    } else if(e.getData().after(getData())){
        return -1;
    } else {
        return 0;
    }
}

}

然后您可以更改 addEsame() 方法以简单地插入到列表中并在每次插入后调用 Collections.sort() 。当然,更好的方法是使用 TreeSet 而不是 ArrayList。如果您这样做,每个 EsameMedico 将根据其自然顺序插入,您无需自己执行任何排序。

If you want to change the ordering of the list you can use the Collections.sort() method that takes a comparator as an argument.

Based on your code you seem to have some confusion between the Comparable and Comparator interfaces. A class that implements the Comparable interface means that it has some sort of natural ordering (e.g. the Integer class is naturally ordered based on the int it represents). Using a comparator you can order objects based on some other ordering criteria.

From the code you have posted, I would like to ask whether you actually intend to order the ElencoEsami class or if you were intending to order the EsameMedico objects?

If its the EsameMedio class that should be ordered, then its the EsameMedico class that should implement the Comparable interface. Assuming that the comparison you do in the addEsame() method is the natural ordering of the EsameMedico class, you can implement the compareTo() method in EsameMedico like this:

public class EsameMedico implements Comparable<EsameMedico>{
  ...
  public int compareTo(Object o) {
    EsameMedico e = (EsameMedico)o;
    if(getData().after(e.getData())) {
        return 1;
    } else if(e.getData().after(getData())){
        return -1;
    } else {
        return 0;
    }
}

}

You can then change your addEsame() method to simply insert into the list and call Collections.sort() after each insertion. A better approach of course, would be to use a TreeSet rather than an ArrayList. If you did this each EsameMedico would be inserted according to its natural order and you wouldn't have to perform any sorting yourself.

哆兒滾 2024-08-16 18:59:10
  1. 使用排序方法而不是“手工排序”;
  2. 正如twolfe18所指出的,使用Comparator对象,并仔细查看策略设计模式
  1. Use the sort method instead of "sorting by hand";
  2. As pointed by twolfe18, use Comparator objects, and take a close look inside the Strategy design pattern.
可可 2024-08-16 18:59:10

我发现这个例子非常有用:
http://www.javabeat.net/tips/20 -sorting-custom-types-in-java.html

对我来说,关键是 Comparator 类的示例,如下所示:

package tips.sort;

import java.util.Comparator;

public class MovieComparator implements Comparator<Movie>{

@Override
public int compare(Movie movie1, Movie movie2) {

    int rank1 = movie1.getRank();
    int rank2 = movie2.getRank();

    if (rank1 > rank2){
        return +1;
    }else if (rank1 < rank2){
        return -1;
    }else{
        return 0;
    }
}

}

I found this example immensely useful:
http://www.javabeat.net/tips/20-sorting-custom-types-in-java.html

The key for me was an example of a Comparator class like so:

package tips.sort;

import java.util.Comparator;

public class MovieComparator implements Comparator<Movie>{

@Override
public int compare(Movie movie1, Movie movie2) {

    int rank1 = movie1.getRank();
    int rank2 = movie2.getRank();

    if (rank1 > rank2){
        return +1;
    }else if (rank1 < rank2){
        return -1;
    }else{
        return 0;
    }
}

}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文