一、Objects
JDK7里面新增的Objects类,本类由一些操作对象的静态工具方法构成,这些工具方法包括了非空检查、方法的非空参数检查、 比较对象的hashCode、为对象返回一个字符串表示、比较两个对象等。 本文是以java8版本介绍Objects类
1、判断对象是否为null
//判断一个对象是否为空,如果为空返回true
static boolean isNull(Object obj);
//判断一个对象是否为空,如果不为空返回true
static boolean nonNull(Object obj);
2、空指针判断处理
//对象不能为空,否则抛出NullPointerException
static <T> T requireNonNull(Tob j);
//对象不能为空,否则抛出NullPointerException,message是异常信息说明
static<T> T requireNonNull(Tobj,String message);
static <T> T requireNonNull(T obj,Supplier<String> messageSupplier)
3、hashCode
// return o!=null? o.hashCode():0;
static int hashCode(Object o);
// return Arrays.hashCode(values);
static int hash(Object...values)
4、equals
// return(a==b)||(a!=null&&a.equals(b));
static boolean equals(Objecta,Objectb)
//判断2个数组对象是否相等,这个方法进行了非空判断
//if(a==b)
//return true;
//else if(a==null||b==null)
//return false;
//else
//return Arrays.deepEquals0(a,b);
static boolean deepEquals(Object a,Object b)
4、toString
//return String.valueOf(o);
static String toString(Objecto)
//return(o!=null)? o.toString():nullDefault;
static String toString(Objecto,String nullDefault)
5、compare
///return(a==b)?0:c.compare(a,b);
static<T> int compare(Ta,Tb,Comparator<? super T> c)
二、Optional
Java中还有OptionalInt OptionalLong,OptionalDouble其方法和Optional差不多,这里就不介绍了
1、创建 Optional 实例
static <T> Optional<T> empty()
static <T> Optional<T> of(T value)
static <T> Optional<T> ofNullable(T value)
你可以使用 of() 和 ofNullable() 方法创建包含值的 Optional。两个方法的不同之处在于如果你把 null 值作为参数传递进去
of() 方法会抛出 NullPointerException:
你看,我们并没有完全摆脱 NullPointerException。因此,你应该明确对象不为 null 的时候使用 of()。
如果对象即可能是 null 也可能是非 null,你就应该使用 ofNullable() 方法
2、返回值
public T get()//如果值为null,抛出 NoSuchElementException 。
public T orElse(T other)
public T orElseGet(Supplier<? extends T> other)
Optional 类提供了 API 用以返回对象值,或者在对象为空的时候返回默认值。
这里你可以使用的第一个方法是 orElse(),它的工作方式非常直接,如果有值则返回该值,否则返回传递给它的参数值:
@Test
public void whenEmptyValue_thenReturnDefault() {
User user = null;
User user2 = new User("anna@gmail.com", "1234");
User result = Optional.ofNullable(user).orElse(user2);
}
这里 user 对象是空的,所以返回了作为默认值的 user2。
如果对象的初始值不是 null,那么默认值会被忽略:
第二个同类型的 API 是 orElseGet() —— 其行为略有不同。这个方法会在有值的时候返回值,如果没有值,它会执行作为参数传入的 Supplier(供应) 函数式接口,并将返回其执行结果:
User result = Optional.ofNullable(user).orElseGet( () -> user2);
orElse() 和 orElseGet() 的不同之处
乍一看,这两种方法似乎起着同样的作用。然而事实并非如此。我们创建一些示例来突出二者行为上的异同。
我们先来看看对象为空时他们的行为:
public void givenEmptyValue_whenCompare_thenOk() {
User user = null
logger.debug("Using orElse");
User result = Optional.ofNullable(user).orElse(createNewUser());
logger.debug("Using orElseGet");
User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
}
private User createNewUser() {
logger.debug("Creating New User");
return new User("extra@gmail.com", "1234");
}
上面的代码中,两种方法都调用了 createNewUser() 方法,这个方法会记录一个消息并返回 User 对象。
代码输出如下:
Using orElse
Creating New User
Using orElseGet
Creating New User
由此可见,当对象为空而返回默认对象时,行为并无差异。
我们接下来看一个类似的示例,但这里 Optional 不为空:
@Test
public void givenPresentValue_whenCompare_thenOk() {
User user = new User("john@gmail.com", "1234");
logger.info("Using orElse");
User result = Optional.ofNullable(user).orElse(createNewUser());
logger.info("Using orElseGet");
User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
}
这次的输出:
Using orElse
Creating New User
Using orElseGet
这个示例中,两个 Optional 对象都包含非空值,两个方法都会返回对应的非空值。不过,orElse() 方法仍然创建了 User 对象。与之相反,orElseGet() 方法不创建 User 对象。
在执行较密集的调用时,比如调用 Web 服务或数据查询,这个差异会对性能产生重大影响。
为什么呢?其源码如下
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
按理说当value不等于null时,不会到else模块啊,那么为什么还会执行createNewUser()方法?
因为你是将方法作为一个实参传入方法,所以 执行orElse(createNewUser());等于 String other = createNewUser();orElse(other );
因此会执行createNewUser()方法。
证明
public static void main(String[] args)throws IOException{
orElse("1",get());//执行了方法
}
public static String get(){
System.out.println("执行了方法");
return "";
}
public static Object orElse(String value,String str){
return value;
}
3、返回异常
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)throws X
除了 orElse() 和 orElseGet() 方法,Optional 还定义了 orElseThrow() API —— 它会在对象为空的时候抛出异常,而不是返回备选的值:
public void whenThrowException_thenOk() {
User result = Optional.ofNullable(user).orElseThrow( () -> new IllegalArgumentException());
}
这里,如果 user 值为 null,会抛出 IllegalArgumentException。
个方法让我们有更丰富的语义,可以决定抛出什么样的异常,而不总是抛出 NullPointerException。
现在我们已经很好地理解了如何使用 Optional,我们来看看其它可以对 Optional 值进行转换和过滤的方法。
4、转换值
有很多种方法可以转换 Optional 的值。我们从 map() 和 flatMap() 方法开始。
public <U> Optional<U> map(Function<? super T,? extends U> mapper)
public <U> Optional<U> flatMap(Function<? super T,Optional<U>> mapper)
先来看一个使用 map() API 的例子:
@Test
public void whenMap_thenOk() {
User user = new User("anna@gmail.com", "1234");
String email = Optional.ofNullable(user) .map(u -> u.getEmail()).orElse("default@gmail.com");
assertEquals(email, user.getEmail());
}
map() 对值应用(调用)作为参数的函数,然后将返回的值包装在 Optional 中。这就使对返回值进行链试调用的操作成为可
能 —— 这里的下一环就是 orElse()。
相比这下,flatMap() 也需要函数作为参数,并对值调用这个函数,然后直接返回结果。
下面的操作中,我们给 User 类添加了一个方法,用来返回 Optional:
public class User {
private String position;
public Optional<String> getPosition() {
return Optional.ofNullable(position);
}
//...
}
既然 getter 方法返回 String 值的 Optional,你可以在对 User 的 Optional 对象调用 flatMap() 时,用它作为参数。其返回的值是解除包装的 String 值:
@Test
public void whenFlatMap_thenOk() {
User user = new User("anna@gmail.com", "1234");
user.setPosition("Developer");
String position = Optional.ofNullable(user) .flatMap(u -> u.getPosition()).orElse("default");
assertEquals(position, user.getPosition().get());
}
5、过滤值
除了转换值之外,Optional 类也提供了按条件“过滤”值的方法。
public Optional<T> filter(Predicate< ? super T> predicate)
filter() 接受一个 Predicate 参数,返回测试结果为 true 的值。如果测试结果为 false,会返回一个空的 Optional。
来看一个根据基本的电子邮箱验证来决定接受或拒绝 User(用户) 的示例:
@Test
public void whenFilter_thenOk() {
User user = new User("anna@gmail.com", "1234");
Optional<User> result = Optional.ofNullable(user) .filter(u -> u.getEmail() != null && u.getEmail().contains("@"));
6、判断对象是为null
void ifPresent(Consumer<? super T> consumer)//如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。
boolean isPresent()//返回 true如果存在值,否则为 false 。
isPresent()一般与.get()方法合用,当view存在时,view.isPresent()值为true,通过get()方法返回对象
if(view.isPresent()) {
return view.get();
}else {
return null;
}