关于java语言表达力不足的几个例子及可有好的封装方法
巴扎黑
巴扎黑 2017-04-18 09:56:58
0
9
459

开发业务过程中 明显感觉到java语言表达力的不足 就好像没有桌子的概念 所以每次提到桌子都得通过这么一长串的文字--有光滑平板、由腿或其它支撑物固定起来的家具,用以吃饭、写字、工作或玩牌--来表达桌子的概念 反正开发过程中我是有点晕

下面是几个比较典型的例子

业务背景

  • 购买某些商品 会给用户发一些优惠券 如2张满100减50优惠券 1张满200减50优惠券等

  • 我提供一个了接口 接收上述券信息

  • 先查询redis判断该券是不是已经存在 如hmget key 100_50 200_50

  • 如果券不存在 先去创建 然后将其放到redis中 如hmset key 100_50 84678bfd7c1011e6a22b4437e6d0648e

  • 最后得到券编码和张数的映射关系 批量发券batchSendCouponsToUser(userId,couponCodeCountMap);

两个元素集合 找出对应的另一个集合中同一位置为空的元素

String[] descArray = {"aaa", "bbb", "ccc"}; // 券描述 如 满100减50 List codeList = newArrayList("111", null, "333"); // 券编码 // 找出尚不存在code的券 List nullElementList = newArrayList(); for (int i = 0; i < codeList.size(); i++) { if (codeList.get(i) == null) { nullElementList.add(descArray[i]); } } assertThat(nullElementList).containsExactly("bbb");

一个集合与一个Map通过另一个集合来关联 并生成一个新的Map

String[] descArray = {"aaa", "bbb", "ccc"}; // 券描述 List codeList = newArrayList("111", "222", "333"); // 券编码 Map descCouponInfoMap = ImmutableMap.of("aaa", new CouponInfo("aaa", 1), "bbb", new CouponInfo("bbb", 2), "ccc", new CouponInfo("ccc", 3)); // 券描述 -- 券信息 // 得到券编码与发放张数Map Map codeCountMap = new HashMap<>(); for (int i = 0; i < codeList.size(); i++) { codeCountMap.put(codeList.get(i), descCouponInfoMap.get(descArray[i]).getCount()); } assertThat(codeCountMap).containsExactly(new DefaultMapEntry("111",1),new DefaultMapEntry("222",2),new DefaultMapEntry("333",3));

两个对象list各抽取一个属性 组成一个Map

List fooList = newArrayList(new Foo("aaa"), new Foo("bbb"), new Foo("ccc")); List barList = newArrayList(new Bar("111"), new Bar("222"), new Bar("333")); Map descCodeMap = new HashMap<>(); // 券描述 -- 券编码 // 将两个List各抽取一个属性成Map for (int i = 0; i < fooList.size(); i++) { descCodeMap.put(fooList.get(i).getDesc(), barList.get(i).getCode()); } assertThat(descCodeMap).contains(new DefaultMapEntry("aaa","111"),new DefaultMapEntry("bbb","222"),new DefaultMapEntry("ccc","333"));

像第一个还好, 可以提供一个通用的工具类如

static List findNullElementList(List srcList, List destList)

后面两个因为涉及到动态的获取属性值 还不好封装 难道使用java就只能这么麻烦吗?

不知道其他语言针对上述场景是不是一样的麻烦?
如 python javascript ruby 等

巴扎黑
巴扎黑

全部回覆 (9)
左手右手慢动作

不是很懂你第一段話要表達什麼意思…

我理解為:有沒有方便的工具可以實現你的需求?

有的,java最不缺的就是工具類,基本上只要想到需要什麼工具,上網搜一下,99%的情況下都能搜出來。

建議使用java8+google guava,可以任意搭配使用,兩者同時使用更佳。

就你這3個例子所說的情況,逐一解答如下:

Q:兩個元素集合 找出對應的另一個集合中同一位置為空的元素
A: 首先,建議寫個zip方法把descArraycodeList合併成一個物件數組,然後再對該物件數組進行操作。

