【java 集合批量移动元素】

集合批量移动元素

需求:某1196高校要举办一个不知其名的活动,随机选了几个班级的某几个学生参加活动,学生到指定地点后,要对学生的座位号进行调整。前提学生本身有自己的座位号,同一个班级的座位号需要从小到大的坐,要求在调整座位号的时候,同一个班的学生必须坐在一起。

分析

其实这就是一个集合元素的移动,同一个班级的学生要求坐在一起其实就是根据对象某个属性进行【合并】的操作,前后调整座位号的时候,当向前调整的时候,如果座位号小于前一个班级的最大的座位号;当先后调整的时候,如果座位号大于后一个班级最小的座位号,那么前后两个班级的座位号需要整体互换。同一个班级的前后座位号的人对调位置即可。其实仔细想这不就是带合并单元格的表格选中几行上下移动吗?

代码实现

package entity;

/**
 * @description: 学生信息
 * @author: pks
 * @date: 2024/7/14 19:26
 */
public class Student {
    /**
     * ID
     */
    private Integer id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 班级
     */
    private String classGrades;

    /**
     * 省
     */
    private String province;

    /**
     * 市
     */
    private String city;

    /**
     * 县
     */
    private String county;

    /**
     * 详细地址
     */
    private String address;

    /**
     * 生日
     */
    private String birthday;

    /**
     * 座位号
     */
    private Integer seatNumber;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClassGrades() {
        return classGrades;
    }

