Java Advent Calendar 2013 5æ¥ç®åãã®ã¨ã³ããªã¼ã§ããåæ¥ã¯日本人のためのDate and Time API Tips - Programming Studio
ãã®ä¼ç»ã¯ãã¯ãªã¹ãã¹ã¨ããããªã¢å çç ´ç¥ãè¿ããã«ãããJavaçæè¡ãã¿ã§ããã°ãªã©ã§ã¨ã³ããªã¼ãæ¸ããã¨ã§é«ã¾ã£ã¦ããããã¨ãããã®ã§ãï¼å¤§åï¼
俺ã®ã¨ã³ããªã§ã¯Java 8ã§æ°è¨ãããStream APIï¼java.util.stream (Java Platform SE 8 b120)ï¼ãåå¼·ããããã®ã¨ã³ããªã«ãã¾ããé²ãæ¹ã¨ãã¦ã¯Java Streams API Preview | Javalobbyã®æ¹ãæ¸ãããã¨ã³ããªãèªã¿é²ãã¦ããã¾ãããã¡ãã®ã¨ã³ããªã«æ²è¼ããã¦ãããµã³ãã«ã³ã¼ããã²ã¨ã¤ãã¤åããããã®æåã確èªãããã¨ã§ãç解ãæ·±ãã¦ããã®ããããã§ãã
ãªããJava Advent Calendar 2013ã®2æ¥ç®ã®I am programmer and proud: Stream APIの始め方ã§ã¯Streamã®ã¤ã³ã¹ã¿ã³ã¹ã«çµã£ã解説è¨äºãããã¦ããã³ãã©ã大å¤åå¼·ã«ãªãã®ã§ãªã¹ã¹ã¡ã§ãã
Stream APIã¨ã¯ï¼
Stream APIã¨ã¯ä½ã¢ã³ãªã®ãã
List<String> list = new ArrayList<>(Arrays.asList("kagami", "hoge", "foobar")); list.stream().forEach(e -> System.out.println(e));
åºåçµæã¯ãããªæãã
kagami hoge foobar
ãã£ããè¨ã£ã¦ãã¾ãã°ããããªæãã«ã³ã¬ã¯ã·ã§ã³ããããã³ã¼ããã·ã³ãã«ã«æ¸ããããã«ãªããã¨ãããã®ã§ããå¾æ¥éãã®forã使ãã°ä¸è¨ã®ãããªã³ã¼ãã¨åçã§ãããã³ã¬ã¯ã·ã§ã³ï¼ã®Streamï¼ã«Lambdaå¼ã渡ããã¨ã§ã·ã³ãã«ã«ãªãã¾ãã
for (String e : list) {
System.out.println(e);
}
Stream APIãå¦ã¶
ã¨ããããã§Java Streams API Preview | Javalobbyã®æ²è¼ããã¦ãããµã³ãã«ã³ã¼ããåãããã¨ã§ãStream APIã®ç解ãæ·±ãã¦ããã¾ãã
ãã®åã«ããã®ãµã³ãã«ã§ä½¿ããã¼ã¿ã®å ¥ãç©ç¨ã¯ã©ã¹ãããã®ã§ããã¡ããå¥éãã¦ã³ãã¼ããã¦ããã¾ãã
https://github.com/edalorzo/jdk8-experiments/blob/master/src/codemasters/lambda/domain/Person.java
https://github.com/edalorzo/jdk8-experiments/blob/master/src/codemasters/lambda/domain/Car.java
https://github.com/edalorzo/jdk8-experiments/blob/master/src/codemasters/lambda/domain/Sale.java
Challenge 1: ãã¹ã¦ã®èªåè»ã¡ã¼ã«ã»ãã©ã³ãåã表示ãã Print All Car Brands
String s = cars.map(Car::getBrand).collect(Collectors.joining(","));
System.out.println(s);
ã¨ããããStream APIã使ããªãã§åããã¨ãããã³ã¼ããæ¸ãã¦ã¿ã¾ãã
StringJoiner sj = new StringJoiner(","); for (Car car : set) { sj.add(car.getBrand()); } System.out.println(sj.toString());
ã¨ããããã§ããã£ã¦ããã¨ã¨ãã¦ã¯ä¸è¨ã®ãããªæãã§ãã
- ã³ã¬ã¯ã·ã§ã³ããèªåè»ã¡ã¼ã«ã»ãã©ã³ãåï¼getBrandï¼ãæ½åºãï¼mapï¼
- æ½åºããå称ãåä¸ã®æååã«ã¾ã¨ããï¼collectï¼
- æååã«ã¾ã¨ããã¨ããå称ã","ï¼ã«ã³ãï¼ã§åºåã
å¾æ¥ã®ã³ã¼ãã§ã¯ãforãªã©ã§æç¶ãã¨ãã¦è¨è¿°ããå¿ è¦ãããã¾ããããStream APIã§ã¯æ½åºï¼mapï¼ãã¦ãã¾ã¨ãï¼collectï¼ã¦ããã²ã¨ã¤ã®æµãã¨ãã¦è¡¨ç¾ã§ãããã¨ãã£ãã¨ããã大ããªç¹å¾´ã®ããã§ãã
Car::getBrandã¦ã®ã¯Lambdaå¼ã®Method Referencesã¨ãããã®ã§ãä¸å ãã¯ããæ¸ãã¨ãã®ã¡ã½ãã使ã£ã¦ãããã¢ã³ã ãã¨ããç解ã§ããããã§ããåèâhttp://www.oracle.com/technetwork/articles/java/lambda-1984522.htmlã®Method References
collect(Collectors.joining(","))ã¦ã®ã¯ãå¼æ°ã§æ¸¡ããããæ¹ã§ã¾ã¨ãããã¨ãããã®ãããã§å¼æ°ã«æ¸¡ãã¦ããããæ¹ã¯ãCollectors.joining(",")ã§ãããã¯ã«ã³ãã§åºåã£ã¦ã¾ã¨ãããã¨ããåä½ããã¾ãããã®ãããæçµçã«ã¯ãã³ã¬ã¯ã·ã§ã³ã®å ã§å称ãã«ã³ãã§åºåã£ãæååã¨ãã¦åºåãããã¨ããåä½ã«ãªãã¾ãã
Challenge 2: 売ãããã¨ã¿è»ããã¹ã¦è¡¨ç¤ºãã Select all Sales on Toyota
List<Sale> toyotaSales; toyotaSales = sales.filter(s -> s.getCar().getBrand().equals("Toyota")).collect(Collectors.toList()); toyotaSales.forEach(System.out::println);
Stream APIã使ããªãã§æ¸ãã¦ã¿ãã
List<Sale> toyotaSales = new LinkedList<>(); for (Sale sale : sales) { if (sale.getCar().getBrand().equals("Toyota")) { toyotaSales.add(sale); } } for (Sale s : toyotaSales) { System.out.println(s); }
ãã£ãåã®ãµã³ãã«ã¨ç°ãªãã®ã¯ãfilterã§ãããã£ã«ã¿ã®åã®éããæ¡ä»¶ã«åè´ãããã®ã ããééããã¾ããcollectã«æ¸¡ãCollectors.toList()ã¯ãè¦ç´ ããªã¹ãå½¢å¼ã§ã¾ã¨ãããã¨ããåä½ããã¾ãã
ãã£ã¦ãæçµçã«ã¯ããã¨ã¿è»ã¨ããæ¡ä»¶ãæºãããã®ããã£ã«ã¿ï¼filterï¼ãããã®ãã£ã«ã¿ãããè¦ç´ ããªã¹ãå½¢å¼ã§ã¾ã¨ãï¼collectï¼ããã¨ãããã®ã«ãªãã¾ãã
forEachã¯ãå¼æ°ã«æ¸¡ããLambdaå¼ã§ã³ã¬ã¯ã·ã§ã³ãèµ°æ»ãããã¨ããåä½ããã¾ããcollection.forEach(System.out::println);ã¦ã®ã¯Lambdaå¼ã®ãµã³ãã«è¦ã¦ãã¨ãã°ãã°è¦ãããã³ã¼ãã§ãè¦ç´ ã®å ¨è¡¨ç¤ºã¨ããåä½ããã¾ãã
Challenge 3: æãè¥ãã客ããã®è³¼å ¥ãªã¹ã Find Buys of the Youngest Person
Optional<List<Sale>> byYoungest = sales .collect(Collectors.groupingBy(Sale::getBuyer)) .entrySet() .stream() .sorted((x, y) -> x.getKey().getAge() - y.getKey().getAge()) .map(Map.Entry::getValue) .findFirst(); if (byYoungest.isPresent()) { System.out.println(byYoungest.get()); }
Stream APIã使ç¨ããã³ã¼ãã§ã¯ããããªæãã®æµãã§é²ãã§ããã¾ãã
- ã客ãããã¨ã«ã°ã«ã¼ãåï¼groupingBy(Sale::getBuyer)ï¼ããã¨ããã¾ã¨ãæ¹ï¼collectï¼ããã¦ã
- ã¾ã¨ãããã®ãSetï¼Set
>>ãã客ãã:販売 = 1:å¤ï¼ã«å¤æï¼entrySetï¼ã㦠- ãã®setããstreamãå¾ã¦ã
- ã客ãã対販売ãªã¹ãã®Setãå¹´é½¢é ã«ä¸¦ã³æ¿ãï¼sorted(...)ï¼ã
- 並ã³æ¿ããSetããã販売ãªã¹ãã ããæ½åºããï¼map(Map.Entry::getValue)ï¼
- å é ãåå¾ããï¼findFirstï¼
æ¥æ¬èªã§æ¸ãã¨é常ã«é·ã£ãããããªãã®ã§ããããããããã¨ã¯ãæãè¥ã人ç©ãè³¼å ¥ãããã®ä¸è¦§ããªã ãã§ãããã ãã³ã¼ããè¦ãã°ãã³ã¬ã¯ã·ã§ã³ããã¼ãªã£ã¦âãã¼ãªã£ã¦âãã¼ãªããã¨ããæµãã表ç¾ããã¦ãã®ãåãããã¨æãã¾ãã
ã¨ã¯ãããã¶ã£ã¡ããåè¦ã§ã¯ä¿ºã¯ãµãããªç解ä¸è½ã§ããããã®ãããå®éã«åå¼·ããã¨ãã¯ã¡ã½ãããä¸åãã¤å¢ããã¦æåã確èªããæ¹æ³ã§é²ãã¦ãã¾ãããä¸ã®ã³ã¼ãä¾ã§ããã¨ãã¾ãcollectã ãã«ãã¦ãã©ããªåã§å¤ãè¿ã£ã¦ãããã確èªããã次ã«entrySetãå¢ããã¦åããã¨ããããsteremãsortedã»ã»ã»ã¨ãã£ãæãã
ããã«ãå¾æ¥ã®ããæ¹ã§æ¸ãç´ãããã¨ããã£ã¦ã¿ã¾ãã
SortedMap<Person, List<Sale>> sortedByAgeMap = new TreeMap<>(new Comparator<Person>() { @Override public int compare(Person x, Person y) { return x.getAge() - y.getAge(); } }); for (Sale s : sales1) { if (sortedByAgeMap.containsKey(s.getBuyer())) { sortedByAgeMap.get(s.getBuyer()).add(s); } else { List<Sale> t = new ArrayList<>(); t.add(s); sortedByAgeMap.put(s.getBuyer(), t); } } System.out.println(sortedByAgeMap.get(sortedByAgeMap.firstKey()));
ã¾ããComparatorã5è¡ãããã¨ããã1è¡ã§æ¸ãã§ãã¾ããããã¯Stream APIã¨ããããLambdaå¼ã®ç¯çã§ããã宣è¨çã«æ¸ããã¨é常ã«ç°¡æ½ã«ãªããã¨ã伺ãã¾ããã°ã«ã¼ãåããã³ã¼ãã¯ãã¾ãã客ããããã¼ãå¤ã«è²©å£²ãªã¹ããåãSortedMapãç¨æããããæ¹ã«ãã¾ãããå®ã®ã¨ããããããªåé·ãªæ¸ãæ¹ã«ãªããã ã£ãï¼ãã¨ãããªãæ©ãã ã³ã¼ãã§ãããªã®ã§ããã¡ãã£ã¨ãã³ãã«ãªãã¨ã¯æãã¾ãããStream APIã®ç°¡æ½ããè¦ãä¸ã§ã¯è¯ãæ¯è¼ã«ãªãã¨æããã§ããããã³ã¼ããæ¸ãã¾ããã
ããã²ã¨ã¤è¦éããªãã®ãOptional (Java Platform SE 8 b120)ã§ããããã¯nullãææ¢ããããã®ãã¿ã¼ã³ã¨ãè¨ãããã®ã§ããã³ã¼ãä¸ã«ããisPresent()ã¯ãè¿ããå¤ãããã°trueã§ãããã§ãªããã°falseãè¿ãã¾ãããªãããã®ä¾ã®å ´åã¯ä¸è¨ã®ããã«ãæ¸ãã¦ãåãã§ãã
byYoungest.ifPresent(System.out::println);
Challenge 4: æãé«ä¾¡ãªè²©å£² Find Most Costly Sale
Comparator<Sale> byCost = Comparator.comparingDouble((ToDoubleFunction<Sale>)Sale::getCost).reversed();
Optional<Sale> mostCostlySale = sales
.sorted(byCost)
.findFirst();
if (mostCostlySale.isPresent()) {
System.out.println(mostCostlySale.get());
}
ãã®ä¾ã§ã¯ã¾ããComparator
Sale::getCost (s) -> s.getCost()
ãããã¦ä½æããToDoubleFunction
ãã¨ã¯ããã®ã³ã¹ãéé Comparatorãsoretedã®å¼æ°ã«æå®ãã¦ãfindFirstãããã°ã³ã¹ãæ大ã®Saleãåå¾ã§ãã¾ãã
ãã£ãããªã®ã§å¾æ¥éãã®æ¸ãæ¹ããã¦ã¿ã¾ãã
List<Sale> tmpSales = new ArrayList<Sale>(sales1); Collections.sort(tmpSales, new Comparator<Sale>() { @Override public int compare(Sale x, Sale y) { if (x.getCost() == y.getCost()) { return 0; } else if (x.getCost() > y.getCost()) { return -1; } return 1; } }); if (tmpSales.size() > 0) { System.out.println(tmpSales.get(0)); }
compareã®ã¨ããã¯é å¼µãã°ããã¡ãã£ã¨ãã³ãã«ãªãã¨ã¯æããã®ã®ãæç´ã«æ¸ãã°ãããªããã¨æãã¾ãã
Challenge 5: ç·æ§ã®ãã¤ã¤ã¼ãã¤ã客ããã®è²©å£²ã®åè¨ã³ã¹ã Sum of Sales from Male Buyers & Sellers
double sum = sales.filter(s -> s.getBuyer().isMale() && s.getSeller().isMale()) .mapToDouble(Sale::getCost) .sum(); System.out.println(sum);
ãããã¾ãã¯Stream APIã®æµããè¦ã¦ããã¾ãã
- ããã¤ã¤ã¼ãç·æ§ãã¤ã客ãããç·æ§ãã®æ¡ä»¶ãæºããSaleããã£ã«ã¿ï¼filterï¼ãã
- Saleããã³ã¹ãï¼Sale::getCostï¼ãæ½åºï¼mapToDoubleï¼ãã
- æ½åºããã³ã¹ããåè¨ï¼sumï¼
ãã¾ã¾ã§ã®ãµã³ãã«ã³ã¼ãã¨æ¯ã¹ãã¨ãmapToDouble, sumãåç»å ´ãã¦ãã¾ãããæ¦ãã¡ã½ããåéãã®åä½ããã¾ãã
ãããå¾æ¥éãã®forã«ã¼ããåãããæ¹ã§æ¸ãã¦ã¿ã¾ãã
double sum = 0; for (Sale s : sales1) { if (s.getBuyer().isMale() && s.getSeller().isMale()) { sum += s.getCost(); } } System.out.println(sum);
ã³ã¬ã¯ã·ã§ã³å è¦ç´ ã®åè¨ã¨ããç´ æ´ãªä¾ã§ãããæ¯ã¹ãã¨ããªãç°ãªããã¨ãåããã¾ããStream APIã使ç¨ããå ´åãfilterãã¦mapãã¦sumãããã¨ã³ã¬ã¯ã·ã§ã³ã«å¯¾ãã¦ä¸é£ã®å¦çã®æµããè¨å®ãã¦ãã¾ããå¾æ¥éãforã«ã¼ãã§è§£ãå ´åãå¦çã®é åºãè¨è¿°ãã¦ãã¾ãã
Challenge 6: æãè¥ãã客ããã®å¹´é½¢ Find the Age of the Youngest Buyer
æãè¥ãã客ããã®å¹´é½¢ãæ¢ãããã ãã³ã¹ãã40,000ãã大ãããã®ãã¨ããã±ã¼ã¹ã§ãã
OptionalInt ageOfYoungest; ageOfYoungest = sales.filter(sale -> sale.getCost() > 40000) .map(Sale::getBuyer) .mapToInt(Person::getAge) .sorted() .findFirst(); if(ageOfYoungest.isPresent()) { System.out.println(ageOfYoungest.getAsInt()); }
æ¡ä»¶ï¼cost > 40000ï¼ã§ãã£ã«ã¿ï¼filterï¼ãããã¦çµè¾¼ã¿ãã客ããï¼Sale::getBuyerï¼ã ããæ½åºï¼mapï¼ãã¦ãããã«å¹´é½¢ï¼Person::getAgeï¼ã ããæ½åºãã¦ã並ã¹æ¿ãã¦ï¼sortedï¼ãä¸çªæåã®ãã®ãé¸æï¼findFirstï¼ãããããã¦ãè¿ãå¤ã¯çµæãåå¨ããã¨ã¯éããªãã®ã§OptionalIntã§åããã
ãããå¾æ¥éãã®ããæ¹ã§æ¸ãã¦ã¿ã¾ãã
SortedSet<Integer> ages = new TreeSet<>(); for (Sale s : sales1) { if (s.getCost() > 40000) { ages.add(s.getBuyer().getAge()); } } if (ages.size() > 0) { System.out.println(ages.first()); }
Challenge 7: ã³ã¹ãã§ã½ã¼ã Sort Sales by Cost
Challenge 4ã¨ã»ã¼åçã®å 容ã§ãã
Comparator<Sale> byCost= Comparator.comparingDouble((ToDoubleFunction<Sale>) Sale::getCost); List<Sale> sortedByCost; sortedByCost = sales.sorted( byCost ).collect(Collectors.toList()); sortedByCost.forEach(System.out::println);
Challenge 8: ã«ã¼ãã©ã³ããã¨ã®è»ç¨®ä¸è¦§ Index Cars by Brand
Map<String,List<Car>> byBrand; byBrand = cars.collect( Collectors.groupingBy(Car::getBrand )); byBrand.forEach((k,v) -> System.out.println(k + ":" + v));
Challenge 3ã§ãåºã¦ããã°ã«ã¼ãåã使ç¨ãã¦ãã«ã¼ãã©ã³ããã¨ã«Carãéç´ãã¾ããMapã§forEachã使ç¨ããå ´åãListã¨ã¯ç°ãªãå¼æ°ã2ã¤åããããããMapã¨ã³ããªã®ãã¼ã¨å¤ã§ããããã§ã¯ããã¼ã¨å¤ãå¼æ°k, vã«åãLambdaå¼ã§è¨è¿°ãã¦ãã¾ãã
Challenge 9: æã売ããè»ç¨® Find Most Bought Car
ã³ã¹ãã§ã¯ãªã売ããæ°ãæ大ã®è»ç¨®ãæ¢ãã¾ãã
ToIntFunction<Map.Entry<Car, List<Sale>>> toSize = e -> e.getValue().size(); Optional<Car> mostBought; mostBought = sales.collect(Collectors.groupingBy(Sale::getCar)) .entrySet() .stream() .sorted(Comparator.comparingInt(toSize).reversed()) .map(Map.Entry::getKey) .findFirst(); if(mostBought.isPresent()) { System.out.println(mostBought.get()); }
ãããæµããè¦ã¦ããã¾ãã
- Saleãè»ç¨®ãã¨ã«ã°ã«ã¼ãåï¼roupingBy(Sale::getCar)ï¼ããã¨ããã¾ã¨ãæ¹ï¼collectï¼ããã¦ã
- è»ç¨®ãã¨ã«ã¾ã¨ããããSaleãªã¹ãã®å¤§ããï¼ï¼ã¤ã¾ãè»ç¨®ãã¨ã®å£²ããæ°ï¼ãéé ã§ä¸¦ã¹æ¿ãï¼soreted(toSize).reversedï¼ããã¦ã
- è»ç¨®ã ããæ½åºï¼Map.Entry::getKeyï¼ãã¦
- å é ãåå¾ããï¼findFirstï¼
ãã®æµããã®ãã®ã¯ä»ã¾ã§ã®Challengeã§åºã¦ãããã®ã®çµã¿åããã§ãããToIntFunctionã®ã¨ããã¯Challenge 4ã®ã¨ããã§ãåºã¦ããã®ã ãã©ã¡ãã£ã¨åããã«ããã
ã¾ããToIntFunction
ææ³ã¨ã
ã¨ã¾ããããªããã§Stream APIãã©ããªããããã£ããè¦ã¦ãã¾ããããã£ããã¯ä¿ºå人ã®ææ³ã¨ããæ¸ãã¦ããã¾ãã
Stream APIåä½ã ãã«é¢ãã¦ã¯ãæ°ããã³ã¬ã¯ã·ã§ã³å¦çã®ã©ã¤ãã©ãªã次ã®ãã¼ã¸ã§ã³ã§å¢ããã ããã¨è¨ãåããªãããªãã§ãã使ãæ¹ã®ä¾ãè¦ã¦å¤§æ ãã¤ãã¿ãæãè¦ã¦javadocãåç §ãã¦ã©ããªã¡ã½ãããã¯ã©ã¹ãæä¾ããã¦ããããå°ããã¤è¦ãã¦ãããããå¹ççãªã³ã¼ãã£ã³ã°ã®ããæ¹ãè¦ãã¦ããããã®ã¹ãããèªä½ã¯ã¿ãã³ããã¾ãå¤ãããªãã¨æãã¾ãã
ããããStreamã¯ããåä½ã§ä½¿ãã¨ããããLambdaå¼ã¨ã»ããã§ä½¿ã£ã¦ãã価å¤ãåºããããã¦ãLambdaå¼ã¯ä»ã¾ã§ã®Javaã®ãã¨ããããæç¶ãåããã°ã©ãã³ã°ã®ç¥èã ãã§ç«ã¡åãããã¨ã¯ã¡ãã£ã¨é£ãããé¢æ°åè¨èªã¯ã©ã¹ã¿ã®æ¹ã ããè¦ãã°2000å¹´åã«ééããå ´æãããããªãã§ãããJavaããã°ã©ãã«ã¨ã£ã¦ã¯âå°ãªãã¨ã俺ã«ã¨ã£ã¦ã¯âè¡æçãªãã®ã§ãããLambdaå¼ã®æ義ã¨ããã¯ãã¼ã¸ã£ã§ã¯ãªãã¨ããã¾ãããããè°è«ã¯ãããã§ããããã¯ç½®ãã¦ããã¨ãã¦ã
é¢æ°åè¨èªåçç¹é·ãæã¤Lambdaå¼ã¨Streamãã©ã®ããã«ç解ããã°ããã®ããããã¯ä¿ºèªèº«ãJavaScriptã¨ãActionScriptã¨ãã§æ©ã¾ããããããã¯ã§ããããã®ã¸ããæ¯ãè¿ããªããæ¸ãã¦ããã¾ãã
俺ãç解ããè¨èã§æ¸ãã°ãã³ã¬ã¯ã·ã§ã³ãããå¦çããã®ã§ã¯ãªãã³ã¬ã¯ã·ã§ã³ãã«ãå¦çã渡ããã¨ãããã®ã«ãªãã¾ããä¾ãã°ä¸è¨ã®ãããªã³ã¼ãã¯ãã³ã¬ã¯ã·ã§ã³ãã«ãæ¨æºåºåããå¦çã渡ãã¦ãã¾ãã
list.stream().forEach(e -> System.out.println(e));
ãã¡ãã¯ãã³ã¬ã¯ã·ã§ã³ãããã«ã¼ãã§å¦çãã¦ãã¾ãã
for (String e : list) {
System.out.println(e);
}
ãã®ä¸¡è ã決å®çã«ç°ãªãã®ã¯ãã³ã¬ã¯ã·ã§ã³ãã©ã®ããã«å¦çããããæ示çã«æ¸ãã¦ãããã©ãããã§ããStreamã®æ¹ã§ã¯ãåè¦ç´ ã«å¯¾ãã¦å¦çãããããæ示ã¯ãã¦ãããã®ã®ãç¹°ãè¿ãå¦çãå é¨ã§ã¯ã©ããªã¢ã«ã´ãªãºã ã«ãªããã¯ä¸åã³ã¼ãã«ãã¦ãã¾ãããä¸æ¹foræã®æ¹ã§ã¯ãã¤ã³ããã¯ã¹0çªå°ã®è¦ç´ ããé ã«å¦çããã¨ããã¢ã«ã´ãªãºã ãæ示çã«æ¸ããã¦ãã¾ãã
ãã®ã¡ãªããã®ã²ã¨ã¤ã¯æé©åã®ä½å°ãåºãããã¨ã§ããJava 8é¢é£ã®ææ¸ãè¦ãã¨ãã¨ããã並è¡æ§ã«ã¤ãã¦è¨åããã¦ãã¾ããããã°ã©ãã®å´ããã¯ãã³ã¬ã¯ã·ã§ã³ãã©ãå¦çããããç¥ã£ããã£ã¡ããªããªãã®ã§ãã©ã¤ãã©ãªå´ã§å¥½ãæ¾é¡ã§ããä½å°ãåºãããããªããã§ããä¸æ¹ãforæãªã©ã§å¦çã®é åºãåºå®ãã¦ãã¾ãã¨ããã®é çªã§ããã³ã¼ããå®è¡ã§ããªããªã£ã¦ãã¾ããã³ã¬ã¯ã·ã§ã³ã©ã¤ãã©ãªã«ä»»ãã¦ãã¾ãã°ããã£ããã¨ããã¯æé©åã§ãããããã£ã¡ã¾ããã¨ããã¼ããã®ãã§ããããã«ãªããã¾ããç¹°ãè¿ãå¦çã®ã¢ã«ã´ãªãºã ããã³æããããã¨ã§ãããã°ã©ãã®è² æ ãæ¸ãå¯è½æ§ãããã¾ãã
å¦çãæ¸ãããå¦çã宣è¨ãããã¨ããªãæé©åã«ã¤ãªããã®ãããã®æè¦ã¯SQLãèãã¦ã¿ãã¨åãããããã§ãããã¨ãã°ãä¸è¨ã®ãããªãã客ãããã¨ã®ã³ã¹ãåè¨ãã³ã¹ãã100以ä¸ã®ãã®ã«çµã£ã¦åºããã¯ã¨ãªãèãã¦ã¿ã¾ã*5ã
SELECT buyer_id, sum(cost) FROM sales WHERE cost > 100 GROUP BY buyer_id;
SQLã§ã¯ãã©ããªçµæã欲ããããè¨è¿°ãã¾ãããã®ã¨ãããã®ã¯ã¨ãªãã©ã®ãããªã¢ã«ã´ãªãºã ã§å¦çããããã¯ç¥ã£ããã¨ã§ã¯ãªãã§ããéç´ã1ããé çªã«è¶³ãããã§ããã®ããããã¨ãããä¸å®ç¯å²ãã¨ã«åå²ãã¦ã¹ã¬ããã§åè¨ãããã¨ãã®çµæã足ãã®ããã¡ã¢ãªã使ãã®ããã£ã¹ã¯ããèªãã®ãâ¦â¦ã¨ã¾ããSQLã§ã¯ã©ããªçµæã欲ãããè¨è¿°ãããã¨ã¨ããããã©ããªã¢ã«ã´ãªãºã ãçµã¦åºåãããã®ããã¯å¥æ¬¡å ã®è©±ã§ãã
ãã®ãã¨ã¯ãSQLã§å®ç¾ãããä½ãããã®ãã¸ãã¹çãªè«çã¬ãã«ã®è¦æ±ã¨ããã®ã¯ã¨ãªãã³ã³ãã¥ã¼ã¿ä¸ã§ã©ã®ããã«å®ç¾ãããã®ç©çã¬ãã«ã®è¦æ±ã¨ããåé¢ãã¦ããã¨è¨ãã¾ã*6ãã§ã¾ãã³ã¬ãå¬ãããã¨ã®ã²ã¨ã¤ã¯æé©åã®ä½å°ãåºããããã§ããRDBMSã®ã¨ã³ã¸ã³å´ã§ã¯ããã®SQLãä½ãå®ç¾ãããã®ãã®çµæãå¤ããªãç¯å²ã«ããã¦ãSQLã好ãåæãã¥ã¼ãã³ã°ã§ããã
ããã§ã¾ãJavaã«æ»ã£ã¦ããããã§ããããã£ãã®SQLãStreamã§æ¸ãã°ãããªæãã«ãªãã
Map<Person, Double> sumOfCostByBuyer = sales .collect(Collectors.groupingBy( Sale::getBuyer, Collectors.summingDouble(s -> {return s.getCost() > 10000 ? s.getCost() : 0;}))); sumOfCostByBuyer.forEach((k, v) -> System.out.println(k + ":" + v));
SQLã®ããã«ãã³ã¬ã¯ã·ã§ã³ããã©ããªçµæã欲ãããããæ¸ããã¦ãã¾ããã³ã¬ã¯ã·ã§ã³ãããå¦çããã®ã§ã¯ãªããã³ã¬ã¯ã·ã§ã³ãã«ãå¦çã渡ããã«ã¼ãã§å¦çããã®ãã¯ãã¾ããã£ã¨ãããããã¢ã«ã´ãªãºã ã§å¦çããã®ãã¯ç¥ãç±ãç¡ããç¥ããªããã¨ã§æé©åã®ä½å°ãçããã
â¦â¦ã¨ãããããããã³ããµãããã¨ãæ¸ãã¦ãã¾ã£ãã®ã ããã©ãããã¯ãå¾ä»ã§å°å ¥ããã代ç©ãªã®ã§ãä¸é½åã§ãã£ããã ãªã§ãã£ããã¨ãã°ã°ãã¨è²ã è¦ã¤ããã¾ããããã¯ã¾ãâ¦â¦å°ã£ããä»ã¾ã§éãã®ããæ¹ã§åé¿ã§ããã ããã·ãã¨æãè¾¼ããã¨ã«ãã¦ã¾ãã
ãããï¼
ãããªäºç´°ãªãã¨ããããã£ã½ã©éè¦ãªLambdaå¼ã¨Streamã使ãçç±ãããã¾ããããã¯â¦â¦
COOL!!*7
ãã以ä¸ã«éè¦ãªçç±ãªã©ããçãç¡ãã
åèURL
çµããã«
ææ¥ã¯@muraken720ããã§ãã
*1:java.util.stream.Collectors#toStringJoinerã¯å»æ¢ãããhttp://download.java.net/jdk8/docs/api/java/util/stream/Collectors.html#joining-java.lang.CharSequence-:title=java.util.stream.Collectors#joining ã«çµ±åããã¦ããããã§ãã
*2:http://download.java.net/jdk8/docs/api/java/util/StringJoiner.html ã¯Java 8ãã追å ãããã¯ã©ã¹
*3:åç §å URLã§ã¯ãcomparing ã«ãªã£ã¦ããããCompartorã®Lambdaå¼ã§ã®æ¯è¼ãæ¸ãããã£ãã®ã§ãããã¦ããã
*4:å¹´é½¢ã®compareã¯ããã§ãããããã£ã¦æãã®ãããã¼ãªã¢ã¬ãªã®ã§ã¹ã«ã¼ãã¦é ããã
*5:ãã¾ãæå³ãæããªãä¾ã§ãã¾ã¬â¦â¦ãã¾ã¬â¦â¦
*6:ãããã¾ãå®éã«ã¯ãããã¬ã¤ã«åãããããã©ããã¾ãå¤å°ã¯ãï¼