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

开发业务过程中 明显感觉到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 等

巴扎黑
巴扎黑

membalas semua(9)
左手右手慢动作

Saya tidak begitu faham maksud perenggan pertama anda...

Pemahaman saya ialah: Adakah terdapat alat mudah yang boleh mencapai keperluan anda?

Ya, perkara yang paling penting tentang Java ialah alatan Pada asasnya, selagi anda memikirkan alat yang anda perlukan, cari dalam talian dan anda boleh menemuinya dalam 99% kes.

Adalah disyorkan untuk menggunakan java8+google guava, yang boleh digunakan dalam mana-mana kombinasi Adalah lebih baik untuk menggunakan kedua-duanya pada masa yang sama.

Mengenai situasi yang anda nyatakan dalam tiga contoh ini, jawapannya adalah seperti berikut:

S: Cari elemen kosong dalam kedudukan yang sama dalam set lain daripada dua set elemen
J: Pertama sekali, adalah disyorkan untuk menulis kaedah zip untuk menggabungkan descArray dan codeList ke dalam satu tatasusunan objek, dan kemudian beroperasi pada tatasusunan objek.

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;
}

Kemudian:

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

S: Satu set dikaitkan dengan Peta melalui set lain dan menjana Peta baharu

J: Dengan cara yang sama, zip dahulu dua tatasusunan ke dalam tatasusunan objek, kemudian:

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

S: Setiap satu daripada dua senarai objek mengekstrak atribut untuk membentuk Peta

J: Dengan cara yang sama, zip dahulu dua tatasusunan ke dalam tatasusunan objek, kemudian:

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

Anda menyebut secara dinamik mendapatkan nilai atribut Sebelum java8, anda boleh mendapatkan nilai atribut secara dinamik melalui refleksi Dalam java8, anda boleh mendapatkannya melalui rujukan kaedah. Di sini saya mengambil java8 sebagai contoh

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

ialah couponInfo::getCount Berdasarkan prinsip ini, banyak fungsi yang hanya boleh dicapai melalui refleksi pada masa lalu boleh dicapai dalam Java8 dengan merujuk supplier melalui kaedah .

Seperti yang dinyatakan di atas, walaupun anda tidak menggunakan Java8, anda boleh menggunakan jambu batu untuk melaksanakan fungsi ini dengan elegan.

Rujukan:

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

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

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

大家讲道理

Malah, Java 8 tidak memerlukan zip,

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

Cari set sepadan yang kosong

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

Peta Berkaitan

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

Jana Peta

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

Jelas sekali ini masalah anda.
Adakah anda tahu apa itu kelas dan objek?
Menggunakan peta senarai untuk semuanya sudah tentu tidak boleh dilakukan.
Anda mentakrifkan kelas kupon dengan atribut kod dan desc
Senarai<Tiket>Senarai tiket;
untuk(Tiket tiket:ticketList){
if(ticket.getCode()==null){

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

}
}

Saya tidak akan bercakap tentang yang kedua dan ketiga.

小葫芦

Kekurangan reka bentuk peringkat tinggi tidak boleh diperbaiki oleh peringkat bawah.

阿神

Poster perlu mengukuhkan reka bentuk abstrak dan reka bentuk struktur data.
Adegan pertama adalah reka bentuk yang sangat tidak stabil berdasarkan kedudukan. Harus mempunyai jenis khusus

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

Adalah lebih mudah untuk mencari yang mempunyai kod kosong dalam Senarai, tetapi lebih baik lagi, gunakan Senarai yang tidak digunakan untuk menyimpan semua notUsedCoupon.

Senario kedua digunakan sebagai statistik klasifikasi Terdapat kaedah pengelompokan siap dalam jambu batu Selepas kumpulan dibina, bilangan setiap kumpulan akan diketahui.

Dalam senario ketiga, tidak perlu mengambil atribut setiap satu. Malah, anda boleh membina rujukan objek kepada Foo dan Bar, dan menggunakan perwakilan kepada dua objek
masing-masing.

Seperti yang dinyatakan oleh responden di atas, terdapat kekurangan reka bentuk peringkat tinggi di sini. Apabila terdapat tiga atribut a, b dan c, jika anda mereka bentuk tiga Senarai masing-masing, maka akan terdapat proses carian
a->b, b->c, dan operasi yang lebih rumit ialah a- &gt ;(b, c). Jika ia berada dalam objek, maka a->o(a,b,c) boleh
menyelesaikan kebanyakan kerja pengindeksan data.

Peter_Zhu

Python ialah bahasa yang ditafsirkan dan boleh memperoleh atribut secara dinamik semasa masa jalan

Saya tidak begitu mengenali Java, tetapi mesti ada beberapa mekanisme pantulan yang serupa.

左手右手慢动作

Jawa ialah bahasa purba Jika ia tidak cukup ekspresif seperti yang anda katakan, mengapa ia menjadi bahasa yang paling popular di dunia. Cuma anda tidak mempelajarinya dengan baik

Ty80

Jangan gunakan tatasusunan atau senarai untuk mengasingkan tiket dan kod. Apabila membina model, anda boleh membuat kelas tiket dengan atribut kod di dalamnya. Bukankah ini sangat jelas?

洪涛

Java ialah bahasa verbose, dan kod yang ditulis dalam java pada asasnya agak bertele-tele (sebelum 8
Java sahaja tidak seanggun pyhton dan bahasa lain untuk mengendalikan operasi asas, tetapi ia boleh dilakukan). melalui kelas alatan dan Groovy yang lain, dsb. Berbaik sangka.

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan
Tentang kita Penafian Sitemap
Laman web PHP Cina:Latihan PHP dalam talian kebajikan awam,Bantu pelajar PHP berkembang dengan cepat!