public static  List> zip(List list1, List list2) throws IllegalArgumentException { if (list1 == null || list2 == null || list1.size() != list2.size()) { throw new IllegalArgumentException("Two list must have the same size"); } List> results = Lists.newArrayListWithCapacity(list1.size()); for (int i = 0; i < list1.size(); ++i) { // Explicit type parameter just because eclipse is not cool // noinspection RedundantTypeArguments Pair pair = Pair.of(list1.get(i), list2.get(i)); results.add(pair); } return results; }

然後:

List> empytCodeList = zip(codeList, descList).stream() .filter(v -> Objects.isNull(v.getFirst()))// 找出codeList中为空的对象 .collect(Collectors.toList());

Q:一個集合與一個Map透過另一個集合來關聯 並產生一個新的Map

A: 同理,先把兩個數組zip成物件數組,然後:

Map codeCountMap = zip(codeList, descList).stream() .collect(Collectors.toMap(Pair::getFirst, v -> descCouponInfoMap.get(v.getSecond()).getCount()));//这里有个隐患就是map.get(desc)有可能未null,从而引发空指针

Q:兩個物件list各抽取一個屬性 組成一個Map

A: 同理,先把兩個數組zip成物件數組,然後:

Map descCodeMap = zip(fooList, barList).stream() .collect(Collectors.toMap(v -> v.getFirst().getDesc(), v -> v.getSecond().getCode()));

其中你所提到的動態取得屬性值,在java8之前,你可以透過反射來動態取得屬性值,在java8,你可以透過方法引用來獲取,這裡我以java8為例:

public static void getFieldVal(Supplier supplier) { return supplier.get(); }

couponInfo::getCount就是一个supplier,基於這個原理,以前很多只能透過反射才能實現的功能,在java8中可以透過方法引用去實現。

以上,就算不用java8,也可以藉助guava去優雅的實作這些功能。

參考資料:

  1. http://ifeve.com/google-guava/

  2. http://www.importnew.com/1036...

  3. http://www.importnew.com/1190...

    大家讲道理

    其實 Java 8 不需要 zip,

    import java.util.*; import java.util.stream.*;

    找出對應集合為空的

    List result = IntStream.range(0, descArray.length) .filter(i -> codeList.get(i) == null) .mapToObj(i -> descArray[i]) .collect(Collectors.toList());

    關聯 Map

    Map codeCountMap = IntStream.range(0, descArray.length) .boxed() .collect(Collectors.toMap( i -> codeList.get(i), i -> descCouponInfoMap.get(descArray[i]).getCount()));

    產生 Map

    Map descCodeMap = IntStream.range(0, descArray.length) .boxed() .collect(Collectors.toMap( i -> descArray[i], i -> codeList.get(i)));
      大家讲道理

      很明顯這是你的問題。
      你知道什麼是類別和物件嗎?
      一切都用list map,當然不行。
      你定義一個優惠券類,有code和desc屬性
      List ticketList;
      for(Ticket ticket:ticketList){
      if(ticket.getCode()==null){

      System.out.println(ticket.getDesc());

      }
      }

      第二和第三個也不說了。

        小葫芦

        高層設計的不足,不能用底層來彌補。

          阿神

          樓主需要加強抽象設計和資料結構設計。
          第1個場景,依位置對應就是一個非常不穩定的設計。應有具體類型

          class Coupon { int id; //对应位置,保证不重复,也不会错位。 String desc; String code; public boolean notUsed() { return code == null; } }

          這樣在List中找code為空的會比較好找,但更好的是,用一個unusedList保存所有notUsedCoupon.

          第2個場景做為分類統計,guava中有現成的分組方法,建構好分組後,每組的數量也就知道了。

          第3個場景其實各自取一個屬性並無必要,實際上完全可以建構一個物件引用到Foo和Bar,分別使用委託給
          這兩個物件。

          就像上面有答主提到,這裡缺少高層設計。當有a,b,c三個屬性,如果分別設計三個List中,那麼就會有
          a->b,b->c的查找過程,複雜一點的操作還有a->(b, c )。如果它們在一個物件中,那麼,只要a->o(a,b,c)就可
          以完成大部分資料索引工作。

            Peter_Zhu

            python 是解釋語言,可以運行時動態取得屬性

            不是很懂 java,不過應該有數似的反射機制。

              左手右手慢动作

              java作為一門古老的語言,如果真如你所說表達力不足,何以成為全世界最流行的語言,只是你學得不好而已

                Ty80

                不要用陣列或list去分開票和編碼,票和編碼應該是一對一的關係吧。在建立模型的時候可以建立一個票的類別啊,裡面有code屬性,這樣不就很明確了麼

                  洪涛

                  java一門囉嗦型語言, 用java寫的程式碼基本上都挺囉嗦的(8之前).
                  java單獨處理基本操作確實不如pyhton等語言優雅, 不過可以透過工具類以及其它Groovy等進行彌補.

                    最新下載
                    更多>
                    網站特效
                    網站源碼
                    網站素材
                    前端模板
                    關於我們 免責聲明 Sitemap
                    PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!