背景

本人还是比较喜欢java8 stream的流式处理数据,它的mapfilter等操作都让我重新正视了java一眼,就好像你分手多年后偶然见到了变漂亮的前女友时的眼前一亮(我瞎说的,你别当真!!!)

不过相处一段时间后发现,使用起来还是有些许疼痛(也有可能是我不会用),比如:

  • 无法连续简洁的.出来操作
  • 批量修改list里面的值有些困难

所以结合使用场景,本人简单粗暴地开发了Distream,希望它可以实现真正的数据流式丝滑处理

java流式数据 java流式数据处理_java流式数据

简要使用说明

1、综合案例

假设有一个实体列表ListFrame<Entity> entitiesEntity如下:

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;
/*code的值转为int并赋值给id  等价于  line.put("id",Integer.valueOf(code))*/
lines = lines.handle("id=int(code)");

/*value的值转为double并赋值给percent  等价于  line.put("percent",Double.valueOf(code))*/
lines = lines.handle("percent=double(value)");

/*value的值转为string并赋值给name等价于  line.put("name",value+"")*/
lines = lines.handle("name=string(value)");

/*等价于string的substring*/
lines = lines.handle("name=substring(name,1,2)");

/*把name的"xxx" 替换为"yyy"*/
lines = lines.handle("name=replace(name,'xxx','yyy')");
/*把name的"xxx" 替换为""*/
lines = lines.handle("name=name-'xxx'");

/*类似于ndexof*/
lines = lines.handle("id=index(name,'xxx')");

/*percent保留两位小数*/
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()
/*得到map {2=3,4=1}*/
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);
//ListFrame<Map<String, Object>> lines = ListFrame.readMap(path,",");
//读取并指定数据类型
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'+序号;姓名=序号+姓名")//add "0" at the front of 序号;rename 姓名 by 序号+姓名
        .handle(new MapHandler());//表达式不方便处理时 可自定义处理器 实现DataHandler即可
public class MapHandler implements DataHandler<Map<String, Object>> {
    @Override
    public Map<String, Object> handle(Map<String, Object> line) {
        line.put("newKey",1);
        return line;
    }
}

或者使用java8简写处理器

ListFrame<Map<String, Object>> lines = ListFrame.readMap(path,new Class[]{Integer.class,String.class,Integer.class,Double.class});
lines = lines.handle(map->{
  map.put("newKey",1);
  return map;
});
11、数据库读取
Datasource datesource = xxx;
ListFrame list = new ListFrame();
//推荐new DruidDataSource()
list.initDataSource(datesource);
lines = list.readSql("select * from xxx").handle(a->...).handle(a->...)...;

文档和开源地址

开源地址和使用说明

欢迎提提建议,谢谢!