如何从这个循环中提取反射?

发布于 2024-12-27 11:06:13 字数 1297 浏览 3 评论 0原文

如果可能的话,如何将反射从该循环中拉出并传入 getter 方法。

public <E> void sortBy(final String fieldName, final boolean sortAsc, List<E> list){
        Collections.sort(list, new Comparator<E>() {
                public int compare(E o1, E o2) {
                    return compareFields(o1,o2,fieldName.replace("SortBy", "get"),sortAsc);
                }
            }
        );
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected <E> int compareFields(E o1, E o2,String fieldName, boolean sortAsc){
        try { 
            Comparable o1Data;
            Comparable o2Data;
            o1Data = (Comparable) o1.getClass().getMethod(fieldName).invoke(o1);
            o2Data = (Comparable) o2.getClass().getMethod(fieldName).invoke(o2);
            if(o1Data == null && o2Data == null){
                return 0;
            } else if (o1Data == null){
                return 1;
            } else if (o2Data == null){
                return -1;
            }
            int result = o2Data.compareTo(o1Data); 
            return (sortAsc) ? -result : result ; 
        }
        catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

上下文:我有很多带有数据表的屏幕。每个都是从列表构建的。每个数据表都需要可按其 6 列中的每一列进行排序。这些列是日期或字符串。

How do I pull the reflection out of this loop and pass in the getter method if that's possible.

public <E> void sortBy(final String fieldName, final boolean sortAsc, List<E> list){
        Collections.sort(list, new Comparator<E>() {
                public int compare(E o1, E o2) {
                    return compareFields(o1,o2,fieldName.replace("SortBy", "get"),sortAsc);
                }
            }
        );
    }

    @SuppressWarnings({ "rawtypes", "unchecked" })
    protected <E> int compareFields(E o1, E o2,String fieldName, boolean sortAsc){
        try { 
            Comparable o1Data;
            Comparable o2Data;
            o1Data = (Comparable) o1.getClass().getMethod(fieldName).invoke(o1);
            o2Data = (Comparable) o2.getClass().getMethod(fieldName).invoke(o2);
            if(o1Data == null && o2Data == null){
                return 0;
            } else if (o1Data == null){
                return 1;
            } else if (o2Data == null){
                return -1;
            }
            int result = o2Data.compareTo(o1Data); 
            return (sortAsc) ? -result : result ; 
        }
        catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

Context: I've got many screens with data tables. Each one is build from a List. Each data table needs to be sortable by each of its 6 columns. The columns are either Date or String.

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

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

发布评论

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

评论(3

活雷疯 2025-01-03 11:06:13

如果您可以假设所有元素都是同一类型。

public <E> void sortBy(final String fieldName, final boolean sortAsc, List<E> list) throws NoSuchMethodException {
    final Method f = list.get(0).getClass().getMethod(fieldName.replace("SortBy", "get"));
    f.setAccessible(true);
    final int direction = sortAsc ? +1 : -1;
    Collections.sort(list, new Comparator<E>() {
        public int compare(E o1, E o2) {
            return compareFields(o1, o2, f, direction);
        }
    }
    );
}

@SuppressWarnings({"rawtypes", "unchecked"})
protected <E> int compareFields(E o1, E o2, Method getter, int sortAsc) {
    try {
        Comparable o1Data = (Comparable) getter.invoke(o1);
        Comparable o2Data = (Comparable) getter.invoke(o2);
        if (o1Data == null)
            return o2Data == null ? 0 : 1;
        if (o2Data == null)
            return -1;
        return sortAsc * o2Data.compareTo(o1Data);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

If you can assume all the elements are the same type.

public <E> void sortBy(final String fieldName, final boolean sortAsc, List<E> list) throws NoSuchMethodException {
    final Method f = list.get(0).getClass().getMethod(fieldName.replace("SortBy", "get"));
    f.setAccessible(true);
    final int direction = sortAsc ? +1 : -1;
    Collections.sort(list, new Comparator<E>() {
        public int compare(E o1, E o2) {
            return compareFields(o1, o2, f, direction);
        }
    }
    );
}

@SuppressWarnings({"rawtypes", "unchecked"})
protected <E> int compareFields(E o1, E o2, Method getter, int sortAsc) {
    try {
        Comparable o1Data = (Comparable) getter.invoke(o1);
        Comparable o2Data = (Comparable) getter.invoke(o2);
        if (o1Data == null)
            return o2Data == null ? 0 : 1;
        if (o2Data == null)
            return -1;
        return sortAsc * o2Data.compareTo(o1Data);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}
ペ泪落弦音 2025-01-03 11:06:13

让数据对象实现一个包含 getFieldByName 方法的接口。

Have the data objects implement an interface that includes getFieldByName method.

城歌 2025-01-03 11:06:13

Apache Bean Utils 对于此类事情非常有用。他们很可能在内部使用反射,但这意味着您不必这样做,并且您可以拥有干净的代码:

...

Comparable o1Data = (Comparable) PropertyUtils.getProperty(o1, fieldName);
Comparable o2Data = (Comparable) PropertyUtils.getProperty(o2, fieldName);
if(o1Data == null && o2Data == null) {

...

这里, fieldName 应该是属性/字段的名称,而不是 getter。由于代码中的变量保存了 getter 的名称,因此您可能应该将其命名为 getterName 之类的名称。

The Apache Bean Utils are quite useful for this kind of thing. They most likely use reflection internally but it means you don't have to and you can have nice clean code:

...

Comparable o1Data = (Comparable) PropertyUtils.getProperty(o1, fieldName);
Comparable o2Data = (Comparable) PropertyUtils.getProperty(o2, fieldName);
if(o1Data == null && o2Data == null) {

...

Here, fieldName should be the name of the property/field, not the getter. Since the variable in your code holds the name of the getter you should probably call it something like getterName instead.

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