真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網站制作重慶分公司

JDK中Stream代碼簡潔的新特性介紹

本篇內容主要講解“JDK中Stream代碼簡潔的新特性介紹”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“JDK中Stream代碼簡潔的新特性介紹”吧!

目前創(chuàng)新互聯(lián)公司已為近千家的企業(yè)提供了網站建設、域名、網站空間、網站托管維護、企業(yè)網站設計、潤州網站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

一、概述

Stream 是一組用來處理數組、集合的API,Stream API 提供了一種高效且易于使用的處理數據的方式。Java 8 中之所以費這么大的功夫引入  函數式編程 ,原因有兩個:

代碼簡潔函數式編程寫出的代碼簡潔且意圖明確,使用stream接口讓你從此告別for循環(huán)。

多核友好,Java函數式編程使得編寫并行程序從未如此簡單,你需要的全部就是用用一下parallel()方法

Stream 是 Java8 中處理集合的關鍵抽象概念,它可以指定你希望對集合進行的操作,可以執(zhí)行非常復雜的查找、過濾和映射數據等操作

二、Stream特性

1、不是數據結構,沒有內部存儲,不會保存數據,故每個Stream流只能使用一次 2、不支持索引訪問 3、支持并行  4、很容易生成數據或集合(List,Set) 5、支持過濾、查找、轉換、匯總、聚合等操作  6、延遲計算,流在中間處理過程中,只是對操作進行了記錄,并不會立即執(zhí)行,需要等到執(zhí)行終止操作的時候才會進行實際的計算

三、分類

關于應用在Stream流上的操作,可以分成兩種:

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術社區(qū)

  2. Intermediate(中間操作): 中間操作的返回結果都是Stream,故可以多個中間操作疊加;

  3. Terminal(終止操作): 終止操作用于返回我們最終需要的數據,只能有一個終止操作。

使用Stream流,可以清楚地知道我們要對一個數據集做何種操作,可讀性強。而且可以很輕松地獲取并行化Stream流,不用自己編寫多線程代碼,可以讓我們更加專注于業(yè)務邏輯。

JDK中Stream代碼簡潔的新特性介紹

無狀態(tài): 指元素的處理不受之前元素的影響;有狀態(tài): 指該操作只有拿到所有元素之后才能繼續(xù)下去。非短路操作:  指必須處理所有元素才能得到最終結果;短路操作: 指遇到某些符合條件的元素就可以得到最終結果,如 A || B,只要A為true,則無需判斷B的結果。

四、Stream的創(chuàng)建

1、通過數組來生成 2、通過集合來生成 3、通過Stream.generate方法來創(chuàng)建 4、通過Stream.iterate方法來創(chuàng)建  5、其他Api創(chuàng)建

4.1 通過數組來生成

//通過數組來生成    static void gen1(){        String[] strs = {"a","b","c","d"};        Stream strs1 = Stream.of(strs);//使用Stream中的靜態(tài)方法:of()        strs1.forEach(System.out::println);//打印輸出(a、b、c、d)    }

4.2 通過集合來生成

//通過集合來生成     static void gen2(){         List list = Arrays.asList("1","2","3","4");         Stream stream = list.stream();//獲取一個順序流         stream.forEach(System.out::println);//打印輸出(1,2,3,4)     }

4.3 通過Stream.generate方法來創(chuàng)建

//generate static void gen3(){     Stream generate = Stream.generate(() -> 1);//使用Stream中的靜態(tài)方法:generate()     //limit 返回由該流的元素組成的流,截斷長度不能超過maxSize     generate.limit(10).forEach(System.out::println);//打印輸出(打印10個1) }

4.4 通過Stream.iterate方法來創(chuàng)建

//使用iterator static void gen4() {     Stream iterate = Stream.iterate(1, x -> x + 1);//使用Stream中的靜態(tài)方法:iterate()     iterate.limit(10).forEach(System.out::println);//打印輸出(1,2,3,4,5,6,7,8,9,10) }

4.5其他Api創(chuàng)建

