背景
本人还是比较喜欢java8 stream的流式处理数据,它的map、filter等操作都让我重新正视了java一眼,就好像你分手多年后偶然见到了变漂亮的前女友时的眼前一亮(我瞎说的,你别当真!!!)
不过相处一段时间后发现,使用起来还是有些许疼痛(也有可能是我不会用),比如:
- 无法连续简洁的.出来操作
- 批量修改list里面的值有些困难
所以结合使用场景,本人简单粗暴地开发了Distream,希望它可以实现真正的数据流式丝滑处理
简要使用说明
1、综合案例
假设有一个实体列表ListFrame<Entity> entities,Entity如下:
public class Entity{
private String name;
private Double value;
private Double percent;
}
需要的做的操作步骤为遍历entities,然后:
- value的值保留两位小数
- name为null时赋值 “”
- value为null时赋值0,否则 加上2
- 将name里面的#替换掉
- 计算value的占比,并赋值给percent
- 最后根据name分组求percent的和
那么,以上6个操作步骤就可以写为:
List<Entity> entityList = xxxx;
MapFrame<Object,Double> groups = ListFrame.fromList(entityList )
.handle("value=format(value,2)")
.handle(entity->entity.getName()==null,"name=''")
.handle(entity->entity.getValue()==null,"value=0","value=value+2")
.handle("name=replace(name,'#','')")
.handle("percent=double(value)/"+sum)
.groupBy("name").sum("percent");
也可以合并表达式为:
MapFrame<Object,Double> groups = entities
.handle(entity->entity.getName()==null,"name=''")
.handle(entity->entity.getValue()==null,"value=0","value=value+2")
.handle("name=replace(name,'#','');value=format(value,2);percent=double(value)/"+sum)
.groupBy("name").sum("percent");
2、表达式内使用函数
字符表达式不仅可以对对象类型使用,也可以对Map进行使用,handle方法会对list里面的每个元素进行处理
ListFrame<Map<String, Object>> lines = xxx;
lines = lines.handle("id=int(code)");
lines = lines.handle("percent=double(value)");
lines = lines.handle("name=string(value)");
lines = lines.handle("name=substring(name,1,2)");
lines = lines.handle("name=replace(name,'xxx','yyy')");
lines = lines.handle("name=name-'xxx'");
lines = lines.handle("id=index(name,'xxx')");
lines = lines.handle("percent=format(percent,2)");
3、求最值
求最值仅对数字类型有效
List<Integer> list = Arrays.asList(2,3,4,5,8,9,4);
ListFrame<Integer> listFrame = ListFrame.fromList(list );
int max = listFrame.max();
int min= listFrame.min();
int avg = listFrame.avg();
double sum= listFrame.sum();
求最值索引
int argmax= listFrame.argmax();
int argmin= listFrame.argmin();
4、类型转换
List<String> list = Arrays.asList("1","2","3","4");
ListFrame<Integer> listFrame = ListFrame.fromList(list );
ListFrame<Integer> listInt= listFrame.asInteger();
ListFrame<Double> listDouble= listFrame.asDouble();
ListFrame<Float> listFloat= listFrame.asFloat();
ListFrame<String> listString= listFloat.asString();
5、统计元素个数
List<Integer> list = Arrays.asList(2,2,2,4);
MapFrame<Integer,Integer> listFrame = ListFrame.fromList(list).frequency()
6、方差和标准差
List<Integer> list = Arrays.asList(2,2,2,4);
ListFrame<Integer> listFrame = ListFrame.fromList(list );
listFrame.variance();
listFrame.standardDeviation();
7、去重
List<Integer> list = Arrays.asList(2,2,2,4);
ListFrame<Integer> listFrame = ListFrame.fromList(list ).distinct();
8、分组统计
MapFrame<Object, ListFrame> agesGroup = lines.groupBy("年龄");
MapFrame<Object, Integer> count = agesGroup.count();
MapFrame<Object, Double> incomeAvg = agesGroup.avg("收入");
MapFrame<Object, Double> incomeSum = agesGroup.sum("收入");
MapFrame<Object, ListFrame> incomeConcat = agesGroup.concat("收入");
MapFrame<Object, MapFrame<Object, ListFrame>> incomeAgeConcat = lines.groupBy("收入").groupBy("年龄");
9、map与对象转换
ListFrame<Map> maps= ListFrame.readMap(path);
ListFrame<User> users = maps.toObjectList(User.class);
ListFrame<Map> map2s = users.toMapList();
ListFrame<User2> user2s = lines.toObjectList(User.class).toObjectList(User2.class);
10、文件数据读取
按行读取文件
ListFrame<String> lines = ListFrame.readString("test.txt");
将csv文件读取为map(或者对象)
序号,姓名,年龄,收入
1,张三,23,5000.11
2,李四,22,4000.22
3,李二狗,20,5000.33
...
ListFrame<Map<String, Object>> lines = ListFrame.readMap(path,new Class[]{Integer.class,String.class,Integer.class,Double.class});
lines = lines
.handle("收入=收入*0.8")
.handle("序号='0'+序号;姓名=序号+姓名")
.handle(new MapHandler());
public class MapHandler implements DataHandler<Map<String, Object>> {
@Override
public Map<String, Object> handle(Map<String, Object> line) {
line.put("newKey",1);
return line;
}
}
11、数据库读取
Datasource datesource = xxx;
ListFrame list = new ListFrame();
list.initDataSource(datesource);
lines = list.readSql("select * from xxx").handle(a->...).handle(a->...)...;
文档和开源地址
开源地址和使用说明
欢迎提提建议,谢谢!
|