JAVA行轉列工具類

目錄

show me the code

使用方法

測試代碼


有時爲了統計的需要,需要將數據進行行轉列,在數據庫中一般用CASE WHEN語句來解決,但無法生成生成列標題,如果遇到想動態生成列的情況,用CASE WHEN便不是那麼好處理了


正好最近我的一個個人小項目中遇到了這個問題,需要根據數據動態生成列標題,同時數據量不多,便想到自己寫一個JAVA版通用的數據行轉列的工具類

show me the code

本人寫的工具類代碼如下:

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

/**
 * 行轉列工具類
 * created on 2020/4/1 9:47
 *
 * @author puhaiyang
 */
public class RowConvertColUtil {
    private static final String NULL_VALUE = "";
    private static final String HEADER_NULL_VALUE = "";
    private static Set<Object> headerSet;
    private static Set<Object> firstColSet;

    private RowConvertColUtil() {
    }

    public static class ConvertData {
        private Set<Object> headerSet;
        private Set<Object> firstColSet;
        private List<List<Object>> dataList;

        public ConvertData(List<List<Object>> dataList, Set<Object> headerSet, Set<Object> firstColSet) {
            this.headerSet = headerSet;
            this.firstColSet = firstColSet;
            this.dataList = dataList;
        }

        public Set<Object> getHeaderSet() {
            return headerSet;
        }

        public void setHeaderSet(Set<Object> headerSet) {
            this.headerSet = headerSet;
        }

        public Set<Object> getFirstColSet() {
            return firstColSet;
        }

        public void setFirstColSet(Set<Object> firstColSet) {
            this.firstColSet = firstColSet;
        }

        public List<List<Object>> getDataList() {
            return dataList;
        }

        public void setDataList(List<List<Object>> dataList) {
            this.dataList = dataList;
        }
    }

    /**
     * 行轉列,返回ConvertData
     *
     * @param orignalList   原始list
     * @param headerName    列表頭字段名
     * @param firstColName  首列字段名
     * @param valueFiedName 值列的字段名
     * @param needHeader    是否需要返回列表頭
     * @return ConvertData
     */
    public static synchronized ConvertData doConvertReturnObj(List orignalList, String headerName, String firstColName, String valueFiedName, boolean needHeader) throws Exception {
        List<List<Object>> lists = doConvert(orignalList, headerName, firstColName, valueFiedName, needHeader);
        return new ConvertData(lists, headerSet, firstColSet);
    }

    /**
     * 行轉列,返回轉換後的list
     *
     * @param orignalList   原始list
     * @param headerName    列表頭字段名
     * @param firstColName  首列字段名
     * @param valueFiedName 值列的字段名
     * @param needHeader    是否需要返回列表頭
     */
    public static synchronized List<List<Object>> doConvert(List orignalList, String headerName, String firstColName, String valueFiedName, boolean needHeader) throws Exception {
        headerSet = new LinkedHashSet<>();
        firstColSet = new LinkedHashSet<>();
        List<List<Object>> resultList = new ArrayList<>();

        getHeaderFirstcolSet(orignalList, headerName, firstColName);
        if (needHeader) {
            List<Object> headerList = new ArrayList<>();
            //填充進header
            headerList.add(HEADER_NULL_VALUE);
            headerList.addAll(headerSet);
            resultList.add(headerList);
        }
        for (Object firstColNameItem : firstColSet) {
            List<Object> colList = new ArrayList<>();
            //名稱
            colList.add(firstColNameItem);
            for (Object headerItem : headerSet) {
                boolean flag = true;
                for (Object orignalObjectItem : orignalList) {
                    Field headerField = orignalObjectItem.getClass().getDeclaredField(headerName);
                    headerField.setAccessible(true);
                    Field firstColField = orignalObjectItem.getClass().getDeclaredField(firstColName);
                    firstColField.setAccessible(true);
                    Field valueField = orignalObjectItem.getClass().getDeclaredField(valueFiedName);
                    valueField.setAccessible(true);
                    if (headerItem.equals(headerField.get(orignalObjectItem))) {
                        if (firstColNameItem.equals(firstColField.get(orignalObjectItem))) {
                            colList.add(valueField.get(orignalObjectItem));
                            flag = false;
                            break;
                        }
                    }
                }
                if (flag) {
                    colList.add(NULL_VALUE);
                }
            }
            resultList.add(colList);
        }
        return resultList;
    }

