Java SE 9 の予習
今日は私の○X回目の誕生日です。
今年は忘れられずにお祝いのプレゼントまでいただきました。(^_^)
いくつになっても誕生日を祝ってもらえるのは嬉しいものです。
と言うわけでお誕生日記念として今年の夏にリリース予定の Java SE 9 の予習をはじめます。
Java SE 9 と言えば Project Jigsaw, Project Kulla (JShell) が目玉となっています。
これらはこれから日本語での情報もたくさん出てくると思うので後回しとします。(既に最新Java情報局で記事があります。)
故に Java SE 9 を使うのであれば必要最低限これだけは覚えておきたいことを自分用メモとして載せておきます。
完全に自分用のメモです!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
package jp.yucchi.jdk9eaexample; import java.time.LocalDate; import java.time.Period; import java.util.List; /** * * @author Yucchi */ class MyFriends { public enum Sex { MALE, FEMALE, OKAMA } int id; String name; LocalDate birthday; Sex gender; String phoneNumber; String profession; String birthplace; int favorabilityRating; List<String> hobby; MyFriends(int id, String name, LocalDate birthday, Sex gender, String phoneNumber, String profession, String birthplace, int favorabilityRating, List<String> hobby) { this.id = id; this.name = name; this.birthday = birthday; this.gender = gender; this.phoneNumber = phoneNumber; this.profession = profession; this.birthplace = birthplace; this.favorabilityRating = favorabilityRating; this.hobby = hobby; } public int getId() { return id; } public String getName() { return name; } public LocalDate getBirthday() { return birthday; } public Sex getGender() { return gender; } public String getPhoneNumber() { return phoneNumber; } public String getProfession() { return profession; } public String getBirthplace() { return birthplace; } public int getFavorabilityRating() { return favorabilityRating; } public int getAge() { return Period.between(birthday, LocalDate.now()).getYears(); } public List<String> getHobby() { return hobby; } public void printMyFriends() { System.out.println(this.id + ": " + this.name + ", " + this.getAge() + "歳" + ", Gender: " + this.gender + ", 電話番号: " + this.phoneNumber + ", 職業: " + this.profession + ", 出身地: " + this.birthplace + ", 好感度: " + this.favorabilityRating + ", 趣味: " + this.hobby); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 |
package jp.yucchi.jdk9eaexample; import java.time.LocalDate; import java.util.ArrayList; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.IntStream; import java.util.stream.Stream; /** * * @author Yucchi */ public class JDK9eaExample { public static void main(String[] args) { List<MyFriends> myFriends = new ArrayList<>(); myFriends.add(new MyFriends(1, "柴田 恭平", LocalDate.of(1951, 8, 18), MyFriends.Sex.MALE, "81300000001", "俳優", "静岡県", 80, List.of("野球", "サッカー", "三味線"))); myFriends.add(new MyFriends(2, "小栗 旬", LocalDate.of(1982, 12, 26), MyFriends.Sex.MALE, "81300000002", "俳優", "東京都", 75, List.of("野球", "音楽鑑賞", "フィギア収集", "マンガ"))); myFriends.add(new MyFriends(3, "市原 隼人", LocalDate.of(1987, 2, 6), MyFriends.Sex.MALE, "81300000003", "俳優", "神奈川県", 70, List.of("テレビゲーム", "カラオケ"))); myFriends.add(new MyFriends(4, "安倍 晋三", LocalDate.of(1954, 9, 21), MyFriends.Sex.MALE, "81300000004", "政治家", "東京都", 40, List.of("ゴルフ", "映画観賞", "読書", "水泳"))); myFriends.add(new MyFriends(5, "ドナルド トランプ", LocalDate.of(1946, 1, 20), MyFriends.Sex.MALE, "1100000005", "政治家", "ニューヨーク", 55, List.of("ゴルフ", "プロレス観戦"))); myFriends.add(new MyFriends(6, "桐谷 美玲", LocalDate.of(1989, 12, 16), MyFriends.Sex.FEMALE, "81300000006", "女優", "千葉県", 95, List.of("音楽鑑賞", "サッカー観戦"))); myFriends.add(new MyFriends(7, "有村 架純", LocalDate.of(1993, 2, 13), MyFriends.Sex.FEMALE, "81300000007", "女優", "兵庫県", 90, List.of("お菓子づくり", "散歩", "買い物"))); myFriends.add(new MyFriends(8, "綾瀬 はるか", LocalDate.of(1985, 3, 24), MyFriends.Sex.FEMALE, "81300000008", "女優", "広島県", 85, List.of("カラオケ", "お菓子づくり", "足首回し"))); myFriends.add(new MyFriends(9, "佐々木 希", LocalDate.of(1988, 2, 8), MyFriends.Sex.FEMALE, "81300000009", "女優", "秋田県", 81, List.of("アクセサリー収集"))); myFriends.add(new MyFriends(10, "剛力 彩芽", LocalDate.of(1992, 8, 27), MyFriends.Sex.FEMALE, "81300000010", "女優", "神奈川県", 76, List.of("お菓子づくり", "フルート", "料理"))); myFriends.add(new MyFriends(11, "堀北 真希", LocalDate.of(1988, 10, 6), MyFriends.Sex.FEMALE, "81300000011", "女優", "東京都", 88, List.of("読書", "サイクリング"))); myFriends.add(new MyFriends(12, "深田 恭子", LocalDate.of(1982, 11, 2), MyFriends.Sex.FEMALE, "81300000012", "女優", "東京都", 80, List.of("サーフィン", "書道", "ピアノ", "水泳"))); myFriends.add(new MyFriends(13, "小池 百合子", LocalDate.of(1952, 7, 15), MyFriends.Sex.FEMALE, "81300000013", "政治家", "兵庫県", 50, List.of("ゴルフ", "テニス"))); myFriends.add(new MyFriends(14, "宇多田 ヒカル", LocalDate.of(1983, 1, 19), MyFriends.Sex.FEMALE, "81300000014", "歌手", "ニューヨーク", 91, List.of("読書", "マンガ", "絵画"))); myFriends.add(new MyFriends(15, "西野 カナ", LocalDate.of(1989, 3, 18), MyFriends.Sex.FEMALE, "81300000015", "歌手", "三重県", 77, List.of("料理", "海外旅行"))); myFriends.add(new MyFriends(16, "きゃりーぱみゅぱみゅ", LocalDate.of(1993, 1, 29), MyFriends.Sex.FEMALE, "81300000016", "歌手", "東京都", 74, List.of("釣り", "音楽"))); myFriends.add(new MyFriends(17, "はるな 愛", LocalDate.of(1972, 7, 21), MyFriends.Sex.OKAMA, "81300000017", "おネエ系タレント", "大阪府", 69, List.of("釣り", "サーフィン", "スノーボード", "ゴルフ", "映画鑑賞"))); myFriends.add(new MyFriends(18, "マツコ・デラックス", LocalDate.of(1972, 10, 26), MyFriends.Sex.OKAMA, "81300000018", "おネエ系タレント", "千葉県", 88, List.of("女装", "ドライブ"))); // MyFriends 全員表示 System.out.println("<-- MyFriends -->"); myFriends.stream().forEach(MyFriends::printMyFriends); // Optional::stream Function<MyFriends, Optional<MyFriends>> optionalStreamMapper = mf -> mf.getFavorabilityRating() >= 80 ? Optional.of(mf) : Optional.empty(); System.out.println("\nJava8 Optional::stream"); myFriends.stream() .map(optionalStreamMapper) .filter(Optional::isPresent) .map(Optional::get) .collect(Collectors.toList()) .forEach(MyFriends::printMyFriends); System.out.println("\nJava9 Optional::stream"); myFriends.stream() .map(optionalStreamMapper) .flatMap(Optional::stream) .collect(Collectors.toList()) .forEach(MyFriends::printMyFriends); // Stream ofNullable Function<MyFriends, MyFriends> streamOfNullableMapper = mf -> mf.getAge() < 25 ? mf : null; System.out.println("\nJava8 Stream ofNullable"); myFriends.stream() .map(streamOfNullableMapper) .flatMap(s -> s != null ? Stream.of(s) : Stream.empty()) .collect(Collectors.toList()) .forEach(MyFriends::printMyFriends); System.out.println("\nJava9 Stream ofNullable"); myFriends.stream() .map(streamOfNullableMapper) .flatMap(mf -> Stream.ofNullable(mf)) .collect(Collectors.toList()) .forEach(MyFriends::printMyFriends); System.out.println("\nID で友達を検索"); // ID で友達を検索 findById(7, myFriends); // 無効な ID で友達を検索 findById(27, myFriends); System.out.println("\n名前で友達を検索"); // 名前で友達を検索 findByName("桐谷 美玲", myFriends); // 無効な名前で友達を検索 findByName("二階堂 ふみ", myFriends); System.out.println("\n電話番号で友達を検索"); // 電話番号で友達を検索 findByPhoneNumber("1100000005", myFriends); // 無効な電話番号で友達を検索 findByPhoneNumber("81300003015", myFriends); System.out.println("\nID、名前、電話番号の順に友達を検索"); // ID、名前、電話番号の順に友達を検索 // ID、名前、電話番号 すべて有効 <14: 宇多田 ヒカル, 34歳, Gender: FEMALE, 電話番号: 81300000014, 職業: 歌手, 出身地: ニューヨーク, 好感度: 911, 趣味: [読書, マンガ, 絵画]> findByMyFriendsIdOrNameOrPhoneNumber(14, "西野 カナ", "81300000016", myFriends); // 名前、電話番号 有効 <15: 西野 カナ, 27歳, Gender: FEMALE, 電話番号: 81300000015, 職業: 歌手, 出身地: 三重県, 好感度: 77, 趣味: [料理, 海外旅行]> findByMyFriendsIdOrNameOrPhoneNumber(99, "西野 カナ", "81300000016", myFriends); // 電話番号 有効 <16: きゃりーぱみゅぱみゅ, 24歳, Gender: FEMALE, 電話番号: 81300000016, 職業: 歌手, 出身地: 東京都, 好感度: 74, 趣味: [釣り, 音楽]> findByMyFriendsIdOrNameOrPhoneNumber(99, "二階堂 ふみ", "81300000016", myFriends); // ID、名前、電話番号 すべて無効 findByMyFriendsIdOrNameOrPhoneNumber(99, "二階堂 ふみ", "81300009014", myFriends); System.out.println("\n職業別にグループ化し好感度 90 以上の友達を検索"); findByProfession(myFriends, 90); System.out.println("\n出身地別にグループ化して友達の名前を検索"); findByBirthplace(myFriends); System.out.println("\n職業別にグループ化し趣味を検索"); findByHobbyByProfession(myFriends); System.out.println("\n年齢が若い順に友達を表示"); findByYoungOrder(myFriends); System.out.println("\n年齢が若い順に好感度が70未満の友達がヒットするまで検索"); findByYoungFriendsByFavorabilityRating(myFriends, 70); System.out.println("\n年齢が大きい順に好感度が90未満の友達がヒットするまでスキップして検索"); findByOldFriendsByFavorabilityRating(myFriends, 90); System.out.println("\n条件付きで年齢が若い順に友達を表示 27歳以下スキップ、34歳まで リミット"); findByConditionalYoungOrder(myFriends, 27, 34); System.out.println("\nID 1 から Double Calculation で計算して友達を検索 ただし、ID は 50 未満の範囲とする。(実質 32 まで)"); findByIdDoubleCalculation(myFriends, 50); } // ID で友達を検索して表示する private static void findById(int id, List<MyFriends> myFriends) { Optional<MyFriends> myFriendsById = findMyFriendsById(id, myFriends); // // Java8 * myFriendsById.ifPresent(MyFriends::printMyFriends); だと存在しなかったときの処理ができなくて不便 (>_<) // if (myFriendsById.isPresent()) { // ここで既に負けている(>_<) // myFriendsById.get().printMyFriends(); // } else { // notFoundById(id); // } myFriendsById.ifPresentOrElse(MyFriends::printMyFriends, () -> notFoundById(id)); } // ID で友達を検索 Optional<MyFriends> オブジェクト取得 private static Optional<MyFriends> findMyFriendsById(int id, List<MyFriends> myFriends) { return myFriends .stream() .filter(e -> e.getId() == id) .findFirst(); } // ID で友達を検索して存在しなかった場合のメッセージを表示 private static void notFoundById(int id) { System.out.println("ID " + id + " の友達は存在しません。"); } // 名前で友達を検索して表示する private static void findByName(String name, List<MyFriends> myFriends) { Optional<MyFriends> myFriendsByName = findMyFriendsByName(name, myFriends); myFriendsByName.ifPresentOrElse(MyFriends::printMyFriends, () -> notFoundByName(name)); } // 名前で友達を検索 Optional<MyFriends> オブジェクト取得 private static Optional<MyFriends> findMyFriendsByName(String name, List<MyFriends> myFriends) { return myFriends .stream() .filter(e -> Objects.equals(e.getName(), name)) .findFirst(); } // 名前で友達を検索して存在しなかった場合のメッセージを表示 private static void notFoundByName(String name) { System.out.println("名前 " + name + " の友達は存在しません。"); } // 電話番号で友達を検索して表示する private static void findByPhoneNumber(String phoneNumber, List<MyFriends> myFriends) { Optional<MyFriends> myFriendsByPhoneNumber = findMyFriendsByPhoneNumber(phoneNumber, myFriends); myFriendsByPhoneNumber.ifPresentOrElse(MyFriends::printMyFriends, () -> notFoundByPhoneNumber(phoneNumber)); } // 電話番号で友達を検索 Optional<MyFriends> オブジェクト取得 private static Optional<MyFriends> findMyFriendsByPhoneNumber(String phoneNumber, List<MyFriends> myFriends) { return myFriends .stream() .filter(e -> Objects.equals(e.getPhoneNumber(), phoneNumber)) .findFirst(); } // 電話番号で友達を検索して存在しなかった場合のメッセージを表示 private static void notFoundByPhoneNumber(String phoneNumber) { System.out.println("電話番号 " + phoneNumber + " の友達は存在しません。"); } // ID、名前、電話番号の順に友達を検索して表示する private static void findByMyFriendsIdOrNameOrPhoneNumber(int id, String name, String phoneNumber, List<MyFriends> myFriends) { Optional<MyFriends> myFriendsById = findMyFriendsById(id, myFriends); Optional<MyFriends> myFriendsByName = findMyFriendsByName(name, myFriends); Optional<MyFriends> myFriendsByPhoneNumber = findMyFriendsByPhoneNumber(phoneNumber, myFriends); myFriendsById .or(() -> myFriendsByName .or(() -> myFriendsByPhoneNumber)) .ifPresentOrElse(MyFriends::printMyFriends, () -> notFoundByIdOrNameOrPhoneNumber(id, name, phoneNumber)); } // ID、名前、電話番号の順に友達を検索して存在しなかった場合のメッセージを表示 private static void notFoundByIdOrNameOrPhoneNumber(int id, String name, String phoneNumber) { System.out.println("ID " + id + "、名前 " + name + "、電話番号 " + phoneNumber + "の何れかに合致する友達は存在しません。"); } // 職業別にグループ化し好感度 90 以上の友達を検索 private static void findByProfession(List<MyFriends> myFriends, int favorabilityRating) { // Java9 Map<String, List<MyFriends>> myFriendsByProfession = myFriends.stream().collect( Collectors.groupingBy(MyFriends::getProfession, Collectors.filtering(e -> e.getFavorabilityRating() >= favorabilityRating, Collectors.toList()))); // // Java8 No Good!! // Map<String, List<MyFriends>> myFriendsByProfession // = myFriends.stream() // .filter(e -> e.getFavorabilityRating() >= favorabilityRating) // .collect( // Collectors.groupingBy(MyFriends::getProfession, // CollectorstoList())); // // Java8 // Map<String, List<MyFriends>> myFriendsByProfession // = myFriends.stream().collect( // Collectors.groupingBy(MyFriends::getProfession, // Collectors.collectingAndThen(Collectors.toList(), // e -> e.stream() // .filter(v -> v.getFavorabilityRating() >= favorabilityRating) // .collect(Collectors.toList())))); myFriendsByProfession.entrySet().forEach(es -> { if (es.getValue().isEmpty()) { System.out.println("Key= " + es.getKey() + ", 好感度 " + favorabilityRating + "以上の友達は存在しません。"); } es.getValue().forEach(v -> { System.out.println("Key= " + es.getKey() + ", Value = " + getMyFriendsInfo(v)); }); }); } private static String getMyFriendsInfo(MyFriends v) { return v.getId() + ": " + v.getName() + ", " + v.getAge() + "歳" + ", Gender: " + v.getGender() + ", 電話番号: " + v.getPhoneNumber() + ", 職業: " + v.getProfession() + ", 出身地: " + v.getBirthplace() + ", 好感度: " + v.getFavorabilityRating() + ", 趣味: " + v.getHobby(); } // 出身地別にグループ化して友達の名前を検索 Java8 で問題なしのケース private static void findByBirthplace(List<MyFriends> myFriends) { Map<String, Set<String>> myFriendsByBirthplace = myFriends.stream() .collect( Collectors.groupingBy(MyFriends::getBirthplace, Collectors.mapping(MyFriends::getName, Collectors.toSet()))); myFriendsByBirthplace.entrySet().forEach(es -> { if (es.getValue().isEmpty()) { System.out.println("Key= " + es.getKey() + " の友達は存在しません。"); } System.out.println("Key= " + es.getKey() + ", Value = " + es.getValue()); }); } // 職業別にグループ化し趣味を検索 Java9 でスマートになる private static void findByHobbyByProfession(List<MyFriends> myFriends) { Map<String, Set<String>> myFriendsByHobbyByProfession = myFriends.stream() .collect( Collectors.groupingBy(MyFriends::getProfession, // Collectors.mapping(MyFriends::getHobby, Collectors.toSet()))); // Map<String, Set<List<String>>> Java8 Collectors.flatMapping(e -> e.getHobby().stream(), Collectors.toSet()))); myFriendsByHobbyByProfession.entrySet().forEach(es -> { if (es.getValue().isEmpty()) { System.out.println("Key= " + es.getKey() + " の趣味はありません。"); } System.out.println("Key= " + es.getKey() + ", Value = " + es.getValue()); }); } // 年齢が若い順に友達を表示 private static void findByYoungOrder(List<MyFriends> myFriends) { myFriends.stream() .sorted(Comparator.comparing(MyFriends::getAge)) .forEach(MyFriends::printMyFriends); } // 年齢が若い順に好感度が70未満の友達がヒットするまで検索 private static void findByYoungFriendsByFavorabilityRating(List<MyFriends> myFriends, int favorabilityRating) { myFriends.stream() .sorted(Comparator.comparing(MyFriends::getAge)) .takeWhile(e -> e.getFavorabilityRating() >= favorabilityRating) .forEach(MyFriends::printMyFriends); } // 年齢が大きい順に好感度が90未満の友達がヒットするまでスキップして検索 private static void findByOldFriendsByFavorabilityRating(List<MyFriends> myFriends, int favorabilityRating) { myFriends.stream() .sorted(Comparator.comparing(MyFriends::getAge).reversed()) .dropWhile(e -> e.getFavorabilityRating() < favorabilityRating) .forEach(MyFriends::printMyFriends); } // 条件付きで年齢が若い順に友達を表示 27歳以下スキップ、34歳まで リミット private static void findByConditionalYoungOrder(List<MyFriends> myFriends, int skip, int limit) { myFriends.stream() .sorted(Comparator.comparing(MyFriends::getAge)) .dropWhile(e -> e.getAge() <= skip) .takeWhile(e -> e.getAge() <= limit) .forEach(MyFriends::printMyFriends); } // ID 1 から Double Calculation で計算して友達を検索 ただし、ID は 50 未満の範囲とする。(実質 32 まで) private static void findByIdDoubleCalculation(List<MyFriends> myFriends, int id) { IntStream.iterate(1, i -> i <= id, i -> i *= 2).forEach(i -> { findById(i, myFriends); }); } } |
static <E> List<E> of()
Returns an immutable list containing zero elements. See Immutable List Static Factory Methods for details.
Type Parameters:
E – the List’s element type
Returns:
an empty List
public Stream<T> stream()
If a value is present, returns a sequential Stream containing only that value, otherwise returns an empty Stream.
API Note:
This method can be used to transform a Stream of optional elements to a Stream of present value elements:
Stream<Optional<T>> os = ..
Stream<T> s = os.flatMap(Optional::stream)
Returns:
the optional value as a Stream
static <T> Stream<T> ofNullable(T t)
Returns a sequential Stream containing a single element, if non-null, otherwise returns an empty Stream.
Type Parameters:
T – the type of stream elements
Parameters:
t – the single element
Returns:
a stream with a single element if the specified element is non-null, otherwise an empty stream
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
If a value is present, performs the given action with the value, otherwise performs the given empty-based action.
Parameters:
action – the action to be performed, if a value is presentemptyAction – the empty-based action to be performed, if no value is present
Throws:
NullPointerException – if a value is present and the given action is null, or no value is present and the given empty-based action is null.
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)
If a value is present, returns an Optional describing the value, otherwise returns an Optional produced by the supplying function.
Parameters:
supplier – the supplying function that produces an Optional to be returned
Returns:
returns an Optional describing the value of this Optional, if a value is present, otherwise an Optional produced by the supplying function.
Throws:
NullPointerException – if the supplying function is null or produces a null result
public static <T,A,R> Collector<T,?,R> filtering(Predicate<? super T> predicate, Collector<? super T,A,R> downstream)
Adapts a Collector to one accepting elements of the same type T by applying the predicate to each input element and only accumulating if the predicate returns true.
API Note:
The filtering() collectors are most useful when used in a multi-level reduction, such as downstream of a groupingBy or partitioningBy. For example, given a stream of Employee, to accumulate the employees in each department that have a salary above a certain threshold:
Map<Department, Set<Employee>> wellPaidEmployeesByDepartment
= employees.stream().collect(
groupingBy(Employee::getDepartment,
filtering(e -> e.getSalary() > 2000,
toSet())));
A filtering collector differs from a stream’s filter() operation. In this example, suppose there are no employees whose salary is above the threshold in some department. Using a filtering collector as shown above would result in a mapping from that department to an empty Set. If a stream filter() operation were done instead, there would be no mapping for that department at all.
Type Parameters:
T – the type of the input elements
A – intermediate accumulation type of the downstream collector
R – result type of collector
Parameters:
predicate – a predicate to be applied to the input elements
downstream – a collector which will accept values that match the predicate
Returns:
a collector which applies the predicate to the input elements and provides matching elements to the downstream collector
public static <T,U,A,R> Collector<T,?,R> flatMapping(Function<? super T,? extends Stream<? extends U>> mapper, Collector<? super U,A,R> downstream)
Adapts a Collector accepting elements of type U to one accepting elements of type T by applying a flat mapping function to each input element before accumulation. The flat mapping function maps an input element to a stream covering zero or more output elements that are then accumulated downstream. Each mapped stream is closed after its contents have been placed downstream. (If a mapped stream is null an empty stream is used, instead.)
API Note:
The flatMapping() collectors are most useful when used in a multi-level reduction, such as downstream of a groupingBy or partitioningBy. For example, given a stream of Order, to accumulate the set of line items for each customer:
Map<String, Set<LineItem>> itemsByCustomerName
= orders.stream().collect(
groupingBy(Order::getCustomerName,
flatMapping(order -> order.getLineItems().stream(),
toSet())));
Type Parameters:
T – the type of the input elements
U – type of elements accepted by downstream collector
A – intermediate accumulation type of the downstream collector
R – result type of collector
Parameters:
mapper – a function to be applied to the input elements, which returns a stream of results
downstream – a collector which will receive the elements of the stream returned by mapper
Returns:
a collector which applies the mapping function to the input elements and provides the flat mapped results to the downstream collector
default Stream<T> takeWhile(Predicate<? super T> predicate)
Returns, if this stream is ordered, a stream consisting of the longest prefix of elements taken from this stream that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of a subset of elements taken from this stream that match the given predicate.
If this stream is ordered then the longest prefix is a contiguous sequence of elements of this stream that match the given predicate. The first element of the sequence is the first element of this stream, and the element immediately following the last element of the sequence does not match the given predicate.
If this stream is unordered, and some (but not all) elements of this stream match the given predicate, then the behavior of this operation is nondeterministic; it is free to take any subset of matching elements (which includes the empty set).
Independent of whether this stream is ordered or unordered if all elements of this stream match the given predicate then this operation takes all elements (the result is the same as the input), or if no elements of the stream match the given predicate then no elements are taken (the result is an empty stream).
This is a short-circuiting stateful intermediate operation.
API Note:
While takeWhile() is generally a cheap operation on sequential stream pipelines, it can be quite expensive on ordered parallel pipelines, since the operation is constrained to return not just any valid prefix, but the longest prefix of elements in the encounter order. Using an unordered stream source (such as generate(Supplier)) or removing the ordering constraint with BaseStream.unordered() may result in significant speedups of takeWhile() in parallel pipelines, if the semantics of your situation permit. If consistency with encounter order is required, and you are experiencing poor performance or memory utilization with takeWhile() in parallel pipelines, switching to sequential execution with BaseStream.sequential() may improve performance.
Implementation Requirements:
The default implementation obtains the spliterator of this stream, wraps that spliterator so as to support the semantics of this operation on traversal, and returns a new stream associated with the wrapped spliterator. The returned stream preserves the execution characteristics of this stream (namely parallel or sequential execution as per BaseStream.isParallel()) but the wrapped spliterator may choose to not support splitting. When the returned stream is closed, the close handlers for both the returned and this stream are invoked.
Parameters:
predicate – a non-interfering, stateless predicate to apply to elements to determine the longest prefix of elements.
Returns:
the new stream
default Stream<T> dropWhile(Predicate<? super T> predicate)
Returns, if this stream is ordered, a stream consisting of the remaining elements of this stream after dropping the longest prefix of elements that match the given predicate. Otherwise returns, if this stream is unordered, a stream consisting of the remaining elements of this stream after dropping a subset of elements that match the given predicate.
If this stream is ordered then the longest prefix is a contiguous sequence of elements of this stream that match the given predicate. The first element of the sequence is the first element of this stream, and the element immediately following the last element of the sequence does not match the given predicate.
If this stream is unordered, and some (but not all) elements of this stream match the given predicate, then the behavior of this operation is nondeterministic; it is free to drop any subset of matching elements (which includes the empty set).
Independent of whether this stream is ordered or unordered if all elements of this stream match the given predicate then this operation drops all elements (the result is an empty stream), or if no elements of the stream match the given predicate then no elements are dropped (the result is the same as the input).
This is a stateful intermediate operation.
API Note:
While dropWhile() is generally a cheap operation on sequential stream pipelines, it can be quite expensive on ordered parallel pipelines, since the operation is constrained to return not just any valid prefix, but the longest prefix of elements in the encounter order. Using an unordered stream source (such as generate(Supplier)) or removing the ordering constraint with BaseStream.unordered() may result in significant speedups of dropWhile() in parallel pipelines, if the semantics of your situation permit. If consistency with encounter order is required, and you are experiencing poor performance or memory utilization with dropWhile() in parallel pipelines, switching to sequential execution with BaseStream.sequential() may improve performance.
Implementation Requirements:
The default implementation obtains the spliterator of this stream, wraps that spliterator so as to support the semantics of this operation on traversal, and returns a new stream associated with the wrapped spliterator. The returned stream preserves the execution characteristics of this stream (namely parallel or sequential execution as per BaseStream.isParallel()) but the wrapped spliterator may choose to not support splitting. When the returned stream is closed, the close handlers for both the returned and this stream are invoked.
Parameters:
predicate – a non-interfering, stateless predicate to apply to elements to determine the longest prefix of elements.
Returns:
the new stream
static IntStream iterate(int seed, IntPredicate hasNext, IntUnaryOperator next)
Returns a sequential ordered IntStream produced by iterative application of the given next function to an initial element, conditioned on satisfying the given hasNext predicate. The stream terminates as soon as the hasNext predicate returns false.
IntStream.iterate should produce the same sequence of elements as produced by the corresponding for-loop:
for (int index=seed; hasNext.test(index); index = next.applyAsInt(index)) {
…
}
The resulting sequence may be empty if the hasNext predicate does not hold on the seed value. Otherwise the first element will be the supplied seed value, the next element (if present) will be the result of applying the next function to the seed value, and so on iteratively until the hasNext predicate indicates that the stream should terminate.
The action of applying the hasNext predicate to an element happens-before the action of applying the next function to that element. The action of applying the next function for one element happens-before the action of applying the hasNext predicate for subsequent elements. For any given element an action may be performed in whatever thread the library chooses.
Parameters:
seed – the initial element
hasNext – a predicate to apply to elements to determine when the stream must terminate.
next – a function to be applied to the previous element to produce a new element
Returns:
a new sequential IntStream
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
Returns a sequential ordered Stream produced by iterative application of the given next function to an initial element, conditioned on satisfying the given hasNext predicate. The stream terminates as soon as the hasNext predicate returns false.
Stream.iterate should produce the same sequence of elements as produced by the corresponding for-loop:
for (T index=seed; hasNext.test(index); index = next.apply(index)) {
…
}
The resulting sequence may be empty if the hasNext predicate does not hold on the seed value. Otherwise the first element will be the supplied seed value, the next element (if present) will be the result of applying the next function to the seed value, and so on iteratively until the hasNext predicate indicates that the stream should terminate.
The action of applying the hasNext predicate to an element happens-before the action of applying the next function to that element. The action of applying the next function for one element happens-before the action of applying the hasNext predicate for subsequent elements. For any given element an action may be performed in whatever thread the library chooses.
Type Parameters:
T – the type of stream elements
Parameters:
seed – the initial element
hasNext – a predicate to apply to elements to determine when the stream must terminate.
next – a function to be applied to the previous element to produce a new element
Returns:
a new sequential Stream
API ドキュメントが英語しかないのが残念(>_<)
正式リリースされる頃には日本語版が出ることを祈ろう!
Java SE 8 からの痒いところに手が届いたようなアップデートだけどかなり便利になる。
なぜ初めからこうしなかったんだろうと思うほどに。
でも zip, pair はまだ無いまま・・・
Java SE 10 まで待つことになるのか必要ないと判断されたのか?
他にもいろいろ細かいところが良くなっているようだから正式リリースが楽しみですね!
TAGS: Java | 2017年2月18日9:48 PM
Comment
ゆっちのBlog » Java SE 9 の予習 その2 ゆっちのBlog » Java SE 9 の予習 その5
Trackback
2017年2月28日4:03 PM(編集)
[…] Java SE 9 の予習 […]
2017年6月29日11:47 AM(編集)
[…] Java SE 9 の予習 […]
Trackback URL