V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
mmdsun
V2EX  ›  问与答

Java stream 如何优雅处理这种数据

  •  
  •   mmdsun · 2020-12-23 13:03:05 +08:00 via Android · 1386 次点击
    这是一个创建于 1191 天前的主题,其中的信息可能已经有所发展或是发生改变。

    [{

    	"bookName": "1",
    
    	"bookTypeId": "",
    
    	"attr": {
    
    		"typeId": "type-a"
    
    	}
    
    },
    
    
    
    {
    
    	"bookName": "2",
    
    	"bookTypeId": "",
    
    	"attr": {
    
    		"typeId": "type-b"
    
    	}
    
    }
    

    ]

    需要把 attr 对象中的 typeid 设置到外面 bookid 中,attr 对象可能为空,返回还是 List<Book>。类似于这种伪代码。请问这种怎么优雅实现。

    List<Book> collect = json.getBookList()
    
                .stream()
    
                .map(m -> m.setBookTypeId(m.getAttr().getTypeId())).collect(
    
    第 1 条附言  ·  2020-12-23 18:45:41 +08:00
    append:

    json.getBookList()
    .stream()
    .peek(book -> m.getArrt())
    .map(Arrt::getTypeId)
    .ifPresent(book::setBookTypeId))
    .collect()

    感谢大家,已解决。网上找到了类似写法。 明天试试看。
    (要改 set get 方法,setBookTypeId 需要返回 Book 的 this )

    回 5 楼 c# linq 确实给编程语言贡献了很多。
    14 条回复    2020-12-23 18:49:41 +08:00
    uselessVisitor
        1
    uselessVisitor  
       2020-12-23 13:19:18 +08:00 via Android
    你这样写挺好的
    canbingzt
        2
    canbingzt  
       2020-12-23 13:47:01 +08:00   ❤️ 1
    json.getBookList()
    .stream()
    .filter(m -> m.getAttr() != null)
    .forEach(m -> m.setBookTypeId(m.getAttr().getTypeId()))
    mmdsun
        3
    mmdsun  
    OP
       2020-12-23 14:40:42 +08:00 via Android
    @beichenhpy 不行。。我这样写要把 setBookTypeId 方法给改了返回 Book 才行,现在 set 方法返回的是 void,而且 getAttr().getId 会报空指针。😅
    xgfan
        4
    xgfan  
       2020-12-23 15:39:34 +08:00   ❤️ 1
    json.getBookList()
    .stream()
    .filter(m -> m.getAttr() != null &&m.getAttr().getTypeId()!=null )
    .peek(m -> m.setBookTypeId(m.getAttr().getTypeId()))
    Rwing
        5
    Rwing  
       2020-12-23 16:00:07 +08:00
    C#欢迎您

    var result = json.BookList
    .Where(b=>b.attr != null)
    .Select(b=>{ bookTypeId=b.attr.typeId; return b; })
    .ToList();
    taogen
        6
    taogen  
       2020-12-23 16:09:21 +08:00   ❤️ 1
    @canbingzt #2
    @xgfan #4

    Don't do that. If you use a functional pattern, do not bring any imperative/procedural stuff in it. The purpose of map is to transform an object into another object. It's meant to be purely functional (side-effect free) by design.
    taogen
        7
    taogen  
       2020-12-23 16:15:19 +08:00
    If we want to process this data in parallel, we are going to distribute it among all the cores of our processors and we do not want to have any kind of visibility or synchronization issues that could lead to bad performances or errors. Avoiding this kind of interference means that we shouldn't modify the source of the data while we're processing it.
    luban
        8
    luban  
       2020-12-23 16:18:28 +08:00
    @mmdsun 可以让 set 方法返回 this
    yuhuan66666
        9
    yuhuan66666  
       2020-12-23 16:19:55 +08:00
    这个赋值位置不能用 map map 要求返回一个新对象,但你的需求实际上是在原对象上添加元素 应该用 peek
    yuhuan66666
        10
    yuhuan66666  
       2020-12-23 16:21:12 +08:00
    看一下 《 java8 实战》对 stream 讲用法还不错
    liuxey
        11
    liuxey  
       2020-12-23 16:37:19 +08:00
    松散结构直接 stream 操作想想就可怕,NPE 教做人
    xgfan
        12
    xgfan  
       2020-12-23 16:37:46 +08:00
    @taogen 是的,你是对的。


    -----------
    最好是不要修改原有集合 /集合里的数据。
    mmdsun
        13
    mmdsun  
    OP
       2020-12-23 18:44:08 +08:00 via Android
    json.getBookList()
    .stream()
    .peek(book -> m.getArrt())
    .map(Arrt::getTypeId)
    .ifPresent(book::setBookTypeId))
    .collect()

    感谢大家,已解决。网上找到了类似写法。 明天试试看。
    ( setBookTypeId 需要返回 Book 的 this )

    回 5 楼 c# linq 确实给编程语言贡献了很多。

    @liuxey @yuhuan66666 @luban @canbingzt @beichenhpy @taogen @xgfan
    wysnylc
        14
    wysnylc  
       2020-12-23 18:49:41 +08:00
    @liuxey #11 需要 optional 救你
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3091 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 14:33 · PVG 22:33 · LAX 07:33 · JFK 10:33
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.