//其他方式     static void gen5(){         String str = "abcdefg";         IntStream stream =str.chars();//獲取str 字節(jié)碼         stream.forEach(System.out::println);//打印輸出(97,98,99,100,101,102,103)     }

五、Stream的常用API

5.1 中間操作

1. filter:過濾流中的某些元素

//中間操作:如果調用方法之后返回的結果是Stream對象就意味著是一個中間操作  Arrays.asList(1,2,3,4,5).stream()//獲取順序流  .filter((x)->x%2==0) // 2 4   .forEach(System.out::println);  //求出結果集中所有偶數的和 int count = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9).stream()//獲取順序流 .filter(x -> x % 2 == 0).// 2 4 6 8  mapToInt(x->x).sum();//求和 System.out.println(count); //打印輸出 20

2. distinct:通過流中元素的 hashCode() 和 equals() 去除重復元素

Arrays.asList(1,2,3,3,3,4,5,2).stream()//獲取順序流  .distinct()//去重  .forEach(System.out::println);// 打印輸出(1,2,3,4,5)  System.out.println("去重:---------------");  Arrays.asList(1,2,3,3,3,4,5,2).stream()//獲取順序流  .collect(Collectors.toSet())//Set()去重  .forEach(System.out::println);// 打印輸出(1,2,3,4,5)

3. 排序

sorted():返回由此流的元素組成的流,根據自然順序排序。sorted(Comparator com):返回由該流的元素組成的流,根據提供的  Comparator進行排序。

//獲取最大值和最小值但是不使用min和max方法    List list = Arrays.asList(1,2, 3,4, 5, 6);    Optional min = list.stream().sorted().findFirst();//自然排序 根據數字從小到大排列    System.out.println(min.get());//打印輸出(1)        Optional max2 = list.stream().sorted((a, b) -> b - a).findFirst();//定時排序 根據最大數進行排序    System.out.println(max2.get());//打印輸出(6)   //按照大小(a-z)排序  Arrays.asList("java","c#","python","scala").stream().sorted().forEach(System.out::println);  //按照長度排序  Arrays.asList("java","c#","python","scala").stream().sorted((a,b)->a.length()-b.length()).forEach(System.out::println);

4. 截取

limit(n):返回由此流的元素組成的流,截短長度不能超過 nskip(n):在丟棄流的第n元素后,配合limit(n)可實現分頁

//打印20-30這樣的集合數據       Stream.iterate(1,x->x+1).limit(50)// limit 50 總共到50       .skip(20)// 跳過前 20       .limit(10) // 打印10個       .forEach(System.out::println);//打印輸出(21,22,23,24,25,26,27,28,29,30)

5. 轉換

map:接收一個函數作為參數,該函數會被應用到每個元素上,并將其映射成一個新的元素。flatMap:接收一個函數作為參數,將流中的每個值都換成另一個流,然后把所有流連接成一個流。

List list = Arrays.asList("a,b,c", "1,2,3");   //將每個元素轉成一個新的且不帶逗號的元素 Stream s1 = list.stream().map(s -> s.replaceAll(",", "")); s1.forEach(System.out::println); // abc  123   Stream s3 = list.stream().flatMap(s -> {     //將每個元素轉換成一個stream     String[] split = s.split(",");     Stream s2 = Arrays.stream(split);     return s2; }); s3.forEach(System.out::println); // a b c 1 2 3

6. 消費

peek:如同于map,能得到流中的每一個元素。但map接收的是一個Function表達式,有返回值;而peek接收的是Consumer表達式,沒有返回值。

//將str中的每一個數值都打印出來,同時算出最終的求和結果 String str ="11,22,33,44,55";       System.out.println(Stream.of(str.split(",")).peek(System.out::println).mapToInt(Integer::valueOf).sum());//11 22 33 44 55 165

5.2 終止操作

1. 循環(huán):forEach

Users類:

