佬们, Java 方法有时候要返回 Map,但是可读性很差,不知道有没有替代方法? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shitshit666
V2EX    Java

佬们, Java 方法有时候要返回 Map,但是可读性很差,不知道有没有替代方法?

  •  
  •   shitshit666 2024-09-01 00:02:43 +08:00 4086 次点击
    这是一个创建于 405 天前的主题,其中的信息可能已经有所发展或是发生改变。
     /** * 根据 refId 和 funcCode 查询收藏个数 * * @param refIds 关联资的 id * @param funCode `like` 点赞 `collect`收藏 * @param module 模块 * @return refId 和数量映射 */ Map<Long, Integer> collectCountByRef(List<Long> refIds, String funCode, Integer module); /** * 查询收藏或点赞状态 * @param module 1:**** * @param userId 用户 id * @param funCode `like` 点赞 `collect`收藏 * @param ds id * @return inspireId 和状态映射 */ Map<Long, Boolean> getCollectStatus(Integer module, Long userId, String funCode, List<Long> inspireIds); 
    32 条回复    2024-09-03 21:11:47 +08:00
    wxw752
        1
    wxw752  
       2024-09-01 00:26:00 +08:00
    封装个对象,返回的时候对象接收。我们公司查库之后严禁返回 Map
    inza9hi
        2
    inza9hi  
       2024-09-01 00:49:44 +08:00
    用 Map 相当于把静态语言当做动态语言用。如果能好好管理一下 Map 的 Key ,其实也还好,胜在自由。
    SoloCompany
        3
    SoloCompany  
       2024-09-01 01:15:57 +08:00   1
    @wxw752 你有看问的是啥吗, 那请问 Map<Long, Integer> 如何封装成一个对象? 一个有 2 的 64 次方个字段的对象, 字段名分别为 r0, r1, 到 r 无穷吗
    ZiLong
        4
    ZiLong  
       2024-09-01 01:43:03 +08:00   1
    对象类型就是命名的 Map ,换一下思路,改成 List<XXX>,XXX 是你定义的返回对象类型,比如你第一个方法,XXX 的属性就是 filedName ,count
    mx1700
        5
    mx1700  
       2024-09-01 01:51:10 +08:00 via Android
    我觉得可读性没什么问题呀,如果非要改,可以把 map 封装到一个类里,比如叫 CollectCounter ,类暴露一个方法: getCount(refId)
    Znemo
        6
    Znemo  
       2024-09-01 01:57:50 +08:00   2
    非要讲究某种意义上的可读性的话,就一个类持有一个 Map 或者继承某个 Map ,做一样的事,再提供一些查询函数。在你这个场景中,感觉意义不是很大。
    dallaslu
        7
    dallaslu  
       2024-09-01 02:04:44 +08:00
    不如给 Map 变量起个好名字:

    ```java
    Map<Long, Integer> likeCountOfRefId = collectCountByRef(refIds, "like", module);
    ```
    iseki
        8
    iseki  
       2024-09-01 06:36:13 +08:00 via Android
    我觉得还行,没啥问题,你又不是返回个 Map<String, Any>,你还是觉得实在不行,把这个 Map 自己包一下给个名字,不过我觉得没必要。
    xiangyuecn
        9
    xiangyuecn  
       2024-09-01 07:42:37 +08:00
    好了,8 小时的工作量变 1 小时了
    wssy001
        10
    wssy001  
       2024-09-01 09:13:01 +08:00
    bean 字段是确认的,那就禁用 Map
    如果是动态的,那就和定规矩的吵一架,要么把动态字段需求砍掉,要么就允许用 Map
    shitshit666
        11
    shitshit666  
    OP
       2024-09-01 09:31:14 +08:00 via Android
    @dallaslu 是的目前是这个样子,包括写注释,但是别人看到这个方法的时候还是可能会蒙
    shitshit666
        12
    shitshit666  
    OP
       2024-09-01 09:31:28 +08:00 via Android
    @xiangyuecn 确实
    shitshit666
        13
    shitshit666  
    OP
       2024-09-01 09:32:36 +08:00 via Android
    @iseki 目前打算是包一层了,多人协作,可维护性也很重要。
    shitshit666
        14
    sitshit666  
    OP
       2024-09-01 09:33:11 +08:00 via Android
    找到一个方法叫枚举 key 的 map: https://blog.51cto.com/u_16213606/7112798
    sagaxu
        15
    sagaxu  
       2024-09-01 10:05:45 +08:00
    Map 可读性差,说的是 key 表示字段名,value 是值,这是用 Map 表达 POJO ,读代码的人无法感知有哪些字段,IDE 也不能补全,拼写错误也照常编译。

    而你这个例子,返回的 data 并不是 POJO ,key 本身也是开发时无法穷举列出的值,此 Map 是 value to value 的映射。这就不适合用其它方式封装。如果你的 value 是开发时可确定的状态,比如说订单状态,流程状态,那么可以定义 enum 类型代替 Long ,返回 Map<enum, V>,至于内部是用 EnumMap 还是 HashMap ,这都不是调用者该关心的。
    VeryZero
        16
    VeryZero  
       2024-09-01 10:29:31 +08:00
    用枚举。

    map 不是一定就可读性差,主要是语意是否清晰
    leonshaw
        17
    leonshaw  
       2024-09-01 13:12:36 +08:00 via Android
    你的例子应该返回 List ,跟输入对应。
    wxw752
        18
    wxw752  
       2024-09-01 16:59:42 +08:00
    @SoloCompany #3 我从未在我司的代码中看到任何 Map 返回的参数。无论是什么,肯定是有方法封装的。
    itechify
        19
    itechify  
    PRO
       2024-09-02 00:56:51 +08:00
    那你返回 list 对象,用的时候再转 map 。。。
    diagnostics
        20
    diagnostics  
       2024-09-02 01:48:12 +08:00
    @SoloCompany List<XX> 不行吗?用 Map 是因为要 O(1) 查询,只用来迭代的话,Tuple ,Object 都能描述一个 String + Long
    cuizibo
        21
    cuizibo  
       2024-09-02 10:17:37 +08:00
    批量查询改为单个查询 返回 int hhh
    ala2008
        22
    ala2008  
       2024-09-02 11:06:40 +08:00
    返回一个对象不就好了,属性有 ID 和数量
    liyanggyang
        23
    liyanggyang  
       2024-09-02 14:36:38 +08:00
    @SoloCompany #3 我也觉得,如果强制要求,就只有返回时候 对象接收。鉴于 Map<Long, Integer> 如何封装成一个对象? 一个有 2 的 64 次方个字段的对象, 字段名分别为 r0, r1, 到 r 无穷吗。 那就返回 List<DTO> , DTO:
    private String key;
    private String value;

    key set 变量名称:r0, r1, 到 r 无穷
    value set 值
    Mandelo
        24
    Mandelo  
       2024-09-02 16:27:55 +08:00
    感觉多此一举了,都是基础的包装类,又不是 Long,Obj 这种
    runliuv
        25
    runliuv  
       2024-09-02 17:49:49 +08:00
    用实体类返回,完美!
    Aresxue
        26
    Aresxue  
       2024-09-02 17:57:48 +08:00
    1.一般是对外的接口层( http 、rpc 、mq )是需要一定避免 Map 的,内部方法合理即可不需要一定避免;
    2.针对你这个 case 非要搞可以搞个 List<xxxCount>对象,意义聊胜于无,从性能来说 Map 还更好些。
    mmdsun
        27
    mmdsun  
       2024-09-02 18:04:09 +08:00
    @SoloCompany 返回 List+ 对象呢?

    List<RefIdAndCount>

    class RefIdAndCount{
    Long id;
    Long count
    }

    另外 op 文章里面的 map+枚举可以换成 java.util.EnumMap;
    shitshit666
        28
    shitshit666  
    OP
       2024-09-02 22:05:55 +08:00 via Android
    @Aresxue 谢谢,目前考虑避免掉 map 了
    shitshit666
        29
    shitshit666  
    OP
       2024-09-02 22:06:21 +08:00 via Android
    @oneisall8955 打算这样了
    shitshit666
        30
    shitshit666  
    OP
       2024-09-02 22:06:27 +08:00 via Android
    @leonshaw 有道理
    AlexBob
        31
    AlexBob  
       2024-09-03 10:43:17 +08:00
    JsonNode,我是这样做的,它能和框架完美的契合,而且序列化也不操心!
    SoloCompany
        32
    SoloCompany  
       2024-09-03 21:11:47 +08:00
    @mmdsun 没想到这么无意义的问题还有人在讨论, 我算是理解了啥是尽信书不如无书

    试问 Stream.collect(Collectors.groupingBy()) 为啥返回的是 Map<K, List<T>> 而不是 SomeFxxkingUnmeaningEntry<K, T>
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1055 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 25ms UTC 18:23 PVG 02:23 LAX 11:23 JFK 14:23
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86