一周开发问题回顾2023年08月07日-2023年08月13日
- 1. Arrays.asList()与 new ArrayList()的区别
- 1.1 Arrays
- 1.1.1补充 ArrayList(Arrays.asList(array))
- 1.2 ArrayList()
- 1.2.1 创建ArrayList的几种方法
- 2.Mysql中group by的使用方式
- 3.画图
- 4. 时间倒排
- 5. 工厂+策略设计模式
- 6.List注释 @Value
- 7.在一个表中增加字段
- 8.Java类的加载顺序
- 9. 另一个策略+工厂
- 10. @PostConstruct
1. Arrays.asList()与 new ArrayList()的区别
1.1 Arrays
Arrays.asList()
和 Arrays源码
Arrays
是java.util
包下的一个类
下面是Arrays.asList()
的源码。
Returns a fixed-size list backed by the specified array. (Changes to the returned list "write through" to the array.) This method acts as bridge between array-based and collection-based APIs, in combination with Collection.toArray. The returned list is serializable and implements RandomAccess.
This method also provides a convenient way to create a fixed-size list initialized to contain several elements:
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
Params:
a – the array by which the list will be backed
Type parameters:
<T> – the class of the objects in the array
Returns:
a list view of the specified array
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
Arrays.asList
方法,使用这个方法将会为数组创建一个固定长度(fixed-size)List 对象。这个方法只是对 array 数组进行了一次包装,以便于在程序中可以使用 List,在这个包装中没有数据被拷贝或者创建。
同时,我们也不能对新创建的 List 的长度进行修改,因为添加或者删除 List 中的元素是不被允许的。
然而,我们是可以对新创建的 List 中的数组中的元素进行修改的。需要注意的是,如果你对 List 中的元素数据进行了修改的话,那么对应 Array 的数据也被改动了。
补充:
参考 https://blog.csdn.net/weixin_45404202/article/details/120518876
https://cloud.tencent.com/developer/article/1860630
Arrays.asList(strs) removeAll引发得java.lang.UnsupportedOperationException异常
1.1.1补充 ArrayList(Arrays.asList(array))
与 Arrays.asList 方法一样,我们还可以使用 ArrayList<>(Arrays.asList(array)) 来从 Array 创建一个 List。
但是,与上面的方法不一样的是,使用这个方法创建的 List 是一个从老的 Array 中数据拷贝过来的,这个新的 List 与老的 Array 不相干,对新 List 中数据的操作不会影响到老的 Array 中的数据。
换句话说,使用这种方法创建的 List 是可以对 List 中的元素进行添加和删除操作的。
补充2:
List<String> timeList = Arrays.asList();
System.out.println(timeList);
List<String> list = new ArrayList<>();
System.out.println(timeList.equals(list));
[]
true
Process finished with exit code 0
1.2 ArrayList()
Arrays.asList() 和 new ArrayList() 的区别(详解)
package java.util;
public class Arrays {
/**
* Returns a fixed-size list backed by the specified array. (Changes to
* the returned list "write through" to the array.) This method acts
* as bridge between array-based and collection-based APIs, in
* combination with {@link Collection#toArray}. The returned list is
* serializable and implements {@link RandomAccess}.
*
* <p>This method also provides a convenient way to create a fixed-size
* list initialized to contain several elements:
* <pre>
* List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
* </pre>
*
* @param <T> the class of the objects in the array
* @param a the array by which the list will be backed
* @return a list view of the specified array
*/
@SafeVarargs
@SuppressWarnings("varargs")
public static <T> List<T> asList(T... a) {
return new ArrayList<>(a);
}
/**
* @serial include
*/
private static class ArrayList<E> extends AbstractList<E>
implements RandomAccess, java.io.Serializable
{
private static final long serialVersionUID = -2764017481108945198L;
private final E[] a;
ArrayList(E[] array) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
.......
}
}
-
Arrays是一个java.util包中的一个类。通过调用asList()这个方法,获取到一个集合,asList()方法中的实现就是new ArrayList();。但是值得注意的是new的这个ArrayList不是java.util包中的ArrayList,而是Arrays中的这个内部类ArrayList。
-
内部类java.util.Arrays.ArrayList虽然也是继承了AbstractList这个抽象类,但是它并没有和java.util.ArrayList一样,去实现add()等方法,那这样的话,如果调用add()方法,其实就是调用父类AbstractList类当中的add()方法,但是AbstractList.add()就抛出了异常。
-
另外,Arrays.asList()拿到的集合是原本数组的引用,在初始化的java.util.Arrays.ArrayList的时候,将原本的数据存放到一个private并且final的数组中。
AbstractList源码:
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws ClassCastException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public void add(int index, E element) {
throw new UnsupportedOperationException();
}
/**
* {@inheritDoc}
*
* <p>This implementation always throws an
* {@code UnsupportedOperationException}.
*
* @throws UnsupportedOperationException {@inheritDoc}
* @throws IndexOutOfBoundsException {@inheritDoc}
*/
public E remove(int index) {
throw new UnsupportedOperationException();
}
public class Test {
public static void main(String[] args) {
String[] stringArray = new String[]{"A", "B", "C", "D"};
List<String> stringList = Arrays.asList(stringArray);
stringList.set(0,"E");
Arrays.stream(stringArray).forEach((e)-> System.out.println(e));
System.out.println("--------------");
stringList.stream().forEach((e)-> System.out.println(e));
System.out.println("--------------");
stringList.add("F");
}
}
- Arrays.asList 返回的 ArrayList 是一个固定长度(fixed-size)List 对象,只对 Array 进行了包装,返回的是Array的引用(a = Objects.requireNonNull(array);),如list对元素修改,则也会改变Array 的值。
- 没有实现 add 和 remove等 方法(不支持该操作,若操作后抛异常 java.lang.UnsupportedOperationException)。
new ArrayList()
List<String> list = new ArrayList();
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
*/
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);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* Constructs a list containing the elements of the specified
* collection, in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
}
- ArrayList是java.util包中的类,如上述代码所示,ArrayList是继承了AbstractList这个抽象类,并且实现了List接口。
- List接口的话,是集合的一个比较重要的接口。这里有一下集合的基本操作方法,比如说add,remove等一系列的操作。AbstractList这个抽象类,虽然实现了List接口,也实现了add,remove等方法,但都只是抛出UnsupportedOperationException()。具体的实现还是看ArrayList类。
1.2.1 创建ArrayList的几种方法
1. 使用默认构造函数:
```java
ArrayList<String> list = new ArrayList<>();
- 指定初始容量的构造函数:
ArrayList<String> list = new ArrayList<>(10);
- 使用Arrays.asList()方法将数组转换为ArrayList:
String[] array = {"apple", "banana", "orange"};
ArrayList<String> list = new ArrayList<>(Arrays.asList(array));
- 使用Collections.addAll()方法将元素添加到ArrayList中:
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "apple", "banana", "orange");
- 使用双括号初始化(Double Brace Initialization):
ArrayList<String> list = new ArrayList<>() {{
add("apple");
add("banana");
add("orange");
}};
2.Mysql中group by的使用方式
为啥SELECT * FROM tableName GROUP BY columnName语法报错?
多次group by
SELECT count(*), sum(price)
FROM (
SELECT dining_date, card_no, dining_type, dining_hall_id, price
FROM dining_logs
WHERE staff_type=3 AND dining_date BETWEEN 20230101 AND 20230131 AND dining_hall_id <> 7
GROUP BY dining_date, card_no, dining_type, dining_hall_id
) t
3.画图
项目的设计,画各种图需要时间此处只是补充资料 https://plantuml.com/zh/
4. 时间倒排
.sorted(Comparator.comparing(MoConfigDetailVo::getOpUpdatedAt).reversed())
.collect(Collectors.toList());
5. 工厂+策略设计模式
首先定义一个策略模式接口
public interface Strategy {
void process(T t, U u, V v);
}
然后创建接口的实现类,也就是不同的情况,每个策略实现的不同类。 这个实现类肯定有多个。
public class TStrategy implements Strategy {
@Override
public void process(T t, U u, V v) {
实现业务逻辑
}
}
最后建造一个工厂类
public class Factory {
private static final Map<T, Strategy> STRATEGY_MAP;
static {
STRATEGY_MAP = new HashMap<>();
STRATEGY_MAP.put(t, new TStrategy());
STRATEGY_MAP.put(t, new SStrategy());
STRATEGY_MAP.put(t, new UStrategy());
STRATEGY_MAP.put(t, new VStrategy());
STRATEGY_MAP.put(t, new WStrategy());
}
public static Strategy createStrategy(T t) {
return STRATEGY_MAP.get(t);
}
}
在实际的业务代码中
实现类如TStrategy strategy = Factory.createStrategy(t);
if (strategy != null) {
strategy.process(t, u, v);
}
6.List注释 @Value
/**
* id集合
*/
@Value("${id:11,1011,22,92,120}")
private List<Integer> ids;
7.在一个表中增加字段
ALTER TABLE a ADD COLUMN `b_id` bigint(20) unsigned NOT NULL DEFAULT '0' COMMENT 'B区id' AFTER `time`;
8.Java类的加载顺序
https://www.cnblogs.com/sxkgeek/p/9647992.html
9. 另一个策略+工厂
工厂
@Component
public class Factory {
private static final Map<Integer,Class< ? extends Strategy>> STRATEGY_MAP = new HashMap<>(4);
@PostConstruct
public void init() {
STRATEGY_MAP.put(Integer code, Atrategy.class);
STRATEGY_MAP.put(Integer code, BStrategy.class);
STRATEGY_MAP.put(Integer code, CStrategy.class);
STRATEGY_MAP.put(Integer code, DStrategy.class);
}
public static Class< ? extends Strategy> createStrategy(Integer code) {
return STRATEGY_MAP.get(code);
}
}
public interface Strategy {
void process(Entity record, Integer i, Vo res);
}
其中一个实现Strategy的类,因为是@Autowired
了dao
所以需要注入spring
容器管理。举例所以只写一个Strategy的实现
@Service
public class BStrategy implements Strategy {
@Autowired
private MoDao moDao;
@Resource
private Client hrClient;
@Override
public void process(MoEntity moRecord, Integer userGroup, MoDetailVo res) {
LambdaQueryWrapper<Entity> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Entity::getMoListId, moRecord.getId());
queryWrapper.eq(Entity::getUserGroup, userGroup);
queryWrapper.eq(Entity::getDiningDay, moRecord.getDiningDay());
queryWrapper.eq(Entity::getMoTypeId, moRecord.getMoTypeId());
queryWrapper.eq(Entity::getDiningShift, moRecord.getDiningShift());
List<MoPeopleListEntity> records = moPeopleListDao.list(queryWrapper);
if (records.isEmpty()) {
return;
}
List<String> Ids = records.stream()
.map(Entity::getUserId)
.collect(Collectors.toList());
Map<String, StaffInfo> staffMap = hrClient.fetchStaffByFeishuIds(Ids).stream()
.collect(Collectors.toMap(StaffInfo::getId, e -> e));
// 略...
res.getPeople().getBlueCollar().addAll(peopleDetailList);
}
}
在业务代码中,则通过SpringBeanUtil.getBean()
从spring
容器中拿到对象,实现功能
Class<? extends Strategy> strategyClass = Factory.createStrategy(item.getCode());
Strategy strategy = SpringBeanUtil.getBean(strategyClass);
if (strategy != null) {
strategy.process(moListRecord, item.getCode(), res);
}
public class SpringBeanUtil implements ApplicationListener<ApplicationStartedEvent> {
private static ApplicationContext applicationContext;
public SpringBeanUtil() {
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
public String getActiveProfile() {
return applicationContext.getEnvironment().getActiveProfiles()[0];
}
public void onApplicationEvent(ApplicationStartedEvent event) {
synchronized(this) {
if (applicationContext == null) {
applicationContext = event.getApplicationContext();
}
}
}
}
10. @PostConstruct
@PostConstruct
是一个在Java中常用的注解,它用于指定一个方法在对象创建后立即执行。这个注解通常用于初始化资源、执行配置或进行其他一次性的操作。
使用@PostConstruct
注解的方法将在依赖注入完成后被调用,但在对象被放入服务之前。它可以用于任何类或bean中,包括普通的POJO类、Spring管理的组件、EJBs等。
下面是一个示例,展示了如何在一个Spring组件中使用@PostConstruct
注解:
@Component
public class MyComponent {
@PostConstruct
public void init() {
// 在对象创建后进行初始化操作
System.out.println("执行初始化操作");
}
}
在上述代码中,MyComponent
类被注解为一个Spring组件,并在init()
方法上使用了@PostConstruct
注解。当Spring容器创建并初始化MyComponent
对象时,init()
方法将被自动调用。
需要注意的是,@PostConstruct
注解需要依赖于Spring或其他框架,以确保方法的正确调用。在纯Java环境中,@PostConstruct
注解可能不会被识别和触发。