根据某个对象属性,获取对象集合中所有不重复的值(去重)
比如现在有个studentView(继承自student),里面有id,name,age,home,province,school,grade等字段,现在有一个List<student>的集合,现在想知道这些student都分布在哪些province,哪些school,和他们的home都有哪些;
以后可能还有实体类team,有id,teamName,level,school等;
正常情况我们会用sql的形式,用distinct的方式,逐个返回,但现在因为数据都已经返回到了后端,不想再通过查询数据库的方式获取,那么在后台该怎么实现呢?
1、因为要处理不同实体类的集合,所有要用到泛型
2、到时候要根据不同的属性字段,进行去重,所有要用到java的反射类
3、其余的要用到一个临时map集合,用于判断去重
下面是实现代码:
import java.lang.reflect.Field;
import org.apache.commons.lang.StringUtils;
//上面是两个特殊的包,一个是反射类的,一个是判断非空的,因为用到了,所有提一下
public static<T> List<T> distinctByAttr(List<T> mcList, String attr) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException { Map<String, String> tempMap = new HashMap<>(); List<T> returnList = new ArrayList<>(); for(T item : mcList){ Field field = null; Class<?> clazz = item.getClass(); for (; clazz != Object.class; clazz = clazz.getSuperclass()) { try { field = clazz.getDeclaredField(attr); //这种是因为有些属性是View(即父类)里面的,要牺牲这样大概10行代码来处理 } catch (Exception e) { // 这里甚么都不能抛出去。 // 如果这里的异常打印或者往外抛,则就不会进入 } } //Field field = item.getClass().getDeclaredField(attr);//如果属性值都是实体类里面存在的话,这种一行代码就搞定,很方便 field.setAccessible(true);//这句很关键,不能少 //String echoValue = item.getProvince(); String echoValue = field.get(item) == null ? "" : field.get(item).toString();//这里是考虑到属性值有为空的时候,避免抛出异常
//下面就是如何去重了 if(echoValue.equals("")){ continue; }else{ String mapValue = tempMap.get(echoValue);//如果mapValue是空的 说明取到的这个是第一次取到 if(StringUtils.isBlank(mapValue)){ tempMap.put(echoValue, echoValue); returnList.add(item);//这里最好返回List<String>,里面放去重后的值,返回List<Object>的话,取值时要知道是根据那个属性去重后的 }else{ continue; } } } tempMap.clear(); return returnList; }
下面大概讲下如何调用这个静态公有方法
//直接类名.静态方法名就好了,这里List就是封装好的list数据,attr就是对应实体类里面的字段名(这个一定不能拼写错)
MgCommonService.distinctByAttr(List, "attr");
这也是第一次实际运用泛型,并且结合反射类,END!!