import java.util.Date;  /**  * @program: lambda  * @ClassName Users  * @description:  * @author: muxiaonong  * @create: 2020-10-24 11:00  * @Version 1.0  **/ public class Users {      private String name;     public Users() {}      /**      * @param name      */     public Users(String name) {         this.name = name;     }      /**      * @param name      * @return      */     public static Users build(String name){         Users u = new Users();         u.setName(name);         return u;     }      public String getName() {         return name;     }      public void setName(String name) {         this.name = name;     }      @Override     public String toString() {         return  "name='" + name + '\'';     }   }
//創(chuàng)建一組自定義對象 String str2 = "java,scala,python"; Stream.of(str2.split(",")).map(x->new Users(x)).forEach(System.out::println);//打印輸出(name='java' name='scala' name='python') Stream.of(str2.split(",")).map(Users::new).forEach(System.out::println);//打印輸出(name='java' name='scala' name='python') Stream.of(str2.split(",")).map(x->Users.build(x)).forEach(System.out::println);//打印輸出(name='java' name='scala' name='python') Stream.of(str2.split(",")).map(Users::build).forEach(System.out::println);//打印輸出(name='java' name='scala' name='python')

2. 計算:min、max、count、sum

min:返回流中元素最小值max:返回流中元素最大值count:返回流中元素的總個數sum:求和

//求集合中的最大值 List list = Arrays.asList(1,2, 3,4, 5, 6);  Optional max = list.stream().max((a, b) -> a - b);  System.out.println(max.get()); // 6   //求集合的最小值  System.out.println(list.stream().min((a, b) -> a-b).get()); // 1 //求集合的總個數 System.out.println(list.stream().count());//6  //求和  String str ="11,22,33,44,55";  System.out.println(Stream.of(str.split(",")).mapToInt(x -> Integer.valueOf(x)).sum());  System.out.println(Stream.of(str.split(",")).mapToInt(Integer::valueOf).sum());  System.out.println(Stream.of(str.split(",")).map(x -> Integer.valueOf(x)).mapToInt(x -> x).sum());  System.out.println(Stream.of(str.split(",")).map(Integer::valueOf).mapToInt(x -> x).sum());

3. 匹配:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny

anyMatch:接收一個 Predicate 函數,只要流中有一個元素滿足該斷言則返回true,否則返回falseallMatch:接收一個  Predicate 函數,當流中每個元素都符合該斷言時才返回true,否則返回falsenoneMatch:接收一個 Predicate  函數,當流中每個元素都不符合該斷言時才返回true,否則返回falsefindFirst:返回流中第一個元素findAny:返回流中的任意元素

List list = Arrays.asList(1,2, 3,4, 5, 6); System.out.println(list.stream().allMatch(x -> x>=0)); //如果集合中的元素大于等于0 返回true System.out.println(list.stream().noneMatch(x -> x > 5));//如果集合中的元素有大于5的元素。返回false System.out.println(list.stream().anyMatch(x -> x > 4));//如果集合中有大于四4的元素,返回true //取第一個偶數 Optional first = list.stream().filter(x -> x % 10 == 6).findFirst(); System.out.println(first.get());// 6 //任意取一個偶數 Optional any = list.stream().filter(x -> x % 2 == 0).findAny(); System.out.println(any.get());// 2

4.收集器:toArray、collect

collect:接收一個Collector實例,將流中元素收集成另外一個數據結構Collector

  1. 鴻蒙官方戰(zhàn)略合作共建——HarmonyOS技術社區(qū)

  2. Supplier supplier();創(chuàng)建一個結果容器A

  3. BiConsumer

  4. BinaryOperator  combiner();函數接口,該參數的作用跟上一個方法(reduce)中的combiner參數一樣,將并行流中各個子進程的運行結果(accumulator函數操作后的容器A)進行合并。

  5. Function

  6. Set

    characteristics();返回一個不可變的Set集合,用來表明該Collector的特征
