Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Lightweight-Stream-APIのあるAndroidアプリ開発

operandoOS
November 09, 2016

 Lightweight-Stream-APIのあるAndroidアプリ開発

operandoOS

November 09, 2016
Tweet

More Decks by operandoOS

Other Decks in Technology

Transcript

  1. Lightweight-Stream-API
    ͷ͋ΔAndroidΞϓϦ։ൃ
    ୈ1ճελʔτΞοϓAndroidษڧձ

    View Slide

  2. About Me
    Shinobu Okano
    @operandoOS
    Mercari, Inc.
    Souzoh, Inc.

    View Slide

  3. View Slide

  4. Lightweight-Stream-API?
    "Stream API from Java 8 rewritten
    on iterators for Java 7 and below."
    https://github.com/aNNiMON/Lightweight-Stream-API

    View Slide

  5. Lightweight-Stream-API?
    AndroidͰ΋࢖͑Δʂʂ

    View Slide

  6. Lightweight-Stream-API?
    Ϡλʔ

    View Slide

  7. Lightweight-Stream-API Includes
    • Functional interfaces
    • Stream/IntStream
    • Optional class
    • Exceptional class
    • Objects from Java 7

    View Slide

  8. Stream͚ͩ͡Όͳ͍Μ΍Ͱʔʂʂ
    Lightweight-Stream-API Includes

    View Slide

  9. ͪͳΈʹ...
    • Lightweight-Stream-API໊ͬͯલ͕௕͍...
    • LSAͬͯ༁ͬ͢Ά͍
    • READMEʹLSAͬͯهड़͕͋ͬͨ
    • ࢿྉͳ͍ͰLSAͱॻ͍ͯ͋Δͷ͸

    Lightweight-Stream-APIͱ͍͏ҙຯͰ͢

    View Slide

  10. Stream

    View Slide

  11. Stream?
    Java 8Ͱಋೖ͞ΕͨAPI

    View Slide

  12. Stream?
    "A sequence of elements
    supporting sequential and
    parallel aggregate operations."

    View Slide

  13. Stream(ਖ਼͘͠͸ͳ͍͚Ͳࡶʹ...)
    ܁Γฦ͠ॲཧͷfor΍whileΛStreamʹͯ͠
    ύΠϓϥΠϯతʹॲཧ͢Δ

    View Slide

  14. Lightweight-Stream-API
    • "without parallel processing but with a variety
    of additional methods and with custom
    operators"
    • parallel͸ఏڙ͞Ε͍ͯͳ͍

    View Slide

  15. Lightweight-Stream-API ≠ Java 8 Stream
    • ΠίʔϧͰ͸ͳ͍
    • Java 8 Stream APIͷΑ͏ͳΠϯλʔϑΣΠε
    ΋ͬͨ΋ͷ

    View Slide

  16. StreamͷྲྀΕ
    • Streamͷੜ੒
    • தؒૢ࡞ (map,filter,etc.)
    • ͋ΔετϦʔϜΛผͷετϦʔϜʹม׵͢Δૢ࡞
    • ऴ୺ૢ࡞ (forEach,count,collect,etc.)
    • ݁Ռ·ͨ͸෭࡞༻Λੜ੒͢Δૢ࡞

    View Slide

  17. Java 8 Stream
    • είΞͷList͔Β30఺Ҏ্ͷ΋ͷΛදࣔ͢Δ
    • Java 8ͷCollectionʹStreamʹม׵͢Δϝιου͕͋Δ
    List scores = Arrays.asList(100, 30, 35, 20);
    scores.stream() // Streamͷੜ੒
    .filter(score -> score >= 30) // தؒૢ࡞
    .forEach(System.out::println); // ऴ୺ૢ࡞

    View Slide

  18. for
    • είΞͷList͔Β30఺Ҏ্ͷ΋ͷΛදࣔ͢Δ
    for (Integer score : scores) {
    if (score >= 30) {
    System.out.println(score);
    }
    }

    View Slide

  19. Java 8 Parallel Stream
    • parallelStream()Ͱฒྻॲཧ
    • ฒྻͰॲཧ͢ΔͷͰ݁Ռͷॱ൪͸มΘΔՄೳੑ͕͋Δ
    List scores = Arrays.asList(100, 30, 35, 20);
    scores.parallelStream()
    .filter(score -> score >= 30)
    .forEach(System.out::println);

    View Slide

  20. Lightweight-Stream-API
    • είΞͷList͔Β30఺Ҏ্ͷ΋ͷΛදࣔ͢Δ
    • Stream.ofͰStreamΛ࡞Δ
    List scores = Arrays.asList(100, 30, 35, 20);
    Stream.of(scores) // Streamͷੜ੒
    .filter(score -> score >= 30) // தؒૢ࡞
    .forEach(System.out::println); // ऴ୺ૢ࡞

    View Slide

  21. ग़ྗ͡Όͳͯ͘Listʹ͍ͨ͠ʂ(Lightweight-Stream-API)
    • ऴ୺ૢ࡞Λcollectʹ͢Δ͚ͩͳͷͰ؆୯ʂ
    List scores = Arrays.asList(100, 30, 35, 20);
    List filteredScores = Stream.of(scores)
    .filter(score -> score >= 30)
    .collect(Collectors.toCollection(ArrayList::new));

    View Slide

  22. தؒૢ࡞ɺऴ୺ૢ࡞ͷϝιου͸৭ʑ͋Δ!
    • શ෦આ໌Ͱ͖ͳ͍ͷͰɺjavadocͱ͔Έͯࢼͯ͠Ͷʂ
    • େମ΄͍͠ͱࢥ͏ػೳ͸ἧͬͯΔ͸ͣ
    • Stream - Lightweight-Stream-API javadoc
    • http://static.javadoc.io/com.annimon/stream/
    1.1.3/com/annimon/stream/Stream.html

    View Slide

  23. Lightweight-Stream-API
    • AndroidͰJava 8ͷStreamͬΆ͍΋ͷ͕࢖͑Δʂ
    • தؒૢ࡞ͱऴ୺ૢ࡞͸ಉ͡Ͱॻ͚Δ
    • ྲྀΕΔΑ͏ʹॲཧΛॻ͚ΔͷͰؾ͍͍࣋ͪ!
    • Javaྗ UP
    • Java 9ͰStreamʹ௥Ճ͞ΕΔfunction΋࢖͑Δ!
    • good-bye for??

    View Slide

  24. Optional

    View Slide

  25. Optional?
    "A container object which may or
    may not contain a non-null value."

    View Slide

  26. Optional?(ࡶ)
    ஋Λϥοϓͯ͠null͔΋͠Εͳ͍
    ͜ͱΛදݱ͢ΔΫϥε

    View Slide

  27. good-bye NullPointerException?
    NO

    View Slide

  28. Optional - Java 8
    Optional optional = OptionalΛฦ͢ϝιου();
    // nullͰͳ͚Ε͹දࣔ͞ΕΔ
    optional.ifPresent(System.out::println);

    View Slide

  29. Optional - Lightweight-Stream-API
    Optional optional = OptionalΛฦ͢ϝιου();
    // nullͰͳ͚Ε͹දࣔ͞ΕΔ
    optional.ifPresent(System.out::println);

    View Slide

  30. ಉ͡΍☺

    View Slide

  31. Optional + Android
    • Android SDKͷAPIͬͯࢥͬͨҎ্ʹnullΛฦ͢΋ͷ͕ଟ͍
    • υΩϡϝϯτಡΜͰʮ͑?nullฦΔͷ?ʯͱ஌Δ΋ͷ΋౓ʑ
    • FragmentͶʔgetContextͱ͔getActivityͱ͔…
    • ίʔυϨϏϡʔͰ͔ͭͬͭΕͨ͘ͳ͍…
    • Fragment#getResources΋mHost͕nullͩͱ
    IllegalStateException

    View Slide

  32. Fragment#getContext()
    "Return the Context this fragment is
    currently associated with."
    https://developer.android.com/reference/android/support/v4/app/Fragment.html#getContext()

    View Slide

  33. Fragment#getContext()
    • nullฦΔ΍Μ
    public Context getContext() {
    return mHost == null ? null : mHost.getContext();
    }

    View Slide

  34. Fragment + Optional
    public static Optional getOptionalContext(Fragment fragment) {
    if (fragment.isDetached()) {
    return Optional.empty();
    }
    return Optional.ofNullable(fragment.getContext());
    }
    // ҆શ!
    FragmentUtil.getOptionalContext(this)
    .ifPresent(context -> {
    Toast.makeText(context, "Optional", Toast.LENGTH_SHORT).show();
    });

    View Slide

  35. Fragment + Optional
    public static Optional
    getOptionalFragmentActivity(Fragment fragment) {
    if (fragment.isDetached()) {
    return Optional.empty();
    }
    return Optional.ofNullable(fragment.getActivity());
    }
    // menuͷߋ৽
    // ҆શ!
    FragmentUtil.getOptionalFragmentActivity(this)
    .ifPresent(FragmentActivity::supportInvalidateOptionsMenu);

    View Slide

  36. Fragment + Optional
    public static Optional getArguments(Fragment fragment) {
    return Optional.ofNullable(fragment.getArguments());
    }
    // ҆શ!
    FragmentUtil.getArguments(this)
    .ifPresent(bundle -> {
    // bundle͔Β஋ΛऔΓग़͢
    });

    View Slide

  37. ෳ਺ͷOptionalΛѻ͏
    • Optional AͱOptional Bͷ྆ํ͕nullͰͳ͚Ε͹...Έ͍ͨͳύλʔϯ
    • ͦ΋ͦ΋͜ΕͰਖ਼͍͠ͷ͔Θ͔Βͳ͍...
    Optional optionalFragmentActivity =
    FragmentUtil.getOptionalFragmentActivity(this);
    Optional titleOptional = titleOptional();
    optionalFragmentActivity.ifPresent(fragmentActivity -> {
    titleOptional.ifPresent(title -> {
    fragmentActivity.setTitle(title);
    });
    });

    View Slide

  38. ෳ਺ͷOptionalΛѻ͏
    • 2ͭͷOptionalʹ஋͕ೖ͍ͬͯΕ͹

    TupleΛOptionalͰϥοϓͯ͠ฦ͢
    • ͜ΕͳΒͲ͏ͩ

    View Slide

  39. ෳ਺ͷOptionalΛѻ͏
    public static Optional> flatMapPair(Optional a, Optional b) {
    if (a.isPresent() && b.isPresent()) {
    // 2ͭͷOptionalʹ஋͕ೖ͍ͬͯΕ͹TupleΛOptionalͰϥοϓͯ͠ฦ͢
    return Optional.ofNullable(Pair.create(a.get(), b.get()));
    } else {
    // ͦ͏Ͱͳ͍ͳΒempty
    return Optional.empty();
    }
    }
    OptionalUtil.flatMapPair(optionalFragmentActivity,titleOptional)
    .ifPresent(pair -> {
    pair.getFirst()setTitle(pair.getSecond());
    });

    View Slide

  40. ෳ਺ͷOptionalΛѻ͏
    public static Optional>
    flatMapTriplet(Optional a,
    Optional b,
    Optional c) {
    if (a.isPresent() && b.isPresent() && c.isPresent()) {
    return Optional.ofNullable(
    Triplet.create(a.get(), b.get(), c.get()));
    } else {
    return Optional.empty();
    }
    }

    View Slide

  41. View Slide

  42. Ͱ΋
    JavaʹTupleͳ͍΍Μ...

    View Slide

  43. Guild

    • Simple java tuples.
    • https://github.com/operando/Guild

    View Slide

  44. LSAͷOptionalʹ͔͠ͳ͍ศརͳϝιου
    • Optional.stream()
    • Optional͔ΒStreamʹม׵Ͱ͖Δ
    • ଞʹ΋͍͔ͭ͋͘Δ…
    Optional.ofNullable(integers)
    .stream()
    .forEach(System.out::println);

    View Slide

  45. Java 8Ͱಉ͜͡ͱΛ͢Δͱ
    • Ұखؒඞཁ
    Optional.ofNullable(integers)
    .map(integers1 -> integers1.stream())
    .orElse(Stream.empty())
    .forEach(System.out::println);

    View Slide

  46. Optionalʹ΋தؒૢ࡞ɺऴ୺ૢ࡞తͳͷ͕͋Δ
    • தؒૢ࡞?తͳͷ
    • map,flagMap,filter,etc…
    • ऴ୺ૢ࡞?తͳͷ
    • ifPresent,orElse,etc…
    • Optional javadoc - Lightweight-Stream-API
    • http://static.javadoc.io/com.annimon/stream/1.1.3/com/
    annimon/stream/Optional.html

    View Slide

  47. Optional
    • AndroidͰJava 8ͷOptionalͱಉ͡Α͏ͳ΋ͷ͕࢖͑Δ
    • Javaྗ UP
    • ifͰnullνΣοΫ͢ΔΑΓࣗવͳײ͡ͰϓϩάϥϜ͕ॻ͚Δ
    • null͕ͳ͘ͳΔΘ͚Ͱ͸ͳ͍
    • ѻ͍͕೉͍͜͠ͱ΋͋Δ
    • Optionalͷϥοϓͯ͠Δ஋͕nullͩͬͨ࣌ͷॲཧΛ๨ΕΔͱ͔...

    View Slide

  48. Objects

    View Slide

  49. Objects΋͍͍ͧʂ
    • Java 7͔Β௥Ճ͞ΕͨAPI
    • AndroidͰ͸minSdkVersion 19Ҏ্͡Όͳ͍
    ͱJava 7ͷAPI͸࢖͑ͳ͍͸ͣ

    View Slide

  50. Objects΋͍͍ͧʂ
    • ̎ͭͷจࣈྻΛൺֱ͍ͨ͠
    String s1 = Stringฦ͢ϝιου();
    String s2 = Stringฦ͢ϝιου();
    // s1͸null͔΋͠Εͳ͍...
    s1.equals(s2);
    // Objects - Lightweight-Stream-API
    // ͲͪΒ͔͕nullͰ΋҆શ!
    Objects.equals(s1,s2);

    View Slide

  51. Andorid N minSdkVersion 24
    • Java 8ͷAPI͕͍͔ͭ͘ೖͬͯΔ
    • StreamͱOptional͸ೖͬͯΔ
    • ଞʹ΋͍͔ͭ͘…
    • Lightweight-Stream-API࢖Θͳͯ͘΋Α͍
    • minSdkVersion 24...Կ೥ઌ?

    View Slide

  52. Android-Java-8-Stream-Example
    • Lightweight-Stream-APIͷ࡞ऀ͕AndroidͰ
    Java 8ͬΆ͘ॻ͘αϯϓϧΛॻ͍ͯΔ
    • https://github.com/aNNiMON/Android-
    Java-8-Stream-Example

    View Slide

  53. ·ͱΊ
    • Lightweight-Stream-APIΛ࢖͑͹

    AndroidͰ΋StreamͬΆ͍΋ͷͱOptional͕࢖͑Δ
    • Javaྗ UPʹͭͳ͕Δ
    • Android։ൃͷJavaͩͱJava 6,7Ͱٕज़͕ࢭ·ͬͯ͠·͏Մೳੑ΋…
    • ๻ͱҰॹʹ։ൃ͢Δਓʹ͸Javaͷྗ΋͚ͭͯ΄͍͠
    • Java 9΋དྷ೥ग़ΔͷͰJavaࣗମʹؔ৺Λʂ

    View Slide

  54. Links
    • Lightweight-Stream-API version 1.1.3 javadoc
    • http://static.javadoc.io/com.annimon/stream/1.1.3/overview-summary.html
    • Stream - Java 8
    • https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html
    • Java 8 Stream Tutorial
    • http://winterbe.com/posts/2014/07/31/java8-stream-tutorial-examples/
    • Optional - Java 8
    • https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
    • OptionalͷऔΓѻ͍͔ͨ
    • http://irof.hateblo.jp/entry/2015/05/05/071450

    View Slide

  55. Thanks

    View Slide