Java拖拽排序工具类「建议收藏」

Java拖拽排序工具类「建议收藏」packagecom.ciih.jwt.util.sort;importjava.lang.reflect.Field;importjava.util.Collections;importjava.util.List;/***拖拽排序工具:此工具将传入的list重新排序后返回,使用者只需要将list重新存入数据库即可完成排序.*<>*拖拽排序必然牵扯到两个元素,被拖拽的元素和被挤压的元素.排序方式就存在两种,一种是两个元素进行交换位置,一种是一个元素拖到.

大家好,又见面了,我是你们的朋友全栈君。

package com.ciih.jwt.util.sort;


import java.lang.reflect.Field;
import java.util.Collections;
import java.util.List;

/**
 * 拖拽排序工具:此工具将传入的list重新排序后返回,使用者只需要将list重新存入数据库即可完成排序.
 * <>
 * 拖拽排序必然牵扯到两个元素,被拖拽的元素和被挤压的元素.排序方式就存在两种,一种是两个元素进行交换位置,一种是一个元素拖到另一元素的下发或上方.
 * 1.此方法需要传入两个基准元素之间的所有元素的集合,
 * 2.以及两个基准元素的id,
 * 3.排序方式.
 * </>
 *
 * @author sunziwen
 * @since 2021-3-23 19:15:07
 */
public class SortUtil {
    /**
     * 此方法需要在T类的主键上打@IdProperty注解,在排序字段上打@OrderProperty注解.
     *
     * @param list 需要重新排序的元素集合
     * @param id1  拖拽元素
     * @param id2  定位元素
     * @param type 排序类型(1交换,2挤压排序)
     * @param <T>  泛型
     * @return List<T>
     */
    public static <T> List<T> sort(List<T> list, Object id1, Object id2, SortType type) {
        String idProperty = null;
        String orderProperty = null;
        Field[] declaredFields = list.get(0).getClass().getDeclaredFields();
        for (Field declaredField : declaredFields) {
            IdProperty idAnnotation = declaredField.getAnnotation(IdProperty.class);
            OrderProperty orderAnnotation = declaredField.getAnnotation(OrderProperty.class);
            if (idAnnotation != null) {
                idProperty = declaredField.getName();
            }
            if (orderAnnotation != null) {
                orderProperty = declaredField.getName();
            }
        }
        if (idProperty == null) {
            throw new RuntimeException("没有在主键属性上打@IdProperty注解");
        }
        if (orderProperty == null) {
            throw new RuntimeException("没有在排序属性上打@OrderProperty注解");
        }
        return sort(list, id1, id2, type, idProperty, orderProperty);
    }

    /**
     * @param list          需要重新排序的元素集合
     * @param id1           拖拽元素
     * @param id2           定位元素
     * @param type          排序类型(1交换,2挤压排序)
     * @param idProperty    主键属性名,一般是"id"
     * @param orderProperty 排序属性名
     * @param <T>           泛型
     * @return List<T>
     */
    public static <T> List<T> sort(List<T> list, Object id1, Object id2, SortType type, String idProperty, String orderProperty) {
        //排序
        list.sort((x, y) -> {
            try {
                Field fieldx = x.getClass().getDeclaredField(orderProperty);
                Field fieldy = y.getClass().getDeclaredField(orderProperty);
                fieldx.setAccessible(true);
                fieldy.setAccessible(true);

                int i = Integer.parseInt(fieldx.get(x).toString());
                int j = Integer.parseInt(fieldy.get(y).toString());
                return i - j;
            } catch (IllegalAccessException | NoSuchFieldException e) {
                e.printStackTrace();
                throw new RuntimeException("反射异常了");
            }
        });
        if (list == null || list.size() <= 0) {
            return list;
        }
        //傻子在原地拖动
        if (id1.equals(id2)) {
            return list;
        }

        try {

            T tFirst = list.get(0);
            T tLast = list.get(list.size() - 1);

            Field orderFirst = tFirst.getClass().getDeclaredField(orderProperty);
            orderFirst.setAccessible(true);
            Object orderValueFirst = orderFirst.get(tFirst);

            Field orderLast = tLast.getClass().getDeclaredField(orderProperty);
            orderLast.setAccessible(true);
            Object orderValueLast = orderLast.get(tLast);

            //交换位置
            if (type == SortType.EXCHANGE) {
                orderFirst.set(tFirst, orderValueLast);
                orderLast.set(tLast, orderValueFirst);
            }

            //冒泡排序需要知道是从上往下,还是从下往上拖拽.因此需要知道他们的order值 order1<order2则是从上往下,反之亦然.
            if (type == SortType.BUBBLE) {

                //order集合
                int[] orders = list.stream().mapToInt(x -> {
                    try {
                        Field order = x.getClass().getDeclaredField(orderProperty);
                        order.setAccessible(true);
                        Object orderVal = order.get(x);
                        if (orderVal == null) {
                            throw new RuntimeException("有元素缺失排序属性值");
                        }
                        return Integer.parseInt(orderVal.toString());
                    } catch (NoSuchFieldException | IllegalAccessException e) {
                        e.printStackTrace();
                        throw new RuntimeException("未知异常:联系作者");
                    }
                }).toArray();

                //获取id1和id2的排序值,用来确认是拖拽方向
                Integer order1 = null;
                Integer order2 = null;
                for (T t : list) {
                    Field idField = t.getClass().getDeclaredField(idProperty);
                    idField.setAccessible(true);
                    Object idVal = idField.get(t);
                    if (idVal.equals(id1)) {
                        Field orderField = t.getClass().getDeclaredField(orderProperty);
                        orderField.setAccessible(true);
                        order1 = Integer.parseInt(orderField.get(t).toString());
                    }
                    if (idVal.equals(id2)) {
                        Field orderField = t.getClass().getDeclaredField(orderProperty);
                        orderField.setAccessible(true);
                        order2 = Integer.parseInt(orderField.get(t).toString());
                    }
                }
                if (order1 == null || order2 == null) {
                    throw new RuntimeException("排序字段缺失属性值");
                }
                //从上往下拖拽
                if (order1 < order2) {
                    //将首位元素挪到末尾
                    list.remove(tFirst);
                    list.add(tFirst);

                    //从下往上拖拽
                } else {
                    //将末尾元素追加到首位
                    T last = list.get(list.size() - 1);
                    list.remove(last);
                    Collections.reverse(list);
                    list.add(last);
                    Collections.reverse(list);
                }


                //将元素集合与order集合重新绑定
                for (int i = 0; i < orders.length; i++) {
                    T t = list.get(i);
                    Field order = t.getClass().getDeclaredField(orderProperty);
                    order.setAccessible(true);
                    order.set(t, orders[i]);
                }
            }

        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
            throw new RuntimeException("未知异常:联系作者");
        }
        return list;
    }

}






