V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
shitshit666
V2EX  ›  Java

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

  •  
  •   shitshit666 · 118 天前 · 3434 次点击
    这是一个创建于 118 天前的主题,其中的信息可能已经有所发展或是发生改变。
        /**
         * 根据 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  
       118 天前
    封装个对象,返回的时候对象接收。我们公司查库之后严禁返回 Map
    inza9hi
        2
    inza9hi  
       118 天前
    用 Map 相当于把静态语言当做动态语言用。如果能好好管理一下 Map 的 Key ,其实也还好,胜在自由。
    SoloCompany
        3
    SoloCompany  
       118 天前   ❤️ 1
    @wxw752 你有看问的是啥吗, 那请问 Map<Long, Integer> 如何封装成一个对象? 一个有 2 的 64 次方个字段的对象, 字段名分别为 r0, r1, 到 r 无穷吗
    ZiLong
        4
    ZiLong  
       118 天前   ❤️ 1
    对象类型就是命名的 Map ,换一下思路,改成 List<XXX>,XXX 是你定义的返回对象类型,比如你第一个方法,XXX 的属性就是 filedName ,count
    mx1700
        5
    mx1700  
       118 天前 via Android
    我觉得可读性没什么问题呀,如果非要改,可以把 map 封装到一个类里,比如叫 CollectCounter ,类暴露一个方法: getCount(refId)
    Znemo
        6
    Znemo  
       118 天前   ❤️ 2
    非要讲究某种意义上的可读性的话,就一个类持有一个 Map 或者继承某个 Map ,做一样的事,再提供一些查询函数。在你这个场景中,感觉意义不是很大。
    dallaslu
        7
    dallaslu  
       118 天前
    不如给 Map 变量起个好名字:

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

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

    map 不是一定就可读性差,主要是语意是否清晰
    leonshaw
        17
    leonshaw  
       118 天前 via Android
    你的例子应该返回 List ,跟输入对应。
    wxw752
        18
    wxw752  
       118 天前
    @SoloCompany #3 我从未在我司的代码中看到任何 Map 返回的参数。无论是什么,肯定是有方法封装的。
    oneisall8955
        19
    oneisall8955  
       117 天前
    那你返回 list 对象,用的时候再转 map 。。。
    diagnostics
        20
    diagnostics  
       117 天前
    @SoloCompany List<XX> 不行吗?用 Map 是因为要 O(1) 查询,只用来迭代的话,Tuple ,Object 都能描述一个 String + Long
    cuizibo
        21
    cuizibo  
       117 天前
    批量查询改为单个查询 返回 int hhh
    ala2008
        22
    ala2008  
       117 天前
    返回一个对象不就好了,属性有 ID 和数量
    liyanggyang
        23
    liyanggyang  
       117 天前
    @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  
       117 天前
    感觉多此一举了,都是基础的包装类,又不是 Long,Obj 这种
    runliuv
        25
    runliuv  
       117 天前
    用实体类返回,完美!
    Aresxue
        26
    Aresxue  
       117 天前
    1.一般是对外的接口层( http 、rpc 、mq )是需要一定避免 Map 的,内部方法合理即可不需要一定避免;
    2.针对你这个 case 非要搞可以搞个 List<xxxCount>对象,意义聊胜于无,从性能来说 Map 还更好些。
    mmdsun
        27
    mmdsun  
       117 天前
    @SoloCompany 返回 List+ 对象呢?

    List<RefIdAndCount>

    class RefIdAndCount{
    Long id;
    Long count
    }

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

    试问 Stream.collect(Collectors.groupingBy()) 为啥返回的是 Map<K, List<T>> 而不是 SomeFxxkingUnmeaningEntry<K, T>
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2635 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 12:09 · PVG 20:09 · LAX 04:09 · JFK 07:09
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.