001/*
002 *  Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com).
003 *  <p>
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  You may obtain a copy of the License at
007 *  <p>
008 *  http://www.apache.org/licenses/LICENSE-2.0
009 *  <p>
010 *  Unless required by applicable law or agreed to in writing, software
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016package com.mybatisflex.core.util;
017
018import com.mybatisflex.core.query.CloneSupport;
019
020import java.util.*;
021import java.util.function.Function;
022
023
024public class CollectionUtil {
025
026    private CollectionUtil() {
027    }
028
029
030    public static boolean isEmpty(Collection<?> collection) {
031        return collection == null || collection.isEmpty();
032    }
033
034    public static boolean isNotEmpty(Collection<?> collection) {
035        return !isEmpty(collection);
036    }
037
038
039    public static boolean isEmpty(Map<?, ?> map) {
040        return map == null || map.isEmpty();
041    }
042
043    public static boolean isNotEmpty(Map<?, ?> map) {
044        return !isEmpty(map);
045    }
046
047    /**
048     * 合并 list
049     */
050    public static <T> List<T> merge(List<T> list, List<T> other) {
051        if (list == null && other == null) {
052            return new ArrayList<>();
053        } else if (isEmpty(other) && list != null) {
054            return list;
055        } else if (isEmpty(list)) {
056            return other;
057        }
058        List<T> newList = new ArrayList<>(list);
059        newList.addAll(other);
060        return newList;
061    }
062
063
064    public static <K, V> HashMap<K, V> newHashMap() {
065        return new HashMap<>();
066    }
067
068    /**
069     * 主要是用于修复 concurrentHashMap 在 jdk1.8 下的死循环问题
070     *
071     * @see <a href="https://bugs.openjdk.org/browse/JDK-8161372">https://bugs.openjdk.org/browse/JDK-8161372</a>
072     */
073    public static <K, V> V computeIfAbsent(Map<K, V> concurrentHashMap, K key, Function<? super K, ? extends V> mappingFunction) {
074        V v = concurrentHashMap.get(key);
075        if (v != null) {
076            return v;
077        }
078        return concurrentHashMap.computeIfAbsent(key, mappingFunction);
079    }
080
081
082    public static <T> List<T> toList(Collection<T> collection) {
083        if (collection instanceof List) {
084            return (List<T>) collection;
085        } else {
086            return new ArrayList<>(collection);
087        }
088    }
089
090    public static String[] toArrayString(Collection<?> collection) {
091        if (isEmpty(collection)) {
092            return new String[0];
093        }
094        String[] results = new String[collection.size()];
095        int index = 0;
096        for (Object o : collection) {
097            results[index++] = String.valueOf(o);
098        }
099        return results;
100    }
101
102    @SuppressWarnings("all")
103    public static <E extends CloneSupport<E>> List<E> cloneArrayList(List<E> list) {
104        if (list == null) {
105            return null;
106        }
107        List<E> arrayList = new ArrayList<>(list.size());
108        for (E e : list) {
109            arrayList.add(e.clone());
110        }
111        return arrayList;
112    }
113
114
115    public static <T> Set<T> newHashSet(T... elements) {
116        return new HashSet<>(Arrays.asList(elements));
117    }
118
119
120    public static <T> List<T> newArrayList(T... elements) {
121        return new ArrayList<>(Arrays.asList(elements));
122    }
123
124
125    public static <E> ArrayList<E> newArrayList(Collection<E> collection) {
126        if (isEmpty(collection)) {
127            return new ArrayList<>();
128        }
129        return new ArrayList<>(collection);
130    }
131
132
133    public static <K, V> HashMap<K, V> newHashMap(Map<K, V> map) {
134        if (map == null || map.isEmpty()) {
135            return new HashMap<>();
136        }
137        return new HashMap<>(map);
138    }
139
140}