    public void setClassGrades(String classGrades) {
        this.classGrades = classGrades;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCounty() {
        return county;
    }

    public void setCounty(String county) {
        this.county = county;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getBirthday() {
        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public Integer getSeatNumber() {
        return seatNumber;
    }

    public void setSeatNumber(Integer seatNumber) {
        this.seatNumber = seatNumber;
    }
}

package util;

import entity.Student;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Stack;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @description: 移动排序
 * @author: pks
 * @date: 2024/7/14 19:34
 */
public class SortUtils {
    /**
     * 前移
     */
    public static final String FRONT_DIRECTION = "front";

    /**
     * 后移
     */
    public static final String REAR_DIRECTION = "rear";

    /**
     * 学生座位移动
     *
     * @param moveDirection 移动方向 front or rear
     * @param studentList 所有学生
     * @param moveStudentList 移动座位的学生
     * @return 移动后排序的学生
     */
    public static List<Student> moveStudent(String moveDirection, List<Student> studentList, List<Student> moveStudentList) {
        List<Student> result = new ArrayList<>();
        // 所有学生大于等于2时才有移动座位的必要
        if (moveStudentList == null || studentList.size() < 2) {
            return studentList;
        }
        // 学生按照班级分组
        Map<String, List<Student>> studentsMap = studentList.stream().collect(Collectors.groupingBy(Student::getClassGrades));
        // 学生最终的排序,按照同一班级里面最小的序号再进行排序
        List<Student> lastSortStudents = getMinNumberStudents(studentsMap);

        Map<String, Integer> sortClassGradesMap = new HashMap<>();  // 按照班级整体排序
        Map<Integer, String> reverseSortClassGradesMap = new HashMap<>(); // 班级学生整体排序key,value互换
        Integer wholeSort = 1;
        for (Student lastSortStudent : lastSortStudents) {
            sortClassGradesMap.put(lastSortStudent.getClassGrades(), wholeSort);
            reverseSortClassGradesMap.put(wholeSort, lastSortStudent.getClassGrades());
            wholeSort ++;
        }

        for (Student moveStudent : moveStudentList) {
            List<Student> students = studentsMap.get(moveStudent.getClassGrades());
            // 前移比较最小值
            Student minSortStudent = students.stream()
                .min(Comparator.comparing(Student::getSeatNumber)).orElse(null);
            // 后移比较最大值
            Student maxSortStudent = students.stream()
                .max(Comparator.comparing(Student::getSeatNumber)).orElse(null);
            Integer seatNumber = moveStudent.getSeatNumber();
            // 当前批量项目整体序号
            Integer currentBatchSort = sortClassGradesMap.get(moveStudent.getClassGrades());
            if (FRONT_DIRECTION.equals(moveDirection)) {
                seatNumber = seatNumber - 1;
                if (minSortStudent != null && seatNumber < minSortStudent.getSeatNumber()) {
                    // 前一个班级整体序号
                    Integer preBatchSort = currentBatchSort - 1;
                    String preClassGrades = reverseSortClassGradesMap.get(preBatchSort);
                    sortClassGradesMap.put(moveStudent.getClassGrades(), preBatchSort);
                    reverseSortClassGradesMap.put(preBatchSort, moveStudent.getClassGrades());
                    sortClassGradesMap.put(preClassGrades, currentBatchSort);
                    reverseSortClassGradesMap.put(currentBatchSort, preClassGrades);
                }
            }
            if (REAR_DIRECTION.equals(moveDirection)) {
                seatNumber = seatNumber + 1;
                if (maxSortStudent != null && seatNumber > maxSortStudent.getSeatNumber()) {
                    // 后一个班级的整体序号
                    Integer nextBatchSort = currentBatchSort + 1;
                    String nextClassGrades = reverseSortClassGradesMap.get(nextBatchSort);
                    sortClassGradesMap.put(moveStudent.getClassGrades(), nextBatchSort);
                    reverseSortClassGradesMap.put(nextBatchSort, moveStudent.getClassGrades());
                    sortClassGradesMap.put(nextClassGrades, currentBatchSort);
                    reverseSortClassGradesMap.put(currentBatchSort, nextClassGrades);
                }
            }

            // 利用堆栈对学生排序
            students = stackSortStudent(students, moveStudent, moveDirection);
            studentsMap.put(moveStudent.getClassGrades(), students);
        }
        for (int i = 1; i <= lastSortStudents.size(); i ++) {
            String projectName = reverseSortClassGradesMap.get(i);
            result.addAll(studentsMap.get(projectName));
        }
        return result;
    }

    private static List<Student> getMinNumberStudents(Map<String, List<Student>> studentsMap) {
        List<Student> sortStudents = new ArrayList<>();
        // 同一个班级里面座位最小的学生
        for (List<Student> value : studentsMap.values()) {
            if (value == null || value.size() == 0) {
                continue;
            }
            Student minSortStudent = value.stream()
                .min(Comparator.comparing(Student::getSeatNumber)).orElse(null);
            sortStudents.add(minSortStudent);
        }
        // 学生最终的排序,按照同班级学生里面座位号最小的学生再进行排序
        return sortStudents.stream()
            .sorted(Comparator.comparing(Student::getSeatNumber, Comparator.nullsLast(Integer::compareTo))).collect(Collectors.toList());
    }

    /**
     * 学生重新排序
     *
     * @param students 学生集合
     * @param moveStudent 移动学生
     * @param moveDirection 移动方向
     * @return 移动后重新排序学生
     */
    public static List<Student> stackSortStudent(List<Student> students, Student moveStudent, String moveDirection) {
        Stack<Student> studentStack = new Stack<>();
        Queue<Student> studentQueue = new LinkedList<>(students);
        while (studentStack.size() < students.size()) {
            Student poll = studentQueue.poll();
            if (poll == null) {
                continue;
            }
            if (poll.getId().equals(moveStudent.getId())) {
                if (FRONT_DIRECTION.equals(moveDirection)) {
                    if (!studentStack.isEmpty()) {
                        // 上移先进的元素取出放在当前元素后面
                        Student pop = studentStack.pop();
                        studentStack.push(poll);
                        studentStack.push(pop);
                    } else {
                        studentStack.push(poll);
                    }
                }
                if (REAR_DIRECTION.equals(moveDirection)) {
                    Student next = studentQueue.poll();
                    // 下移将下一个元素先放进栈
                    if (next != null) {
                        studentStack.push(next);
                    }
                    studentStack.push(poll);
                }
            } else {
                studentStack.push(poll);
            }
        }
        return  new LinkedList<>(studentStack);
    }

    public static void main(String[] args) {
        List<Student> students = new ArrayList<>();
        for (int i = 0; i < 20; i++) {
            Student student = new Student();
            student.setId(i);
            student.setSeatNumber(i);
            student.setName("student" + i);
            if (i < 6) {
                student.setClassGrades("666班");
            } else if (i < 12) {
                student.setClassGrades("888班");
            } else {
                student.setClassGrades("999班");
            }
            students.add(student);
        }
        for (Student student : students) {
            System.out.println(student.getClassGrades() + " : " + student.getName() + ":" + student.getSeatNumber());
        }

        System.out.println("***************************重新调整座位号************************************");

        Map<Integer, Student> studentMap = students.stream().collect(Collectors.toMap(Student::getId, Function.identity()));
        List<Student> sortStudents = moveStudent(REAR_DIRECTION, students, Arrays.asList(studentMap.get(5), studentMap.get(12)));
        for(int i = 0; i < sortStudents.size();i ++) {
            sortStudents.get(i).setSeatNumber(i);
        }
        for (Student student : sortStudents) {
            System.out.println(student.getClassGrades() + " : " + student.getName() + ":" + student.getSeatNumber());
        }
    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值