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

开发业务过程中 明显感觉到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<String> codeList = newArrayList("111", null, "333"); // 券编码
        // 找出尚不存在code的券
        List<String> 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<String> codeList = newArrayList("111", "222", "333"); // 券编码
        Map<String,CouponInfo> descCouponInfoMap = ImmutableMap.of("aaa", new CouponInfo("aaa", 1), "bbb", new CouponInfo("bbb", 2), "ccc", new CouponInfo("ccc", 3)); // 券描述 -- 券信息
       
        // 得到券编码与发放张数Map
        Map<String,Integer> 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<Foo> fooList = newArrayList(new Foo("aaa"), new Foo("bbb"), new Foo("ccc"));
        List<Bar> barList = newArrayList(new Bar("111"), new Bar("222"), new Bar("333"));
        Map<String,String> 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 <T>List<T> findNullElementList(List<T> srcList, List<T> destList)

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

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

巴扎黑
巴扎黑

répondre à tous(9)
左手右手慢动作

Je ne comprends pas très bien ce que signifie votre premier paragraphe...

Ma compréhension est la suivante : existe-t-il un outil pratique qui peut répondre à vos besoins ?

Oui, la chose la plus indispensable à propos de Java, ce sont les outils. En gros, tant que vous réfléchissez aux outils dont vous avez besoin, recherchez en ligne et vous pouvez les trouver dans 99 % des cas.

Il est recommandé d'utiliser java8+google guava, qui peut être utilisé dans n'importe quelle combinaison. Il est préférable d'utiliser les deux en même temps.

Concernant les situations que vous avez évoquées dans ces trois exemples, les réponses sont les suivantes :

Q : Recherchez l'élément vide à la même position dans l'autre ensemble à partir de deux ensembles d'éléments
A : Tout d'abord, il est recommandé d'écrire une méthode zip pour fusionner descArray et codeList dans un tableau d'objets, puis opérer sur le tableau d'objets.

public static <U, V> List<Pair<U, V>> zip(List<? extends U> list1, List<? extends V> list2) throws IllegalArgumentException {
    if (list1 == null || list2 == null || list1.size() != list2.size()) {
        throw new IllegalArgumentException("Two list must have the same size");
    }
    List<Pair<U, V>> 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<U, V> pair = Pair.<U, V>of(list1.get(i), list2.get(i));
        results.add(pair);
    }
    return results;
}

Puis :

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

Q : Un ensemble est associé à une carte via un autre ensemble et génère une nouvelle carte

A : De la même manière, compressez d'abord les deux tableaux dans des tableaux d'objets, puis :

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

Q : Chacune des deux listes d'objets extrait un attribut pour former une carte

A : De la même manière, compressez d'abord les deux tableaux dans des tableaux d'objets, puis :

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

Vous avez mentionné l'obtention dynamique des valeurs d'attribut. Avant Java8, vous pouviez obtenir dynamiquement les valeurs d'attribut par réflexion. Dans Java8, vous pouviez les obtenir via des références de méthode. Ici, je prends Java8 comme exemple :

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

couponInfo::getCount est un supplier Sur la base de ce principe, de nombreuses fonctions qui ne pouvaient être réalisées que par réflexion dans le passé peuvent être réalisées en Java8 en référençant via la méthode .

Comme mentionné ci-dessus, même si vous n'utilisez pas Java8, vous pouvez utiliser de la goyave pour implémenter ces fonctions avec élégance.

Référence :

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

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

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

大家讲道理

En fait, Java 8 ne nécessite pas de zip,

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

Trouver l'ensemble correspondant qui est vide

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

Carte associée

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

Générer une carte

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

C'est évidemment votre problème.
Savez-vous ce que sont les classes et les objets ?
Utiliser la carte de liste pour tout n'est bien sûr pas possible.
Vous définissez une classe de coupon avec les attributs code et desc
List<Ticket> ticketList;
for(Ticket ticket:ticketList){
if(ticket.getCode()==null){

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

}
>

Je ne parlerai pas du deuxième et du troisième.

小葫芦

Les défauts de la conception de haut niveau ne peuvent pas être compensés par le niveau inférieur.

阿神

L'affiche doit renforcer la conception abstraite et la conception de la structure des données.
La première scène est une conception très instable basée sur la position. Doit avoir un type spécifique

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

Il sera plus facile de trouver ceux avec du code vide dans la liste, mais mieux encore, utilisez une liste unused pour enregistrer tous les coupons non utilisés.

Le deuxième scénario est utilisé comme statistiques de classification. Il existe une méthode de regroupement prête à l'emploi dans la goyave. Une fois les groupes construits, le nombre de chaque groupe sera connu.

Dans le troisième scénario, il n'est pas nécessaire de prendre un attribut chacun. En fait, vous pouvez construire une référence d'objet à Foo et Bar, et utiliser la délégation aux deux objets
respectivement.

Comme le répondant l'a mentionné ci-dessus, il y a ici un manque de conception de haut niveau. Lorsqu'il y a trois attributs a, b et c, si vous concevez respectivement trois listes, alors il y aura un processus de recherche de
a->b, b->c, et une opération plus compliquée est a- &gt ;(b, c). S'ils se trouvent dans un objet, alors a->o(a,b,c) peut
effectuer la plupart du travail d'indexation des données.

Peter_Zhu

Python est un langage interprété et peut obtenir dynamiquement des attributs au moment de l'exécution

Je ne connais pas très bien Java, mais il devrait y avoir plusieurs mécanismes de réflexion similaires.

左手右手慢动作

Java est un langage ancien. S'il n'est pas assez expressif comme vous l'avez dit, pourquoi est-il devenu le langage le plus populaire au monde ? C'est juste que vous ne l'avez pas bien appris

Ty80

N'utilisez pas de tableaux ou de listes pour séparer les tickets et les codes. Il doit y avoir une relation un à un entre les tickets et les codes. Lors de la création d'un modèle, vous pouvez créer une classe de ticket avec un attribut de code n'est-ce pas très clair ?

.
洪涛

Java est un langage verbeux, et le code écrit en java est fondamentalement assez verbeux (avant 8)
Java seul n'est pas aussi élégant que Python et d'autres langages pour gérer les opérations de base, mais cela peut être fait. à travers des classes d'outils et autres Groovy, etc. Faites amende honorable.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!