java返回集合为null还是空集合及空集合的三种写法小结

 更新时间:2021年11月12日 11:38:40   作者:月染霜华  
这篇文章主要介绍了java返回集合为null还是空集合及空集合的三种写法小结,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

返回集合为null还是空集合及空集合的三种写法

个人认为在自己写接口时,需要返回集合时返回一个空集合,比如mybatis查询如果返回一个集合,结果为空时也会返回一个空集合而不是null。

那么这样有什么好处呢?最大的好处就是调用方不用在判断是否为null,可以直接用,因为不用抛空指针。

当然这也有缺点,如果返回Lists.newArrayList();或者new ArrayList();这会新建一个对象,而这个对象很可能是没必要的,这样白白浪费性能。

解决方法当然也有,可以用Collections.emptyList();这个方法返回一个空集合,并不会新建对象,而是返回

public static final List EMPTY_LIST = new EmptyList<>(); 

这个变量。

当然这也有缺点,如果调用方只是遍历,这没什么不会报错,但是如果要新增,删除里面的元素那就会报错,

那么你可能想为什么,原因就是代码里直接写死了调用时报错,那么为什么要这样写呢?

原因也很简单,如果多个线程对这个集合增删,那么调用方就全乱了,所以采用了直接报错,快速失败的方法

来解决问题。

总结:

返回null,返回new ArrayList<>(),返回EMPTY_LIST 。

null肯定是不推荐的,那么是新建一个List还是返回空List呢?

这要根据接口的性能要求,如果性能要求高返回EMPTY_LIST,否则新建一个对象。

返回空List的方式

方式一:new ArrayList()  

JDK1.8已经优化了,默认构造函数创建的list内部共享空数组,首次插入数据时才会扩容到默认容量;

private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

方式二:new ArrayList(0)

private static final Object[] EMPTY_ELEMENTDATA = {};
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}

方式三:Collections.emptyList()(推荐)

特点:不可变,安全

/**
* The empty list (immutable). This list is serializable.
*
* @see #emptyList()
*/
@SuppressWarnings("rawtypes")
public static final List EMPTY_LIST = new EmptyList<>();
/**
* Returns an empty list (immutable). This list is serializable.
*
* <p>This example illustrates the type-safe way to obtain an empty list:
* <pre>
* List<String> s = Collections.emptyList();
* </pre>
*
* @implNote
* Implementations of this method need not create a separate <tt>List</tt>
* object for each call. Using this method is likely to have comparable
* cost to using the like-named field. (Unlike this method, the field does
* not provide type safety.)
*
* @param <T> type of elements, if there were any, in the list
* @return an empty immutable list
*
* @see #EMPTY_LIST
* @since 1.5
*/
@SuppressWarnings("unchecked")
public static final <T> List<T> emptyList() {
return (List<T>) EMPTY_LIST;
}
/**
* @serial include
*/
private static class EmptyList<E>
extends AbstractList<E>
implements RandomAccess, Serializable {
private static final long serialVersionUID = 8842843931221139166L;
public Iterator<E> iterator() {
return emptyIterator();
}
public ListIterator<E> listIterator() {
return emptyListIterator();
}
public int size() {return 0;}
public boolean isEmpty() {return true;}
public boolean contains(Object obj) {return false;}
public boolean containsAll(Collection<?> c) { return c.isEmpty(); }
public Object[] toArray() { return new Object[0]; }
public <T> T[] toArray(T[] a) {
if (a.length > 0)
a[0] = null;
return a;
}
public E get(int index) {
throw new IndexOutOfBoundsException("Index: "+index);
}
public boolean equals(Object o) {
return (o instanceof List) && ((List<?>)o).isEmpty();
}
public int hashCode() { return 1; }
@Override
public boolean removeIf(Predicate<? super E> filter) {
Objects.requireNonNull(filter);
return false;
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
}
@Override
public void sort(Comparator<? super E> c) {
}
// Override default methods in Collection
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
}
@Override
public Spliterator<E> spliterator() { return Spliterators.emptySpliterator(); }
// Preserves singleton property
private Object readResolve() {
return EMPTY_LIST;
}
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Boot 集成 Kafka的详细步骤

    Spring Boot 集成 Kafka的详细步骤

    Spring Boot与Kafka的集成使得消息队列的使用变得更加简单和高效,可以配置 Kafka、实现生产者和消费者,并利用 Spring Boot 提供的功能处理消息流,以下是 Spring Boot 集成 Kafka 的详细步骤,包括配置、生产者和消费者的实现以及一些高级特性,感兴趣的朋友一起看看吧
    2024-07-07
  • Java8实现优雅的获取重复字符与次数

    Java8实现优雅的获取重复字符与次数

    这篇文章主要为大家详细介绍了在Java8中,我们应该如何进行字符及字符串的去重,以及计算去重次数,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下
    2023-12-12
  • netty中的ByteBuf源码详解

    netty中的ByteBuf源码详解

    这篇文章主要介绍了netty中的ByteBuf源码详解,ByteBuf,顾名思义,就是字节缓冲区,是Netty中非常重要的一个组件,某些场景下性能不是太好,netty开发团队重新设计了ByteBuf用以替代原生ByteBuffer,需要的朋友可以参考下
    2023-11-11
  • SpringBoot中数据传输对象(DTO)的实现

    SpringBoot中数据传输对象(DTO)的实现

    本文主要介绍了SpringBoot中数据传输对象(DTO)的实现,包括了手动创建DTO、使用ModelMapper和Lombok创建DTO的示例,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07
  • 解决springboot整合cxf-jaxrs中json转换的问题

    解决springboot整合cxf-jaxrs中json转换的问题

    这篇文章主要介绍了解决springboot整合cxf-jaxrs中json转换的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • 使用Java获取Json中的数据简单示例

    使用Java获取Json中的数据简单示例

    开发过程中经常会遇到json数据的处理,而单独对json数据进行增删改并不方便,下面这篇文章主要给大家介绍了关于使用Java获取Json中的数据,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-04-04
  • java输入时如何通过回车(enter)来结束输入

    java输入时如何通过回车(enter)来结束输入

    这篇文章主要介绍了java输入时如何通过回车(enter)来结束输入,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • 详解Java 自动装箱与自动拆箱

    详解Java 自动装箱与自动拆箱

    这篇文章主要介绍了Java 自动装箱与自动拆箱的相关资料,帮助大家更好的理解和学习Java,感兴趣的朋友可以了解下
    2020-09-09
  • 多模块maven的deploy集成gitlab ci自动发版配置

    多模块maven的deploy集成gitlab ci自动发版配置

    这篇文章主要为大家介绍了多模块maven项目deploy集成gitlab ci自动发版的配置流程步骤,有需要的朋友可以借鉴参考下,希望能够有所帮助
    2022-02-02
  • JDK动态代理与CGLib动态代理的区别对比

    JDK动态代理与CGLib动态代理的区别对比

    今天小编就为大家分享一篇关于JDK动态代理与CGLib动态代理的区别对比,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-02-02

最新评论