/**  * @program: lambda  * @ClassName Customer  * @description:  * @author: muxiaonong  * @create: 2020-10-24 11:36  * @Version 1.0  **/ public class Customer {      private String name;      private Integer age;      ...getset忽略 }  public static void main(String[] args) {         Customer c1 = new Customer("張三",10);         Customer c2 = new Customer("李四",20);         Customer c3 = new Customer("王五",10);          List list = Arrays.asList(c1,c2,c3);          //轉成list         List ageList = list.stream().map(Customer::getAge).collect(Collectors.toList());         System.out.println("ageList:"+ageList);//ageList:[10, 20, 10]          //轉成set         Set ageSet = list.stream().map(Customer::getAge).collect(Collectors.toSet());         System.out.println("ageSet:"+ageSet);//ageSet:[20, 10]  //轉成map,注:key不能相同,否則報錯         Map CustomerMap = list.stream().collect(Collectors.toMap(Customer::getName, Customer::getAge));         System.out.println("CustomerMap:"+CustomerMap);//CustomerMap:{李四=20, 張三=10, 王五=10}  //字符串分隔符連接         String joinName = list.stream().map(Customer::getName).collect(Collectors.joining(",", "(", ")"));         System.out.println("joinName:"+joinName);//joinName:(張三,李四,王五)  //聚合操作 //1.學生總數         Long count = list.stream().collect(Collectors.counting());         System.out.println("count:"+count);//count:3 //2.最大年齡 (最小的minBy同理)         Integer maxAge = list.stream().map(Customer::getAge).collect(Collectors.maxBy(Integer::compare)).get();         System.out.println("maxAge:"+maxAge);//maxAge:20  //3.所有人的年齡         Integer sumAge = list.stream().collect(Collectors.summingInt(Customer::getAge));         System.out.println("sumAge:"+sumAge);//sumAge:40  //4.平均年齡         Double averageAge = list.stream().collect(Collectors.averagingDouble(Customer::getAge));         System.out.println("averageAge:"+averageAge);//averageAge:13.333333333333334  //分組         Map> ageMap = list.stream().collect(Collectors.groupingBy(Customer::getAge));         System.out.println("ageMap:"+ageMap);//ageMap:{20=[com.mashibing.stream.Customer@20ad9418], 10=[com.mashibing.stream.Customer@31cefde0, com.mashibing.stream.Customer@439f5b3d]}   //分區(qū) //分成兩部分,一部分大于10歲,一部分小于等于10歲         Map> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));         System.out.println("partMap:"+partMap);  //規(guī)約         Integer allAge = list.stream().map(Customer::getAge).collect(Collectors.reducing(Integer::sum)).get();         System.out.println("allAge:"+allAge);//allAge:40       }
 public static void main(String[] args) {         Customer c1 = new Customer("張三",10);         Customer c2 = new Customer("李四",20);         Customer c3 = new Customer("王五",10);          List list = Arrays.asList(c1,c2,c3);          //轉成list         List ageList = list.stream().map(Customer::getAge).collect(Collectors.toList());         System.out.println("ageList:"+ageList);//ageList:[10, 20, 10]          //轉成set         Set ageSet = list.stream().map(Customer::getAge).collect(Collectors.toSet());         System.out.println("ageSet:"+ageSet);//ageSet:[20, 10]  //轉成map,注:key不能相同,否則報錯         Map CustomerMap = list.stream().collect(Collectors.toMap(Customer::getName, Customer::getAge));         System.out.println("CustomerMap:"+CustomerMap);//CustomerMap:{李四=20, 張三=10, 王五=10}  //字符串分隔符連接         String joinName = list.stream().map(Customer::getName).collect(Collectors.joining(",", "(", ")"));         System.out.println("joinName:"+joinName);//joinName:(張三,李四,王五)  //聚合操作 //1.學生總數         Long count = list.stream().collect(Collectors.counting());         System.out.println("count:"+count);//count:3 //2.最大年齡 (最小的minBy同理)         Integer maxAge = list.stream().map(Customer::getAge).collect(Collectors.maxBy(Integer::compare)).get();         System.out.println("maxAge:"+maxAge);//maxAge:20  //3.所有人的年齡         Integer sumAge = list.stream().collect(Collectors.summingInt(Customer::getAge));         System.out.println("sumAge:"+sumAge);//sumAge:40  //4.平均年齡         Double averageAge = list.stream().collect(Collectors.averagingDouble(Customer::getAge));         System.out.println("averageAge:"+averageAge);//averageAge:13.333333333333334  //分組         Map> ageMap = list.stream().collect(Collectors.groupingBy(Customer::getAge));         System.out.println("ageMap:"+ageMap);//ageMap:{20=[com.mashibing.stream.Customer@20ad9418], 10=[com.mashibing.stream.Customer@31cefde0, com.mashibing.stream.Customer@439f5b3d]}   //分區(qū) //分成兩部分,一部分大于10歲,一部分小于等于10歲         Map> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10));         System.out.println("partMap:"+partMap);  //規(guī)約         Integer allAge = list.stream().map(Customer::getAge).collect(Collectors.reducing(Integer::sum)).get();         System.out.println("allAge:"+allAge);//allAge:40       }

六、Stream的方法摘要

修飾符和類型方法和說明
staticCollectoraveragingDouble(ToDoubleFunction mapper) 返回一個 Collector ,它產生應用于輸入元素的雙值函數的算術平均值。
staticCollectoraveragingInt(ToIntFunction mapper) 返回一個 Collector ,它產生應用于輸入元素的整數值函數的算術平均值。
staticCollectoraveragingLong(ToLongFunction mapper) 返回一個 Collector ,它產生應用于輸入元素的長值函數的算術平均值。
static CollectorcollectingAndThen(Collector downstream, Function finisher) 適應 Collector進行額外的整理轉換。
staticCollectorcounting() 返回 Collector類型的接受元件 T計數輸入元件的數量。
static Collector>>groupingBy(Function classifier) 返回 Collector “由基團”上的類型的輸入元件操作實現 T ,根據分類功能分組元素,并且在返回的結果 Map 。
static Collector>groupingBy(Function classifier, Collector downstream) 返回 Collector “由基團”上的類型的輸入元件操作實現級聯(lián) T ,根據分類功能分組元素,然后使用下游的指定執(zhí)行與給定鍵相關聯(lián)的值的歸約運算 Collector 。
static >CollectorgroupingBy(Function classifier, SuppliermapFactory, Collector downstream) 返回 Collector “由基團”上的類型的輸入元件操作實現級聯(lián) T ,根據分類功能分組元素,然后使用下游的指定執(zhí)行與給定鍵相關聯(lián)的值的歸約運算 Collector 。
static Collector>>groupingByConcurrent(Function classifier) 返回一個并發(fā) Collector “由基團”上的類型的輸入元件操作實現 T ,根據分類功能分組元素。
static Collector>groupingByConcurrent(Function classifier, Collector downstream) 返回一個并發(fā) Collector “由基團”上的類型的輸入元件操作實現級聯(lián) T ,根據分類功能分組元素,然后使用下游的指定執(zhí)行與給定鍵相關聯(lián)的值的歸約運算 Collector 。
static > CollectorgroupingByConcurrent(Function classifier, SuppliermapFactory, Collector downstream) 返回一個并發(fā) Collector “由基團”上的類型的輸入元件操作實現級聯(lián) T ,根據分類功能分組元素,然后使用下游的指定執(zhí)行與給定鍵相關聯(lián)的值的歸約運算 Collector 。
static Collectorjoining() 返回一個 Collector ,按照遇到的順序將輸入元素連接到一個 String中。
static Collectorjoining(CharSequence delimiter) 返回一個 Collector ,按照遇到的順序連接由指定的分隔符分隔的輸入元素。
static Collectorjoining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 返回一個 Collector ,它將按照指定的 Collector分隔的輸入元素與指定的前綴和后綴進行連接。
static Collectormapping(Function mapper, Collector downstream) 適應一個 Collector類型的接受元件 U至類型的一個接受元件 T通過積累前應用映射函數到每個輸入元素。
staticCollector>maxBy(Comparator comparator) 返回一個 Collector ,它根據給出的 Comparator產生最大元素,描述為 Optional。
staticCollector>minBy(Comparator comparator) 返回一個 Collector ,根據給出的 Comparator產生最小元素,描述為 Optional。
staticCollector>>partitioningBy(Predicate predicate) 返回一個 Collector ,根據Predicate對輸入元素進行 Predicate ,并將它們組織成 Map> 。
static Collector>partitioningBy(Predicate predicate, Collector downstream) 返回一個 Collector ,它根據Predicate對輸入元素進行 Predicate ,根據另一個 Collector減少每個分區(qū)的值,并將其組織成 Map ,其值是下游縮減的結果。
staticCollector>reducing(BinaryOperatorop) 返回一個 Collector ,它在指定的 Collector下執(zhí)行其輸入元素的 BinaryOperator 。
staticCollectorreducing(T identity, BinaryOperatorop) 返回 Collector執(zhí)行下一個指定的減少其輸入元件的 BinaryOperator使用所提供的身份。
static Collectorreducing(U identity, Function mapper, BinaryOperator op) 返回一個 Collector ,它在指定的映射函數和 BinaryOperator下執(zhí)行其輸入元素的 BinaryOperator 。
staticCollectorsummarizingDouble(ToDoubleFunction mapper) 返回一個 Collector , double生產映射函數應用于每個輸入元素,并返回結果值的匯總統(tǒng)計信息。
staticCollectorsummarizingInt(ToIntFunction mapper) 返回一個 Collector , int生產映射函數應用于每個輸入元素,并返回結果值的匯總統(tǒng)計信息。
staticCollectorsummarizingLong(ToLongFunction mapper) 返回一個 Collector , long生產映射函數應用于每個輸入元素,并返回結果值的匯總統(tǒng)計信息。
staticCollectorsummingDouble(ToDoubleFunction mapper) 返回一個 Collector ,它產生應用于輸入元素的雙值函數的和。
staticCollectorsummingInt(ToIntFunction mapper) 返回一個 Collector ,它產生應用于輸入元素的整數值函數的和。
staticCollectorsummingLong(ToLongFunction mapper) 返回一個 Collector ,它產生應用于輸入元素的長值函數的和。
static > CollectortoCollection(SuppliercollectionFactory) 返回一個 Collector ,按照遇到的順序將輸入元素累加到一個新的 Collection中。
static Collector>toConcurrentMap(Function keyMapper, Function valueMapper) 返回一個并發(fā)的 Collector ,它將元素累加到 ConcurrentMap ,其鍵和值是將所提供的映射函數應用于輸入元素的結果。
static Collector>toConcurrentMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction) 返回一個并發(fā)的 Collector ,它將元素累加到一個 ConcurrentMap ,其鍵和值是將提供的映射函數應用于輸入元素的結果。
static >Collector toConcurrentMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction, SuppliermapSupplier) 返回一個并發(fā)的 Collector ,它將元素累加到一個 ConcurrentMap ,其鍵和值是將所提供的映射函數應用于輸入元素的結果。
staticCollector>toList() 返回一個 Collector ,它將輸入元素 List到一個新的 List 。
static Collector>toMap(Function keyMapper, Function valueMapper) 返回一個 Collector ,它將元素累加到一個 Map ,其鍵和值是將所提供的映射函數應用于輸入元素的結果。
static Collector>toMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction)  返回一個 Collector ,它將元素累加到 Map ,其鍵和值是將提供的映射函數應用于輸入元素的結果。
static > CollectortoMap(Function keyMapper, Function valueMapper, BinaryOperator mergeFunction, SuppliermapSupplier) 返回一個 Collector ,它將元素累加到一個 Map ,其鍵和值是將所提供的映射函數應用于輸入元素的結果。
staticCollector> toSet()返回一個 Collector ,將輸入元素 Set到一個新的 Set 。

七、總結

對于Java中新特性除了 Stream  還有l(wèi)amaba表達式都是可以幫忙我們很好的去優(yōu)化代碼,使我們的代碼簡潔且意圖明確,避免繁瑣的重復性的操作,對于文中有興趣的小伙伴可以操作起來。

到此,相信大家對“JDK中Stream代碼簡潔的新特性介紹”有了更深的了解,不妨來實際操作一番吧!這里是創(chuàng)新互聯(lián)網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!


本文題目:JDK中Stream代碼簡潔的新特性介紹
本文鏈接:http://weahome.cn/article/pjspsd.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部