0
点赞
收藏
分享

微信扫一扫

高薪程序员&面试题精讲系列56之Java中如何实现行转列?又如何实现列转行?

一叶轻舟okok 2022-01-13 阅读 22

一. 面试题及剖析

1. 今日面试题

2. 题目剖析

今天 壹哥 给大家讲解的这个题目,与之前的题目有些不同。那么哪里有不同呢?我们仔细回想一下之前的面试题,你会发现之前很多题目都是以记忆、理解、底层探究为主,但今天的题目其实是以提供解决问题的思路和方案为主。

我们在面试时,可能会遇到各种各样的面试官,这些面试官都有自己的风格,他们提问的角度也不同。有的人就喜欢追着问知识点,有的就喜欢追着问项目细节,还有的人喜欢追着问解决方案。我们今天的题目,就属于在考察求职者解决问题的思路、思维,看看求职者是否有解决问题的开拓性想法,其实这个能力对于我们做项目来说更为重要一些。所以有挺多面试官多会给求职者抛出类似于这样的问题:你遇到过xxx情况吗?这种情况你是怎么解决的?如果你遇到xxx问题,你该怎么解决,你有哪些思路?......

对于这类题目,面试官一方面是在考察我们是否经历过这种问题,从而可以判断出我们的经验水平;另一方面,其实更多的是在看我们的思维逻辑能力。这种题目的答案,其实都不是唯一的,也并没有固定的标准答案,主要看我们敢不敢想,能不能想,有没有想!有些求职者,遇到类似的这种问题,觉得自己确实没有遇到过这种情况,然后就想也不想,直接给人家面试官来一句:我没遇到过,我不知道.......

如果你这样回答问题,你觉得面试官会怎么想?会怎么判定你?某种情况你可能没有遇到过,但你一定要有自己的思路和解决方案,这个解决方案未必就正确,但你得给出自己的想法!要不然以后真把你招到项目组里来了,遇到个难题,你就跟老大说我以前没碰到过这情况,我弄不了,那人家公司花这么多钱招你干嘛来的啊?!是为了听你说不知道的吗?

二. 参考答案

1. 需求背景

行转列、列转行这样的需求,一般是在做表格效果时会遇到,常见的就是Excel报表统计、Excel文件的导入导出等。

对于行转列或者列转行,我们的实现方案,其实可以从3个维度来进行考虑实现:

本例中会采用第2种实现方案,即采用Java后端代码,对查询出的数据集合进行转换。

2. 转换前的效果

这里我先用LayUI编写了一个分页效果页面,下面是未进行 行转列之前的效果图:

从图中可以看出,id、姓名、地址、性别等数据在一行中展示,而此时前端从后端返回的JSON数据格式如下所示:

{
	"code": 0,
	"msg": "success",
	"count": 14,
	"data": [{
		"id": 3,
		"username": "壹壹哥",
		"address": "上海",
		"sex": "男"
	}, {
		"id": 4,
		"username": "壹哥",
		"address": "上海",
		"sex": "男"
	},......]
}

这是用JSON格式化工具进行格式化后的效果。

从中可以看出,id、username、address、sex等字段同时被封装在一个json对象中。那么接下来,我们就需要对这个表格中的数据进行 行转列的变换,那么该如何实现呢?壹哥 把核心代码提供给大家了,大家可以参考下面的内容。

3. 转换代码

以下是实现行转列的关键代码,大家可以参考实现。

3.1 User类

为了方便封装数据,我这里会定义一个User类,后面进行 行转列时会对该类进行操作。

@Data
@ToString
public class User {

    private Integer id;

    private String username;

    private String address;

    private String sex;

}

3.2 行转列核心类

我把行转列的操作,定义在了service层,各位可以按照根据自己的需求,把行转列的核心代码进行自定义调用。

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private com.yyg.boot.mapper.UserMapper userMapper;

  	//本案例中用到了PageHeper分页类,它与行列转换没有关系,只是为了实现分页效果,你完全可以去掉PageHelper的内容。
    @Override
    public PageInfo<User> findUsers(Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<User> list = userMapper.findUsers();

        //进行行转列操作,调用封装的行转列代码
        List convertList = convert(User.class, list);
        return new PageInfo<User>(convertList);
    }

    /**
     * 封装行转列的实现方法,主要是利用了反射,对集合中JavaBean的字段进行取值
     */
    public <T> List convert(Class<T> clazz, List<T> list) {
      	//获取字节码中的所有字段
        Field[] fields = clazz.getDeclaredFields();
      	//创建一个空的List集合,在该集合中又嵌套了一个List集合
        List<List> result = new ArrayList<>(fields.length);
        for (int i = 0; i < fields.length; i++) {
          	//添加若干个空的List集合
            result.add(new ArrayList());
        }

        for (T t : list) {
            for (int i = 0; i < fields.length; i++) {
              	//取出每个List集合
                List l = result.get(i);
                Field field = fields[i];
                field.setAccessible(true);
                try {
                  	//将字段中的数据,添加到集合中
                    l.add(field.get(t));
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }
        }

        return result;
    }

}

4. 转换后的效果

当我们转换后,此时得到的JSON数据格式如下:

{"code":0,"msg":"success","count":4,
 "data":[[3,4,5,7,9,11,14,15,16,18],
         ["壹壹哥","壹哥","一一哥","一一哥","一一哥","一一哥","一一哥","一一哥","一一哥22","一一哥22"],
         ["上海","上海","上海","上海","上海","上海","上海","上海","上海","上海"],
         ["男","男","男","男","男","男","男","男","男","男"]]}

利用JSON格式化工具对以上JSON进行格式化,得到的效果如下图所示:

这时我们会发现,此时JSON中的data数组,内部的数据与之前的数据完全不同了,前端只需要根据新的JSON数组进行页面渲染就可以了。

三. 结语

另外对于列转行,请参考我的代码,进行逆向处理。

今天的题目,其实答案并不唯一,壹哥 在这里只能给大家提供一些参考实现,各位可能会有更好的解决思路,就算是抛砖引玉吧,如果你有更好的解决思路,请在评论区留言给我哦。

举报

相关推荐

0 条评论