我正在参加「创意开发 投稿大赛」详情请看:掘金创意开发大赛来了!
排序
- 上文我们提到了如何巧妙解决前端甩过来的数据不全这个锅了。我们也通过抽象的方法进行数据填充。本以为可以盒盖下班了,没想到在我左脚刚出公司的那一刻前端的Call来了。这次甩过来的锅名叫【数据错乱】。
- 家里的娃子已经不停的催我回家了,但是没办法只能硬着头皮回去打开电脑和前端耐心的沟通。
- 前端很自然的说看,你给的数据测试验证不通过,仔细查看数据库发现数据查出来是没问题的,但是前段是按照我给的顺序自动加载的,而横坐标的内容是它提前写死的,换句话来说我必须按照ACBD的顺序才可以。这个时候我心中是万马奔腾。
问题所在
- 仔细分析下,的确在日常开发配合中排序也是我们所头疼的问题。不过大多数我们都是通过数据库排序就可以解决的,但是数据库的排序也是有个问题,在数字排序上相同位数的排序没有问题,但是不同位数排序会存在错乱问题。
- 另外就是我们有些场景是需要组装数据的,这个时候数据库的排序就不能解决我们的问题。
- 不同的问题,但是我们是同样的处理流程,根据场景找出问题所在,然后进行设计最后开发验证。
- 首先我们得准备好一个最终排序的集合,我们才能够将带排序内容按照我们的预定顺序进行排序。所以这里就需要子类提供一个这样的方法
public abstract class DataOrder {
/**
* @author zxhtom
* @Description 由子类提供排序规则
*/
public abstract List<List<String>> orderData();
public <T> List<T> orderValue(List<T> list,String... fieldNames) {
return orderValue(1, list, fieldNames);
}
/**
* @author zxhtom
* @Description 将list按照fieldNames字段一次排序 , direction表示排序方向
*/
public <T> List<T> orderValue(Integer direction , List<T> list,String... fieldNames) {
//TODO
return collect;
}
public <T> Object getValue(T item,String fieldName){
//TODO
return null;
}
}
复制代码
- 同样我们在父类中就需要进行整体规划设计。最终是在
orderValue
中实现我们的排序的,而Java的排序也是很简单的,我们借助Stream既可以快速完成排序。但是Stream的排序内核是需要我们提供比较大小依据的,而我们判断大小即可抽象出来放在getValue
中进行比较。
public <T> List<T> orderValue(Integer direction , List<T> list,String... fieldNames) {
List<List<String>> orderList = orderData();
List<T> collect = list.stream().sorted((itemFirst, itemSecond) -> {
Integer resultOrderIndex = 0;
for (int i = 0; i < fieldNames.length; i++) {
if (orderList.size() > i) {
List<String> singleOrderList = orderList.get(i);
int indexFirst = singleOrderList.indexOf(getValue(itemFirst, fieldNames[i]));
int indexSecond = singleOrderList.indexOf(getValue(itemSecond, fieldNames[i]));
if (indexFirst != indexSecond) {
if (indexFirst == -1) {
indexFirst = Integer.MAX_VALUE;
}
if (indexSecond == -1) {
indexSecond = Integer.MAX_VALUE;
}
resultOrderIndex = indexFirst - indexSecond;
break;
}
}
}
return direction * resultOrderIndex;
}).collect(Collectors.toList());
return collect;
}
复制代码
- 很明显我们在
Stream
的框架下进行排序,内核借助getValue
这个方法。
public <T> Object getValue(T item,String fieldName){
Class<?> itemClass = item.getClass();
if (itemClass.isAssignableFrom(Map.class)||item instanceof Map) {
Map<String, Object> itemMap = (Map<String, Object>) item;
if (itemMap.containsKey(fieldName)) {
return itemMap.get(fieldName);
}
} else if(itemClass.isAssignableFrom(JSONObject.class)||item instanceof JSONObject){
JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(item));
if (jsonObject.containsKey(fieldName)) {
return jsonObject.get(fieldName);
}
}else if(itemClass.isAssignableFrom(String.class)){
return item;
}else {
Object o = null;
try {
Field field = itemClass.getField(fieldName);
field.setAccessible(true);
return field.get(item);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
return null;
}
复制代码
- 而
getValue
这个方法就是按照子类提供的数据进行排序的。
使用
List<String> strings = new DataOrder() {
@Override
public List<List<String>> orderData() {
List<List<String>> result = new ArrayList<>();
result.add(Arrays.asList(new String[]{"删除","查看","打印","导出","添加气体检测","添加送电过程","添加停电过程"}));
return result;
}
}.orderValue(powerList,"");
resultMap.put("data", strings);
复制代码
- 这样我们就完成了排序功能,将使用与开发抽离,两者不会互相污染。
总结
- 同样是常见的问题,同样的简单的解法,但是经过封装之后在使用就会简单明了且容易迭代的一个创意Idea。希望自己能够逐渐搭建出自己的创意宇宙。啦啦啦!!!