Java8
for Android
at Kyobashi.dex #1
About me
Masaki Ogata
@ogaclejapan
Company
CyberAgent, inc.
と一緒に仕事してます :)
Java8
for Android
Java8
for Android
Java8のようなLibraries
for Android
・Lambda Expression
・Stream API
・Date and Time API
Lambda Expressions
( int x , int y ) -> x + y |
Retrolambda
Backport of Java 8's lambda expressions to Java 7, 6 and 5
Gradle Retrolambda Plugin
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'me.tatarka:gradle-retrolambda:3.2.2'
}
}
// Required because retrolambda is on maven central
repositories {
mavenCentral()
}
apply plugin: 'me.tatarka.retrolambda'
:)
Retrolambda Tips for Android
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lambda_tips);
/* 型は推論可能であれば省略可、引数は1つのみの場合に限り括弧も省略可 */
findViewById(R.id.button).setOnClickListener(v -> v.setEnabled(false));
/* return文は1行表示なら省略可 */
findViewById(R.id.button).setOnTouchListener((v, event) -> true);
/* 複数行の場合は{}括弧を省略できない */
new Thread(() -> {
// something
}).start();
/* メソッド参照もできる(staticのメソッド参照はClassName::method) */
new Thread(this::task).start();
}
void task() {
// something
}
キタ━━━( ´∀`)・ω・) ゚Д゚)・∀・) ̄ー ̄)´_ゝ`)━━━!!!?
Date and Time API
LocalDate.of( 2015 , 9 , 7 ).atTime( 20, 0 )
ThreeTenABP
https://github.com/JakeWharton/ThreeTenABP
An adaptation of the JSR-310 backport for Android.
ThreetenABP Tips for Android
public class MyApplication extends Application {
@Override public void onCreate() {
super.onCreate();
AndroidThreeTen.init(this);
}
}
/* 日付のみを扱う */
LocalDate d = LocalDate.of(2015, 9, 7);
/* 時間のみを扱う */
LocalTime t = LocalTime.of(20, 0);
/* 日付と時間を扱う */
LocalDateTime dt = LocalDateTime.of(d, t);
/* 秒、ナノ秒の期間を扱う */
Duration du = Duration.between(dt, dt.plusHours(2));
/* 年月日の期間を扱う */
Period p = Period.between(d.withYear(2014), d);
/* 経過時間を扱う */
Instant i = dt.toInstant(ZoneOffset.UTC);
/* 日付/時間の出力および解析を扱う */
String s = d.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
Awesome Sample code
∩゚∀゚∩age
Stream API
list.stream( ).map( s -> s.length( ) )
Lightweight Stream API
https://github.com/aNNiMON/Lightweight-Stream-API
Stream API from Java 8 rewrited on iterators for Java 7 and below.
Lightweight Stream API
Functional interfaces
Stream (without parallel processing)
Optional class
Objects from Java 7
Σ(`Д´ )
・Interface : 14 files
・Class : 5 files
Lightweight !!
.filter(Predicate<? super T> predicate)
.map(Function<? super T,? extends R> mapper)
.flatMap(Function<? super T,? extends Stream<? extends R>> mapper)
.distinct()
.sorted(Comparator<? super T> comparator)
.limit(long maxSize)
.skip(long n)
Supported Stream APIs
.peek(Consumer<? super T> action)
.forEach(Consumer<? super T> action)
.reduce(BiFunction<T, T, T> accmulator)
.min(Comparator<? super T> comparator)
.max(Comparator<? super T> comparator)
.allMatch(Predicate<? super T> predicate)
etc..
Supported Stream APIs
Stream Tips for Android
/* 初期値をStreamで作る */
final List<User> users = Stream.ofRange(1, 99)
.map(i -> new User("Name" + i, i))
.collect(Collectors.toList());
/* ResponseからUserリストをStreamに変形して10代のユーザのみを抽出した名前のリストを返す */
private List<String> getTeenagers(Response response) {
return Stream.of(response)
.flatMap(res -> Stream.of(res.users()))
.filter(user -> 12 < user.age && user.age < 20)
.sorted((user1, user2) -> Integer.compare(user1.age, user2.age))
.map(user -> user.name)
.collect(Collectors.toList());
}
public static class User {
public final String name;
public final int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
}
One more thing...
Optional<T>
A container object which may or may not contain a non-null value.
Optional Tips for Android
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_showcase);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
/* @NullableなメソッドにはOptionalで対抗する */
Optional.ofNullable(getActionBar()).ifPresent(ab -> {
ab.setTitle("Kyobashi.dex #1");
ab.setDisplayHomeAsUpEnabled(true);
});
}
private final WeakReference<KyobashiActivity> activityRef;
public void handle() {
Optional.ofNullable(activityRef.get())
.filter(act -> !act.isFinishing())
.ifPresent(KyobashiActivity::something);
}
Let's hava fun
:)