Record some significant JDK1.8 operations
Lambda
anonymous inner class
Comparator<Integer> comparator1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
Comparator<Integer> comparator2 = (o1, o2) -> {
return Integer.compare(o1,o2);
};
Comparator<Integer> comparator3 = Integer::compare;
Method Reference
There are three ways to use method reference:
[object]::[normal method name] [class]::[static method name] [class]::[normal method name]
Object::method
public static void main(String[] args) {
Consumer<Integer> consumer = (x) -> System.out.println(x);
consumer.accept(100);
PrintStream ps = System.out;
Consumer<Integer> consumer2 = ps::println;
consumer2.accept(200);
Consumer<Integer> consumer3 = System.out::println;
consumer2.accept(200);
}
public static void main(String[] args) {
User user = new User();
Supplier<String> supplier1 = user::getName;
System.out.println(supplier1.get());
}
static class User{
private String name = "aaa";
private Integer age = 10;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
class::static method
Comparator<Integer> comparator3 = Integer::compare;
class::application method
public static void main(String[] args) {
BiPredicate<String, String> biPredicate = (x,y)->x.equals(y);
System.out.println(biPredicate.test("cyt", "cyt"));
BiPredicate<String, String> biPredicate2 = String::equals;
System.out.println(biPredicate2.test("cyt", "cyt666"));
}
the principle of this kind of way is that:
x is the caller of the method, y is the callee (info by the video, but not my prospective)
constructor reference
public class Test {
public static void main(String[] args) {
Supplier<User> supplier = () -> new User();
System.out.println(supplier.get());
Supplier<User> supplier1 = User::new;
System.out.println(supplier1.get());
Function<Integer,User> function1 = User::new;
System.out.println(function1.apply(20));
BiFunction<String,Integer,User> function2 = User::new;
System.out.println(function2.apply("jinondo",20));
}
static class User{
private String name;
private Integer age;
public User(String name) {
this.name = name;
}
public User(Integer age) {
this.age = age;
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
Array Reference
Function<Integer,String[]> function1 = (x)->new String[x];
String[] array1 = function1.apply(10);
System.out.println(array1.length);
Function<Integer,String[]> function2 = String[]::new;
String[] array2 = function2.apply(20);
System.out.println(array2.length);
Stream
create stream
Four method to create a stream
public static void main(String[] args) {
List<String> list = new ArrayList<>();
Stream<String> stream1 = list.stream();
User[] users = new User[10];
Stream<User> stream2 = Arrays.stream(users);
Stream<String> stream3 = Stream.of("aa", "bb", "cc");
Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
stream4.limit(10).forEach(System.out::println);
Stream.generate(()-> Math.random())
.limit(5)
.forEach(System.out::println);
}
Filter
List<User> list = new ArrayList<User>(){{
add(new User("Curt",20));
add(new User("Cobain",30));
add(new User("Bryce",20));
add(new User("Lucy",40));
}};
Stream<User> userStream = list.stream().filter((x) -> {
System.out.println("Middle Operation...");
return x.age > 20;
});
userStream.forEach(System.out::println);
Limit & Skip
List<User> list = new ArrayList<User>(){{
add(new User("Curt",10));
add(new User("Cobain",30));
add(new User("Bryce",20));
add(new User("Lucy",40));
}};
list.stream().
filter(x-> x.age>10)
.limit(2)
.forEach(System.out::println);
short circuit
List<User> list = new ArrayList<User>(){{
add(new User("Curt",10));
add(new User("Cobain",30));
add(new User("Bryce",20));
add(new User("Lucy",40));
}};
list.stream().
filter(x-> {
System.out.println("short circuit");
return x.age>10;
})
.limit(2)
.forEach(System.out::println);
list.stream()
.skip(2)
.forEach(System.out::println);
Distinct
List<User> list = new ArrayList<User>(){{
add(new User("Curt",10));
add(new User("Cobain",20));
add(new User("Bryce",30));
add(new User("Lucy",40));
add(new User("Lucy",40));
add(new User("Lucy",40));
add(new User("Lucy",40));
}};
list.stream()
.distinct()
.forEach(System.out::println);
Map & FlatMap
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
List<User> users = new ArrayList<User>(){{
add(new User("Curt",10));
add(new User("Cobain",20));
add(new User("Bryce",30));
add(new User("Lucy",40));
}};
list.stream()
.map(str->str.toUpperCase())
.forEach(System.out::println);
users.stream()
.map(user->user.getName())
.forEach(System.out::println);
public class Test {
public static void main(String[] args) {
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
Stream<Stream<Character>> streamStream = list.stream().map(Test::filterCharacter);
streamStream.forEach(sm->{
sm.forEach(System.out::println);
});
}
public static Stream<Character> filterCharacter(String str){
List<Character> list = new ArrayList<>();
for (Character ch:str.toCharArray()){
list.add(ch);
}
return list.stream();
}
}
flatMap
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
Stream<Character> streamStream = list.stream().flatMap(Test::filterCharacter);
streamStream.forEach(System.out::println);
Extension of Flat Map
The difference between add and addAll
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
List list1 = new ArrayList(){{
add(11);
add(22);
}};
list1.add(list);
System.out.println(list1);
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
List list1 = new ArrayList(){{
add(11);
add(22);
}};
list1.addAll(list);
System.out.println(list1);
Sorted
List<User> users = new ArrayList<User>(){{
add(new User("Cobain",20));
add(new User("Curt",20));
add(new User("Bryce",30));
add(new User("Lucy",40));
}};
users.stream().sorted((user1,user2)->{
if (user1.age.equals(user2.age)){
return user1.name.compareTo(user2.name);
}
return user2.age - user1.age;
})
.forEach(System.out::println);
Or Default Sort
List<String> list = Arrays.asList("aaa","bbb","ccc","ddd");
list.stream().sorted()
.forEach(System.out::printl n);
Find & Match
public static void main(String[] args) {
List<User> users = new ArrayList<User>(){{
add(new User("Cobain",20));
add(new User("Curt",20));
add(new User("Bryce",30));
add(new User("Lucy",40));
}};
boolean isMatched = users.stream().allMatch(e -> e.getAge() > 20);
System.out.println(isMatched);
boolean isMatched2 = users.stream().anyMatch(e -> e.getAge() > 20);
System.out.println(isMatched2);
boolean isMatched3 = users.stream().noneMatch(e -> e.getAge() > 20);
System.out.println(isMatched3);
Optional<User> op = users.stream().sorted((x, y) -> Integer.compare(y.getAge(), x.getAge())).
findFirst();
System.out.println(op.orElse(null));
Optional<User> op2 = users.stream()
.filter(e -> e.getAge() > 20)
.findAny();
System.out.println(op2.get());
Optional<User> op3 = users.parallelStream()
.filter(e -> e.getAge() >= 20)
.findAny();
System.out.println(op3.get());
}
long count = users.stream().count();
System.out.println(count);
Optional<User> max = users.stream()
.max((x, y) -> Integer.compare(x.getAge(), y.getAge()));
System.out.println(max.get());
Optional<Integer> min = users.stream()
.map(User::getAge)
.min(Integer::compare);
System.out.println(min.get());
Reduce
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
List<User> users = new ArrayList<User>(){{
add(new User("Cobain",20));
add(new User("Curt",20));
add(new User("Bryce",30));
add(new User("Lucy",40));
}};
Integer sum = list.stream().reduce(0, (x, y) -> x + y);
System.out.println(sum);
Optional<Integer> op = users.stream()
.map(User::getAge)
.reduce(Integer::sum);
System.out.println(op.get());
Result
55
110
why the call of reduce can be an actual object or an Optional :
reduce(0, (x, y) -> x + y); have init the original value,
but reduce(Integer::sum); didn’t.
There is a design called map-reduce
Collect
collection
List<User> users = new ArrayList<User>() {{
add(new User("Cobain", 20));
add(new User("Curt", 20));
add(new User("Bryce", 30));
add(new User("Lucy", 40));
add(new User("Lucy", 40));
add(new User("Lucy", 40));
}};
List<String> list = users.stream()
.map(User::getName)
.collect(Collectors.toList());
list.forEach(System.out::println);
System.out.println("=====================");
Set<String> set = users.stream()
.map(User::getName)
.collect(Collectors.toSet());
set.forEach(System.out::println);
System.out.println("=====================");
HashSet<String> hashSet = users.stream()
.map(User::getName)
.collect(Collectors.toCollection(HashSet::new));
hashSet.forEach(System.out::println);
List<User> users = new ArrayList<User>() {{
add(new User("Cobain", 20));
add(new User("Curt", 20));
add(new User("Bryce", 30));
add(new User("Lucy", 40));
}};
Long count = users.stream()
.collect(Collectors.counting());
System.out.println(count);
Double avg = users.stream()
.collect(Collectors.averagingDouble(User::getAge));
System.out.println(avg);
Integer sum = users.stream().collect(Collectors.summingInt(User::getAge));
System.out.println(sum);
Optional<User> max = users.stream()
.collect(Collectors.maxBy((x, y) -> Integer.compare(x.getAge(), y.getAge())));
System.out.println(max.get());
Optional<Integer> min = users.stream()
.map(User::getAge)
.collect(Collectors.minBy(Integer::compare));
System.out.println(min.get());
group
static class User {
private String name;
private Integer age;
private String country;
}
List<User> users = new ArrayList<User>() {{
add(new User("Cobain", 20,"China"));
add(new User("Curt", 20,"England"));
add(new User("Bryce", 30,"China"));
add(new User("Lucy", 40,"America"));
}};
Map<Integer, List<User>> map = users.stream().
collect(Collectors.groupingBy(User::getAge));
System.out.println(map);
Map<String, Map<String, List<User>>> map2 = users.stream().
collect(Collectors.groupingBy(User::getCountry, Collectors.groupingBy((x) -> {
if (x.getAge() <= 20) {
return "Youth";
}
if (x.getAge() <= 30) {
return "Midlife";
}
return "Older";
})));
System.out.println(map2);
result
{20=[User{name='Cobain', age=20, country='China'}, User{name='Curt', age=20, country='England'}], 40=[User{name='Lucy', age=40, country='America'}], 30=[User{name='Bryce', age=30, country='China'}]}
{China={Midlife=[User{name='Bryce', age=30, country='China'}], Youth=[User{name='Cobain', age=20, country='China'}]}, America={Older=[User{name='Lucy', age=40, country='America'}]}, England={Youth=[User{name='Curt', age=20, country='England'}]}}
partition
Map<Boolean, List<User>> map = users.stream()
.collect(Collectors.partitioningBy(e -> e.getAge() > 20));
System.out.println(map);
result
{false=[User{name='Cobain', age=20, country='China'}, User{name='Curt', age=20, country='England'}], true=[User{name='Bryce', age=30, country='China'}, User{name='Lucy', age=40, country='America'}]}
statstic
DoubleSummaryStatistics dss = users.stream()
.collect(Collectors.summarizingDouble(User::getAge));
System.out.println(dss.getSum());
System.out.println(dss.getAverage());
System.out.println(dss.getMax());
System.out.println(dss.getCount());
System.out.println(dss.getMin());
join
List<User> users = new ArrayList<User>() {{
add(new User("Cobain", 20,"China"));
add(new User("Curt", 20,"England"));
add(new User("Bryce", 30,"China"));
add(new User("Lucy", 40,"America"));
}};
String str1 = users.stream()
.map(User::getName)
.collect(Collectors.joining("-"));
System.out.println(str1);
String str2 = users.stream()
.map(User::getName)
.collect(Collectors.joining(",","===","<<<"));
System.out.println(str2);
Parallel Stream
the underlying implementation of Parallel Stream is Fork/Join
package cyt.java.jdk8;
import java.util.concurrent.RecursiveTask;
public class ForkJoinCalculate extends RecursiveTask<Long> {
private long start;
private long end;
private static final long THRESHOLD = 10000;
public ForkJoinCalculate(long start, long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long length = end-start;
if (length<=THRESHOLD){
long sum = 0;
for (long i = start; i <= end; i++) {
sum += i;
}
return sum;
}
long middle = (start + end) / 2;
ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
left.fork();
ForkJoinCalculate right = new ForkJoinCalculate(middle+1, end);
right.fork();
return left.join() + right.join();
}
}
public static void main(String[] args) {
Instant start = Instant.now();
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinCalculate(0,10000000L);
Long sum = pool.invoke(task);
System.out.println(sum);
Instant end = Instant.now();
System.out.println("Time cost: " + Duration.between(start,end).toMillis());
}
When the amount of calculation is large, multi thread operation do works
Use Parallel Stream:
Instant start = Instant.now();
long sum = LongStream.rangeClosed(0, 10000000L)
.parallel()
.reduce(0, Long::sum);
System.out.println(sum);
Instant end = Instant.now();
System.out.println("Time cost: " + Duration.between(start,end).toMillis());
Optional
public static void main(String[] args) {
Optional<User> op = Optional.of(new User());
User user = op.get();
System.out.println(user);
Optional<Object> op2 = Optional.empty();
Optional<User> op3 = Optional.ofNullable(null);
if (op3.isPresent()){
System.out.println(op3.get());
}
User user1 = op3.orElse(new User("Curt", 20, "America"));
System.out.println(user1);
User user2 = op3.orElseGet(() -> {
return new User();
});
System.out.println(user2);
Optional<User> op4 = Optional.ofNullable(new User("Jinondo", 21, "China"));
Optional<String> str = op4.map((e) -> e.getName());
System.out.println(str.get());
Optional<String> str2 = op4.flatMap((e) -> Optional.of(e.getName()));
System.out.println(str2.get());
}
static class User {
private String name;
private Integer age;
private String country;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(name, user.name) &&
Objects.equals(age, user.age);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
public User(String name, Integer age, String country) {
this.name = name;
this.age = age;
this.country = country;
}
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", country='" + country + '\'' +
'}';
}
}
Date / Time Api
First, the new api is thread safe
DateTimeFormatter dtf = DateTimeFormatter.ISO_LOCAL_DATE;
Callable<LocalDate> task = () -> LocalDate.parse("2021-07-24",dtf);
ExecutorService pool = Executors.newFixedThreadPool(10);
List<Future<LocalDate>> result = new ArrayList<>();
for (int i = 0; i < 10; i++) {
result.add(pool.submit(task));
}
for (Future<LocalDate> future:result){
try {
System.out.println(future.get());
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
pool.shutdown();
LocalDateTime Example
LocalDateTime ldt1 = LocalDateTime.now();
System.out.println(ldt1);
LocalDateTime ldt2 = LocalDateTime.of(2021, 05, 17, 16, 24, 33);
System.out.println(ldt2);
LocalDateTime ldt3 = ldt2.plusYears(2);
System.out.println(ldt3);
LocalDateTime ldt4 = ldt2.minusMonths(3);
System.out.println(ldt4);
System.out.println(ldt2.getDayOfYear());
System.out.println(ldt2.getHour());
System.out.println(ldt2.getSecond());
Intsant
Instant ins1 = Instant.now();
System.out.println(ins1);
OffsetDateTime odt1 = ins1.atOffset(ZoneOffset.ofHours(8));
System.out.println(odt1);
long milli1 = ins1.toEpochMilli();
System.out.println(milli1);
Instant ins2 = Instant.ofEpochSecond(60);
System.out.println(ins2);
Duration / Period
Instant ins1 = Instant.now();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Instant ins2 = Instant.now();
Duration dura1 = Duration.between(ins1, ins2);
System.out.println(dura1.getSeconds());
System.out.println(dura1.toMillis());
LocalDate ld1 = LocalDate.of(2016, 9, 1);
LocalDate ld2 = LocalDate.now();
Period period = Period.between(ld1, ld2);
System.out.println(period.getYears());
System.out.println(period.toTotalMonths());
TemporalAdjusters
LocalDateTime ldt1 = LocalDateTime.now();
System.out.println(ldt1);
LocalDateTime ldt2 = ldt1.withDayOfMonth(10);
System.out.println(ldt2);
LocalDateTime ldt3 = ldt1.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
System.out.println(ldt3);
LocalDateTime ldt5 = ldt1.with((ta) -> {
LocalDateTime ldt4 = (LocalDateTime) ta;
DayOfWeek dow1 = ldt4.getDayOfWeek();
if (dow1.equals(DayOfWeek.FRIDAY)) {
return ldt4.plusDays(3);
} else if (dow1.equals(DayOfWeek.SATURDAY)) {
return ldt4.plusDays(2);
} else {
return ldt4.plusDays(1);
}
});
System.out.println(ldt5);
Format
DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE_TIME;
LocalDateTime ldt1 = LocalDateTime.now();
String str1 = ldt1.format(dtf1);
System.out.println(str1);
DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt2 = LocalDateTime.now();
String str2 = ldt2.format(dtf2);
System.out.println(str2);
LocalDateTime newDate = ldt1.parse(str1, dtf1);
System.out.println(newDate);
Timezone
Set<String> set = ZoneId.getAvailableZoneIds();
set.forEach(System.out::println);
LocalDateTime ldt1 = LocalDateTime.now(ZoneId.of("Europe/Tallinn"));
System.out.println(ldt1);
LocalDateTime ldt2 = LocalDateTime.now(ZoneId.of("Europe/Tallinn"));
ZonedDateTime zdt1 = ldt2.atZone(ZoneId.of("Europe/Tallinn"));
ZonedDateTime zdt2 = ldt2.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(zdt1);
System.out.println(zdt2);
Convert
Date date = new Date();
Instant instant = date.toInstant();
ZoneId zoneId = ZoneId.systemDefault();
LocalDateTime localDateTime = instant.atZone(zoneId).toLocalDateTime();
System.out.println(localDateTime);
LocalDateTime localDateTime2 = LocalDateTime.now();
ZoneId zoneId2 = ZoneId.systemDefault();
ZonedDateTime zdt = localDateTime2.atZone(zoneId2);
Date date2 = Date.from(zdt.toInstant());
System.out.println(date2);
@Repeatable
|