1. jdk1.7 Objects
- 替代 obj!=null?:obj:default 运算
Objects.requireNonNullElse("value1","defaultvalue"); // 返回value1
Objects.requireNonNullElse(null,"defaultvalue"); // 返回defaultvalue
- 判断对象空/非空
if(Objects.isNull(obj)){} // 判断对象为空
if(Objects.nonNull(obj)){} // 判断对象非空
- 检查为空则抛出 NullPointerException 异常
Objects.requireNonNull(obj)
2. 集合API
2.1 字符串集合拼接
List<String> list = Arrays.asList("aa", "bb", "cc");
String rs1 = list.stream().map(si -> {
return "'".concat(si).concat("'");
}).collect(Collectors.joining(",")); // 'aa','bb','cc'
String rs2 = list.stream().collect(Collectors.joining("','", "'","'")); // 'aa','bb','cc'
String rs3 = list.stream().collect(Collectors.joining(",", "'","'")); // 'aa,bb,cc'
String rs4 = String.join(",", list);// aa,bb,cc
String rs5 = new StringJoiner(",").add("aa").add("bb").add("cc").toString();// aa,bb,cc
2.2 commons-collections4: CollectionUtils
// 检查集合是否为空
CollectionUtils.isEmpty(Collection<?> coll)
// 检查集合是否为非空。
CollectionUtils.isNotEmpty(Collection<?> coll)
// 除非元素为null,否则向集合添加元素
CollectionUtils.addIgnoreNull(personList,null);
// 将两个已排序的集合a和b合并为一个已排序的列表,以便保留元素的自然顺序
CollectionUtils.collate(Iterable<? extends O> a, Iterable<? extends O> b)
// 将两个已排序的集合a和b合并到一个已排序的列表中,以便保留根据Comparator c的元素顺序。
CollectionUtils.collate(Iterable<? extends O> a, Iterable<? extends O> b, Comparator<? super O> c)
// 返回该个集合中是否含有至少有一个元素
CollectionUtils.containsAny(Collection<?> coll1, T... coll2)
// 如果参数是null,则返回不可变的空集合,否则返回参数本身。(很实用 ,最终返回List EMPTY_LIST = new EmptyList<>())
CollectionUtils.emptyIfNull(Collection<T> collection)
// 反转给定数组的顺序。
CollectionUtils.reverseArray(Object[] array);
// 差集
CollectionUtils.subtract(Iterable<? extends O> a, Iterable<? extends O> b)
// 并集
CollectionUtils.union(Iterable<? extends O> a, Iterable<? extends O> b)
// 交集
CollectionUtils.intersection(Collection a, Collection b)
// 交集的补集(析取)
CollectionUtils.disjunction(Collection a, Collection b)
2.3 guava : Lists
// 1. 创建集合
// guava-29.0-jre.jar
ArrayList<String> ss1 = Lists.newArrayList("aa","bb","cc");
// 以上代码等同于 jdk 的代码
List<String> ss2 = Arrays.asList("aa","bb","cc");
2.4 jdk8: Stream集合的流式操作
+--------------------+ +------+ +------+ +---+ +-------+
| stream of elements +-----> |filter+-> |sorted+-> |map+-> |collect|
+--------------------+ +------+ +------+ +---+ +-------+
比如:
List<Integer> transactionsIds =
widgets.stream()
.filter(b -> b.getColor() == RED)
.sorted((x,y) -> x.getWeight() - y.getWeight())
.mapToInt(Widget::getWeight)
.sum();
主要方法:
- forEach 循环数据 用到Comsumer
- map 遍历元素,并映射成一个新的集合
- filter 过滤元素,用到 Predicate
- limit(n) 只取前面的n个数据
- sorted 排序
- parallelStream 并行的流
Collectors实现了很多归约操作
- Collectors.toList() 转换为list
- Collectors.joining(", ") 拼接成字符串
示例:
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 2, 4);
// 排序,并循环输出前面2个数据
list.stream().sorted( Integer::compareTo ).limit(2).forEach(x -> System.out.println(x));
// 过滤大于1,再取平方,再连接成字符串
String rs = list.stream().filter(x -> x > 1).map(x -> String.valueOf(x * x)).collect(Collectors.joining(","));
System.out.println(rs); // 输出 9,4,16
}
3. jdk8: default 默认方法
- 在接口中定义的默认实现,如果子类没有覆盖本方法,则默认继承该@default实现
public interface MyInterface {
default void mydefaultMethod() {
//...
}
}
4. jdk8: @FunctionalInterface
- 该注解只能标记在"有且仅有一个抽象方法"的接口上。
- 可以有多个default方法和多个static方法
- Supplier、Consumer、Function、Optional、Predicate等都是FunctionalInterface
4.1 Supplier
- 可以理解为“对象生产者”,比如类的无参构造方法;无参的工厂方法
- 生产对象的类型即为Supplier范型的类型
- 调用Supplier对象的get方法及可触发生产对象
public class SupplierTest {
public String attribute1 = "attribute1";
public static String getInstance() {
return "sdsd";
}
public static void main(String[] args) {
Supplier<String> supplier = String::new; // 获取Sring的无参构造方法生产者
System.out.println(supplier.get());
Supplier<SupplierTest> sp = SupplierTest::new; // 获取SupplierTest的无参构造方法生产者
System.out.println(sp.get().attribute1);
Supplier<String> sass = SupplierTest::getInstance; // 获取SupplierTest的无参getInstance方法生产者
System.out.println(sass.get());
}
}
4.2 Consumer和BiConsumer
- Consumer单个参数的方法的消费者
- BiConsumer两个参数的方法的消费者
- 消费的含义就是只消费不返回数据,和Function、BiFunction的区别就是 Function 有返回值
Consumer的例子
- 顾名思义就是消费者
- 需要消费的数据作为参数
- 调用消费者的 accept 方法,传入“消费数据”参数,即可消费
- 只消费,不返回数据,所以返回类型是void
public class ConsumerTest {
static void compute(Integer arg1) {
System.out.println("compute " + arg1);
}
public static void main(String[] args) {
// static viod 的单参数方法作为消费者
Consumer<Integer> comsumer1 = ConsumerTest::compute;
comsumer1.accept(123);
// Lambda 表达式(单参数)的消费者
Consumer<String> comsumer2 = arg1 -> System.out.println("compute " + arg1);
comsumer2.accept("456");
// 常用在集合中的forEach
List<String> list = Arrays.asList("aa","bb","cc");
list.stream().forEach(System.out::println);
list.stream().forEach( str -> System.out.println("str = " + str));
}
}
BiConsumer的例子
- 消费两个参数数据,消费数据作为参数
- 调用消费者的 accept 方法,传入两个“消费数据”参数,即可消费
- 只消费,不返回数据,所以返回类型是void
public class BIConsumerTest {
void comsumeXxx(String xxx){
System.out.println("xxx = " + xxx);
}
static void compute(String arg1,Integer arg2) {
System.out.println("compute 1args1=" + arg1 + ",arg2 = " + arg2);
}
static void compute2(String arg1,Integer arg2) {
System.out.println("compute2 args1=" + arg1 + ",arg2 = " + arg2);
}
public static void main(String[] args) {
// static void 的双参数方法作为 BiConsumer
BiConsumer<String,Integer> comsumer1 = BIConsumerTest::compute;
comsumer1.accept("hello", 1);
// 在原来的消费者后增加 comsumer, 执行的时候先执行老的, 再执行新的 comsumer
comsumer1.andThen(BIConsumerTest::compute2).accept("hello", 1);
// 类的 void 的单参数方法作为 BiConsumer,消费的时候参数1为对象
BiConsumer<BIConsumerTest,String> comsumer2 =BIConsumerTest::comsumeXxx;
comsumer2.accept(new BIConsumerTest(), "hello");
// 用在hashmap中
HashMap<String,Integer> map = new HashMap<String,Integer>();
map.put("k1", 1);
map.put("k2", 2);
map.forEach( (k,v) -> { System.out.println("args1=" + k + ",arg2 = " + v); });
// 或
map.forEach(BIConsumerTest::compute);
}
}
Consumer和BiConsumer混用的例子
public class ComsumerTest {
private String value1;
public static void main(String[] args) {
ComsumerTest s = new ComsumerTest();
s.setXxx(ComsumerTest::setValue1, "111");
System.out.println(s.getValue1());
}
public void setXxx(BiConsumer<ComsumerTest,String> consumer, String value){
// 以下两行代码等同于 consumer.accept(this, value);
Consumer<ComsummerTest> c = istance -> consumer.accept(istance,value);
c.accept(this);
}
public String getValue1() {
return value1;
}
public void setValue1(String value1) {
this.value1 = value1;
}
}
4.3 Function和BiFunction
Function
- 有返回值的函数调用
- 仅有一个参数
public class FunctionTest {
String testNoArgFunction(){
return "no args function";
}
static String testFunction(Integer intArg){
return "test_".concat(String.valueOf(intArg));
}
public static void main(String[] args) {
// static 的单参数有返回值的方法作为 Function
Function<Integer,String> f = FunctionTest::testFunction;
// 调用 apply 有返回值
System.out.println(f.apply(99));
// 类的无参方法作为 Function,类对象作为函数的参数
Function<FunctionTest,String> f2 = FunctionTest::testNoArgFunction;
System.out.println(f2.apply(new FunctionTest()));
// 常用在 list stream 的 map 方法 中(即传入一个值,返回一个新的值)
Arrays.asList(11,22).stream().map( intArg -> { return "test_".concat(String.valueOf(intArg)); }).forEach(System.out::println);
// 等同于
Arrays.asList(11,22).stream().map( f ).forEach(System.out::println);
}
}
BiFunction
- 有返回值的函数调用
- 有两个参数
public class BiFunctionTest {
String testFunction2(Integer intArg){
return "test2_".concat(String.valueOf(intArg));
}
static String testFunction(Integer intArg,Integer intArg2){
return "test_".concat(String.valueOf(intArg)).concat(String.valueOf(intArg2));
}
public static void main(String[] args) {
// static 双参数 有返回值的方法 作为 BiFunction
BiFunction<Integer,Integer,String> bf = BiFunctionTest::testFunction;
System.out.println(bf.apply(1, 2));
// 等同于
BiFunction<Integer,Integer,String> bf1 = (Integer intArg,Integer intArg2) -> {
return "test1_".concat(String.valueOf(intArg)).concat(String.valueOf(intArg2));
};
System.out.println(bf1.apply(1, 2));
// 单参参数有返回值的对象方法 作为BiFunction。相当于也是两个参数,其中第一个参数是类对象本身
BiFunction<BiFunctionTest,Integer,String> bf2 = BiFunctionTest::testFunction2;
System.out.println(bf2.apply(new BiFunctionTest(), 1));
}
}
4.4 Optional
- 基本语法
public class OptionalTest {
public static void main(String[] args) {
// of 方法,要求参数不能为null,如果为null,则抛出 NullPointerException 异常
Optional<Integer> it1 = Optional.of(1);
// ofNullable 方法,参数可以为null
Optional<Integer> it2 = Optional.ofNullable(null);
System.out.println("it1的值为1:" + it1.get()); // 如果值为空,则抛出NoSuchElementExceptiony异常
System.out.println("it1值不为空:" + it1.isPresent());
System.out.println("it2值不为空:" + it2.isPresent());
System.out.println("it2值为空:" + !it2.isPresent());
// 等同于
System.out.println("it2值为空:" + (it2==Optional.<Integer>empty()));
// 如果不是null,调用Consumer
it1.ifPresent( value -> {
System.out.println("it1值不为空,值=" +value);
});
System.out.println("it1 orElse(100)的值为it1存在的值:" + it1.orElse(100));
System.out.println("it2 orElse(100)的值为100,因为it2的值为空:" + it2.orElse(100));
// orElse 等同于 orElseGet,只是 orElseGet 的参数是个 Supplier 对象
Integer rs = it1.orElseGet( () -> {
return 100;
});
try {
Integer rs2 = it2.orElseThrow();
} catch (NoSuchElementException e) {
System.out.println("it2值为空,抛出NoSuchElementException");
}
// filter(Predicate):判断Optional对象中保存的值是否满足Predicate,并返回新的Optional
Optional<Integer> t1filter = it1.filter( intArgs -> { return intArgs>100; });
// 由于 1>100 为false,所以t1filter的值为空
System.out.println("t1filter值为空:" + !t1filter.isPresent());
// map(Function):对Optional中保存的值进行函数运算,并返回新的Optional(可以是任何类型)
Optional<String> t1map = it1.map( intArgs -> { return "hello " + intArgs; });
System.out.println("t1map的值为:" + t1map.get());
// flatMap():功能与map()相似, 区别是mapping函数返回必须是Optional
Optional<String> t1map2 = it1.flatMap(intArgs -> { return Optional.<String>of("hello " + intArgs); });
System.out.println("t1map的值为:" + t1map2.get());
}
}
- 用法示例
public class OptionalCase {
static class User {
public User() {
}
public User(String name) {
this.name = name;
}
String name;
}
// 老的用法
public static String getUserName(User u) {
if (u == null || u.name == null) {
return "none";
}
return u.name;
}
// 新的写法
public static String getUserNameNew(User u) {
return Optional.ofNullable(u)
.map(t -> t.name)
.orElse("none");
}
public static void main(String[] args) {
System.out.println(getUserName(null)); // none
System.out.println(getUserName(new User())); // none
System.out.println(getUserName(new User("zhangsan"))); // zhangsan
System.out.println(getUserNameNew(null)); // none
System.out.println(getUserNameNew(new User())); // none
System.out.println(getUserNameNew(new User("zhangsan"))); // zhangsan
}
}
- 用法实例2
public void setName(String name) throws IllegalArgumentException {
this.name = Optional.ofNullable(name).filter(User::isNameValid)
.orElseThrow(()->new IllegalArgumentException("Invalid username."));
}
4.5 Predicate
- 用于判断的FunctionalInterface
- boolean test(T t)是它的接口函数
- and、or表示逻辑与、逻辑或
public static void main(String[] args) {
// 设置一个大于100的过滤条件
Predicate<Integer> predicate = x -> x > 100;
// 设置一个小于200的过滤条件
Predicate<Integer> predicate2 = x -> x < 200;
// 设置一个偶数过滤条件
Predicate<Integer> predicate3 = x -> x%2==0;
System.out.println(predicate.test(101)); // 输出 true
System.out.println(predicate.test(97)); // 输出 false
// and 逻辑
System.out.println(predicate.and(predicate2).test(101)); // 输出 true
System.out.println(predicate.and(predicate2).test(201)); // 输出 fasle
System.out.println(predicate.and(predicate2).and(predicate3).test(101)); // 输出 false
System.out.println(predicate.and(predicate2).and(predicate3).test(102)); // 输出 true
// or 逻辑
System.out.println(predicate.or(predicate2).test(88)); // 输出 true
System.out.println(predicate.or(predicate2).test(101)); // 输出 true
// 常用在filter中
Arrays.asList(88,101,102).stream().filter(predicate).forEach(System.out::println);// 过去大于100的并输出
}