Wednesday, January 11, 2017

Java 8

Java 8的三大特性:Stream API, Optional API, 跟CompletableFuture稱為Java8三神器。
还会介绍apache commons的validate。

lambda

import java.util.stream.Collectors;

List<String> lines = Arrays.asList("spring", "node", "mkyong");

记得filter后要赋值
List<String> result = lines.stream() //convert list to stream
.filter(line -> !"mkyong". equals (line)) //filters the line, equals to "mkyong"
.collect(Collectors.toList()); //collect the output and convert streams to a List

result.forEach(System.out::println); //output : spring node

List<String> result;
result.forEach(x->func(x.getName()));

返回不是特定字符串的结果:
    String x = list.stream()
                   .filter(str->!StringUtils.equals(getSomething(str), "abc"))
                   .findAny()
                   .map(v -> getSomething(v))
                   .orElse(null);


map映射,可以将某一个类型的list转换成另一类型的list
List<Customer> customers = accounts.stream()
.filter(account -> account.getName()!="aaa")
.filter(account -> account.getAccountNumber()=="12")
.map(account ->{
Customer cust = new Customer();
cust.setCustomerId(Integer.parseInt(account.getAccountNumber()));
cust.setAddress(new Address("NEW", account.getName()));
return cust;
})
.collect(Collectors.toList());

字符串是否含有给定数组字符的一个:
Arrays.stream(items).parallel().anyMatch(inputStr::contains);

boolean ans = list.stream().anyMatch(n->n*(n+1))/4==5);

HashMap key排序
        Map<String, String> sortedMap = map.entrySet().stream() .sorted(Map.Entry.comparingByValue((String s1, String s2)-> s2.length() - s1.length())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new)); System.out.println("Sorted Map: " + Arrays.toString(sortedMap.entrySet().toArray()));

groupingBy统计数量

List<String> items =
                Arrays.asList("apple", "apple", "banana",
                        "apple", "orange", "banana", "papaya");

        Map<String, Long> result =
                items.stream().collect(
                        Collectors.groupingBy(
                                Function.identity(), Collectors.counting()
                        )
                );

Optonal

Optional的引入是为了解决null既可作为不存在或空结果的含糊性。有了Optional.isPresent的接口后,就可以让开发者意识到如何只处理空结果的情况,不用在考虑不存在情况。这个例子是找到第一个以L开头的字符串,若找到将其全大写输出。longest是一个Optional类型可以为空结果,若为空结果时,不会打印任何东西。

public void testOptional(){
Stream<String> names = Stream.of("aamurudu", "Okanbi", "Oduduwa");
Optional<String> longest = names
                               .filter(name -> name.startsWith("L"))
                               .findFirst();

longest.ifPresent(name -> {
           String s = name.toUpperCase();
           System.out.println("The longest name is "+ s);
       });
}

一般object变Optional:
Optional<Role> roleOpt = Optional.ofNullable(role); role可以为空,至于Optional.of("h")比如不为null。

Future

这个程序分成5个异步任务,等待5个任务(每个任务产生一个随机等待时间)全部完成后再输出完成信息。Future用于异步任务完成后执行主线程,它来保存异步任务结果,Future<Integer>参数类型就是返回类型。线程池设为10,以免线程不收回。tasks.add用了lambda表达式,类似于匿名类,简化程序。

public class AsyncTask {

public void asyncReturns() throws InterruptedException {
long startTime = System.currentTimeMillis();
ExecutorService executor = Executors.newFixedThreadPool(10);

List<Callable<Integer>> tasks = new ArrayList<>();

// Build parallel tasks
for (int i = 0; i < 5; i++) {
tasks.add(() -> getRandomByRange(waitTime));
}

// Execute all calls at the same time
List<Future<Integer>> futures = executor.invokeAll(tasks);

for (int i = 0; i < futures.size(); i++) {
try {
Future<Integer> future = futures.get(i);
Integer result = future.get();
System.out.println("task " + i + " takes " + result + " millisec");
} catch (ExecutionException e) {
e.printStackTrace();
}

}
executor.shutdown();
long endTime = System.currentTimeMillis();
System.out.println("done in "+(endTime-startTime)+" millisec");
}

public int getRandomByRange(int upper) throws InterruptedException {
int wait = new Random().nextInt(upper) * 1000;
Thread.sleep(wait);
return wait;
}

int waitTime = 5;

}

假设执行没有返回值的异步任务,一定要shutdown,作用是执行提交任务且终止线程池,否则一直等待。Future的意思就是未来会完成的结果。
ExecutorService executor = Executors.newFixedThreadPool(10);
executor.submit(()-> getRandomByRange2());
  executor.submit(()-> getRandomByRange2());
executor.shutdown();

Runnable的lambda表达式

原有:
Runnable task1 = new Runnable(){
     @Override
    public void run(){
        System.out.println("Task #1 is running");
    }
};
Thread thread1 = new Thread(task1);
thread1.start();

新的:
Runnable task2 = () -> { System.out.println("Task #2 is running"); };
new Thread(task2).start();

可见lambda表达式简化了很多。


lang3

lang3-> notNull: 查某个参数是否null,如果是出现exception:java.lang.NullPointerException: The validated object is null。但参数可以为空。

声明
test(@Nullable final String abc)

验证
notNull(para, "para must be not null");
isTrue(para>0, "para must be greater than 0")

检查一个Collection类型(ArrayList, HashSet)是否空(null或无元素)
CollectionUtils.isEmpty(mylist)
StringUtils.isEmpty("")

数组
asList固定大小不支持加删,但支持改。singletonList大小为1,不支持加删改
List<String> aList = Arrays.asList("a", "b");
List<String> bList = Collections.singletonList("a");

首字母大写
StringUtils.capitalized()

不可改变Map, Google Guava (Google Collections Library)
ImmutableSet<String> COLOR_NAMES = ImmutableSet.of("Red")
Map<String, String> COLOR_Map = ImmutableMap.of("1","Red")

类模板
 @Override
 public boolean equals(Object other)
 {
     return EqualsBuilder.reflectionEquals(this, other);
 }

  @Override
 public String toString()
 {
     return ToStringBuilder.reflectionToString(this);
 }

findFirst vs findAny
区别只在于多线程情况下,findFirst仍能保证返回data stream的第一个元素。


ref:
lambda
optional

No comments:

Post a Comment