    private static void getHeaderFirstcolSet(List orignalList, String headerName, String firstColName) {
        try {
            for (Object item : orignalList) {
                Field headerField = item.getClass().getDeclaredField(headerName);
                headerField.setAccessible(true);
                Field firstColField = item.getClass().getDeclaredField(firstColName);
                firstColField.setAccessible(true);
                headerSet.add(headerField.get(item));
                firstColSet.add(firstColField.get(item));
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

代碼量不多,短短几十行。

使用方法

 

調用doConvertdoConvertReturnObj方法

 

測試代碼

再寫一個測試代碼:

import java.util.*;

/**
 * 行轉爲列測試
 * created on 2020/4/1 9:47
 *
 * @author puhaiyang
 */
public class RowConvertCol {
    private static class ScoreInfo {
        private String stuName;
        private String subjectName;
        private Integer value;

        public String getStuName() {
            return stuName;
        }

        public String getSubjectName() {
            return subjectName;
        }

        public Integer getValue() {
            return value;
        }

        public ScoreInfo(String stuName, String subjectName, Integer value) {
            this.stuName = stuName;
            this.subjectName = subjectName;
            this.value = value;
        }

        @Override
        public String toString() {
            return "ScoreInfo{" +
                    "stuName='" + stuName + '\'' +
                    ", subjectName='" + subjectName + '\'' +
                    ", value=" + value +
                    '}';
        }
    }

    public static void main(String[] args) throws Exception {
        func2();
    }

    private static void func2() throws Exception {
        List<ScoreInfo> scoreInfoList = new ArrayList<>();
        scoreInfoList.add(new ScoreInfo("張三", "語文", 61));
        scoreInfoList.add(new ScoreInfo("張三", "數學", 78));
        scoreInfoList.add(new ScoreInfo("張三", "英語", 93));
        scoreInfoList.add(new ScoreInfo("李四", "語文", 70));
        scoreInfoList.add(new ScoreInfo("李四", "數學", 86));
        scoreInfoList.add(new ScoreInfo("李四", "英語", 72));
        scoreInfoList.add(new ScoreInfo("王五", "語文", 66));
        scoreInfoList.add(new ScoreInfo("趙六", "語文", 91));
        scoreInfoList.add(new ScoreInfo("王五", "數學", 88));
        scoreInfoList.add(new ScoreInfo("趙六", "數學", 63));
        scoreInfoList.add(new ScoreInfo("王五", "英語", 93));
        scoreInfoList.add(new ScoreInfo("趙六", "英語", 58));
        scoreInfoList.add(new ScoreInfo("王七", "英語", 65));
        scoreInfoList.add(new ScoreInfo("王七", "數學", 91));
        for (ScoreInfo scoreInfo : scoreInfoList) {
            System.out.println(scoreInfo.toString());
        }

        System.out.println("-------------------");

        List<List<Object>> lists = RowConvertColUtil.doConvert(scoreInfoList, "subjectName", "stuName", "value", true);

        for (List<Object> list : lists) {
            System.out.println(list.toString());
        }
    }
}

測試輸出內容:

ScoreInfo{stuName='張三', subjectName='語文', value=61}
ScoreInfo{stuName='張三', subjectName='數學', value=78}
ScoreInfo{stuName='張三', subjectName='英語', value=93}
ScoreInfo{stuName='李四', subjectName='語文', value=70}
ScoreInfo{stuName='李四', subjectName='數學', value=86}
ScoreInfo{stuName='李四', subjectName='英語', value=72}
ScoreInfo{stuName='王五', subjectName='語文', value=66}
ScoreInfo{stuName='趙六', subjectName='語文', value=91}
ScoreInfo{stuName='王五', subjectName='數學', value=88}
ScoreInfo{stuName='趙六', subjectName='數學', value=63}
ScoreInfo{stuName='王五', subjectName='英語', value=93}
ScoreInfo{stuName='趙六', subjectName='英語', value=58}
ScoreInfo{stuName='王七', subjectName='英語', value=65}
ScoreInfo{stuName='王七', subjectName='數學', value=91}
-------------------
[, 語文, 數學, 英語]
[張三, 61, 78, 93]
[李四, 70, 86, 72]
[王五, 66, 88, 93]
[趙六, 91, 63, 58]
[王七, , 91, 65]

希望能有用

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章