//@Data
//@AllArgsConstructor
//class User {
//    @IdProperty
//    private Integer id;
//    private String username;
//    private String password;
//    @OrderProperty
//    private Integer order;
//
//    public static void main(String[] args) {
//        ArrayList<User> users = new ArrayList<>();
//        users.add(new User(1, "乔峰", "降龙十八掌", 1));
//        users.add(new User(2, "段誉", "六脉神剑", 2));
//        users.add(new User(3, "虚竹", "北冥神功", 3));
//        users.add(new User(4, "鸠摩智", "小无相功", 4));
//        users.add(new User(5, "慕容复", "斗转星移", 5));
//        users.add(new User(6, "丁春秋", "化功大法", 6));
//        List<User> sort = SortUtil.sort(users, 1, 6, SortType.BUBBLE);
//        sort.sort(Comparator.comparingInt(User::getOrder));
//        sort.forEach(System.out::println);
//    }
//}
package com.ciih.jwt.util.sort;

public enum SortType {
    /**
     * <p>排序方式<p/>
     * <>1交换式</>
     * <>2冒泡式</>
     */
    EXCHANGE(1), BUBBLE(2);
    private Integer status;

    SortType(Integer status) {
        this.status = status;
    }

    public Integer getStatus() {
        return status;
    }
}
package com.ciih.jwt.util.sort;

import java.lang.annotation.*;

/**
 * @author sunziwen
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface IdProperty {
}
package com.ciih.jwt.util.sort;

import java.lang.annotation.*;

/**
 * @author sunziwen
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface OrderProperty {
}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/147752.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 异步和同步的区别_同步和异步请求的区别

    异步和同步的区别_同步和异步请求的区别”同步“就好比:你去外地上学(人生地不熟),突然生活费不够了;此时你决定打电话回家,通知家里转生活费过来,可是当你拨出电话时,对方一直处于待接听状态(即:打不通,联系不上),为了拿到生活费,你就不停的oncall、等待,最终可能不能及时要到生活费,导致你今天要做的事都没有完成,而白白花掉了时间。“异步”就是:在你打完电话发现没人接听时,猜想:对方可能在忙,暂时无法接听电话,所以你发了一条短信(或…

    2025年8月1日
    3
  • 云南 代理服务器_今日更新快速ip代理服务地址 免费国外代理服务器 2013.4.17

    云南 代理服务器_今日更新快速ip代理服务地址 免费国外代理服务器 2013.4.1761.175.223.134:3128@HTTP;浙江省台州市电信61.175.223.142:3128@HTTP;浙江省台州市电信60.190.129.52:3128@HTTP;浙江省嘉兴市电信代理ip61.166.55.153:11808@HTTP;云南省昭通市电信115.124.73.166:8080@HTTP;印度尼西亚雅加达市180.250.79.122:8080@HTTP;印度…

    2022年4月28日
    380
  • matlab自带的插值函数interp1的几种插值方法[通俗易懂]

    matlab自带的插值函数interp1的几种插值方法[通俗易懂]插值法    插值法又称“内插法”,是利用函数f(x)在某区间中已知的若干点的函数值,作出适当的特定函数,在区间的其他点上用这特定函数的值作为函数f(x)的近似值,这种方法称为插值法。如果这特定函数是多项式,就称它为插值多项式。线性插值法    线性插值法是指使用连接两个已知量的直线来确定在这两个已知量之间的一个未知量的值的方法。    假设我们已知坐标(x0,y0)与…

    2022年6月13日
    56
  • matlab控制倒立摆小车并绘制二维动态效果图[通俗易懂]

    matlab控制倒立摆小车并绘制二维动态效果图[通俗易懂]clc;closeall;clearA=[0100;00-1.1760;0001;0018.2930];%设置倒立摆小车控制系统参数B=[0;1;0;-1.667];C=[1000;0010];G=[42.851.04;471.8322.39;0.9443.15;19.17464.64];K=[-9.1841-10.7148-63.8735-15.4258];sim(‘CAR.mdl’);%运行倒立摆小车控制系…

    2022年8月18日
    5
  • rider 激活码分享【中文破解版】

    (rider 激活码分享)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlS32PGH0SQB-eyJsaWNlbnNlSWQi…

    2022年3月25日
    382
  • Navicat 15 for MySQL激活码【2021最新】

    (Navicat 15 for MySQL激活码)JetBrains旗下有多款编译器工具(如:IntelliJ、WebStorm、PyCharm等)在各编程领域几乎都占据了垄断地位。建立在开源IntelliJ平台之上,过去15年以来,JetBrains一直在不断发展和完善这个平台。这个平台可以针对您的开发工作流进行微调并且能够提供…

    2022年3月22日
    379

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号