CollectionUtil:一个函数式风格的集合工具
本文分享一个函数式风格的集合操作工具。
使用示例
List<Integer> list = Arrays.asList(1, 2, 3, 4);
int size = CollectionUtil.size(list);//=> 4
boolean empty = CollectionUtil.isEmpty(list);//=> false
boolean notEmpty = CollectionUtil.isNotEmpty(list);//=> true
boolean indexValid = CollectionUtil.isIndexValid(list, 3);//=> true
boolean indexValid1 = CollectionUtil.isIndexValid(list, 4);//=> false
List<Object> list1 = CollectionUtil.list();//=> empty list
List<Integer> list2 = CollectionUtil.list(1);//=> (1)
List<Integer> list3 = CollectionUtil.list(list);//=> (1,2,3,4)
List<Integer> list4 = CollectionUtil.list(1, 2, 3, 4);//=> (1,2,3,4)
List<Integer> list5 = CollectionUtil.ensure(list);//=> list
List<Integer> list6 = CollectionUtil.ensure((List<Integer>) null);//=> empty list
Map<String, Integer> map = CollectionUtil.ensure(Collections.singletonMap("one", 1));//=> map contains: one - 1
Map<String, Integer> map1 = CollectionUtil.ensure((Map<String, Integer>) null);//=> empty map
Set<Integer> set = CollectionUtil.ensure(new HashSet<>(list));//=> set contains: 1,2,3,4
Set<Integer> set1 = CollectionUtil.ensure((Set<Integer>) null);//=> empty set
List<Integer> copyList = CollectionUtil.copy(list);//=> (1,2,3,4)
Integer head = CollectionUtil.head(list);//=> 1
List<Integer> tailList = CollectionUtil.tail(list);//=> (2,3,4)
List<Integer> list7 = CollectionUtil.append(list, 0);//=> (1,2,3,4,0)
CollectionUtil.forEach(list, i -> System.out.println("int:" + i));
List<Integer> reversedList = CollectionUtil.reverse(list);//=> (4,3,2,1)
List<Integer> rangeList = CollectionUtil.range(1, 5);//=> (1,2,3,4)
Integer integer1 = CollectionUtil.find(list, i -> i % 2 == 0, -1);//=> 2
Integer integer2 = CollectionUtil.find(list, i -> i > 10, -1);//=> -1
int count = CollectionUtil.count(list, i -> i % 2 == 0);//=> 2
boolean contains = CollectionUtil.contains(list, i -> i % 2 == 0);//=> true
List<Integer> concatList = CollectionUtil.concat(list,
Arrays.asList(11, 22),
Arrays.asList(33, 44));//=> (1,2,3,4,11,22,33,44)
CollectionUtil.doTimes(3, i -> {
System.out.print("(" + i + ")");
});//打印 (0) (1) (2)
List<Integer> list8 = CollectionUtil.doTimes(5, i -> {
return i * i;
});//=> (0,1,4,9,16)
List<Integer> filteredList = CollectionUtil.filter(list, i -> i % 2 == 0);//=> (2,4)
String reducedStr = CollectionUtil
.reduce(list, new StringBuilder(),
(builder, integer) -> builder.append('(').append(integer).append(')'))
.toString();//=> "(1)(2)(3)(4)"
List<Integer> list9 = CollectionUtil.map(list, i -> i * 10);//=> (10,20,30,40)
List<String> list10 = CollectionUtil.map(
Arrays.asList(1, 2, 3, 4),
Arrays.asList("one", "two", "three", "four"),
i -> s -> s + ":" + i);//=> ("one:1","two:2","three:3","four:4")
完整实现
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
/**
* 函数式集合工具类
*
* @author LeZheng
*/
public class CollectionUtil {
/**
* 获取集合的大小
*
* @param collection
* @return 集合的大小或0(集合为空时)
*/
public static int size(@Nullable Collection<?> collection) {
return collection == null ? 0 : collection.size();
}
/**
* 判断集合是否为空
*
* @param collection
* @return true:null或空集合;否则为false
*/
public static boolean isEmpty(@Nullable Collection<?> collection) {
return collection == null || collection.isEmpty();
}
/**
* isEmpty的取反,判断集合是否不为空
*
* @param collection
* @return
*/
public static boolean isNotEmpty(@Nullable Collection<?> collection) {
return !isEmpty(collection);
}
/**
* 判断索引是否合法
*
* @param collection 目标集合
* @param index 目标索引
* @return 如果合法返回true,否则返回false
*/
public static boolean isIndexValid(@Nullable Collection<?> collection, int index) {
return collection != null && index >= 0 && index < collection.size();
}
/* 构建空的不可变集合 */
public static <T> List<T> list() {
return Collections.emptyList();
}
/* 构建单元素的不可变集合 */
public static <T> List<T> list(T t) {
return Collections.singletonList(t);
}
/* 构建一个列表的不可变副本 */
public static <T> List<T> list(List<T> list) {
return Collections.unmodifiableList(new ArrayList<>(list));
}
/* 根据可变参数构建不可变副本 */
public static <T> List<T> list(T... t) {
return Collections.unmodifiableList(Arrays.asList(Arrays.copyOf(t, t.length)));
}
/**
* 复制一个列表
*
* @param list
* @return list的一个可变列表副本
*/
public static <T> List<T> copy(List<T> list) {
return new ArrayList<>(list);
}
/**
* 获取列表的头元素
*
* @param list
* @return 列表第一个元素,如果列表为空则抛出异常
*/
public static <T> T head(List<T> list) {
if (isEmpty(list)) {
throw new IllegalStateException("head of empty list");
}
return list.get(0);
}
/**
* 列表的尾部元素(除了第一个以外的元素集合)
*
* @param list
* @return 列表中除了第一个元素以外的剩余部分,列表为空则抛出异常
*/
public static <T> List<T> tail(List<T> list) {
if (isEmpty(list)) {
throw new IllegalStateException("tail of empty list");
}
List<T> ts = copy(list);
ts.remove(0);
return Collections.unmodifiableList(ts);
}
/* 非破坏性地往列表追加元素,得到一个一个新列表 */
public static <T> List<T> append(List<T> list, T t) {
List<T> ts = copy(list);
ts.add(t);
return Collections.unmodifiableList(ts);
}
/* 对列表执行 foreach 操作 */
public static <T> Collection<T> forEach(Collection<T> list, Consumer<? super T> consumer) {
return foldLeft(list, list, l -> t -> {
consumer.accept(t);
return l;
});
}
public static <T, U> List<U> map(Collection<T> collection, Function<T, U> function) {
return foldLeft(collection, new ArrayList<>(collection.size()), l -> t -> {
l.add(function.apply(t));
return l;
});
}
public static <T, T2, U> List<U> map(Collection<T> c1, Collection<T2> c2, Function<T, Function<T2, U>> function) {
return foldLeft(c1, c2, new ArrayList<>(c1.size()), l -> t1 -> t2 -> {
l.add(function.apply(t1).apply(t2));
return l;
});
}
public static <T, T2, T3, U> List<U> map(Collection<T> c1, Collection<T2> c2, Collection<T3> c3,
Function<T, Function<T2, Function<T3, U>>> function) {
return foldLeft(c1, c2, c3, new ArrayList<>(c1.size()), l -> t1 -> t2 -> t3 -> {
l.add(function.apply(t1).apply(t2).apply(t3));
return l;
});
}
public static <T, T2, T3, T4, U> List<U> map(Collection<T> c1, Collection<T2> c2, Collection<T3> c3, Collection<T4> c4,
Function<T, Function<T2, Function<T3, Function<T4, U>>>> function) {
return foldLeft(c1, c2, c3, c4, new ArrayList<>(c1.size()), l -> t1 -> t2 -> t3 -> t4 -> {
l.add(function.apply(t1).apply(t2).apply(t3).apply(t4));
return l;
});
}
public static <T, T2, T3, T4, T5, U> List<U> map(Collection<T> c1, Collection<T2> c2, Collection<T3> c3, Collection<T4> c4, Collection<T5> c5,
Function<T, Function<T2, Function<T3, Function<T4, Function<T5, U>>>>> function) {
return foldLeft(c1, c2, c3, c4, c5, new ArrayList<>(c1.size()), l -> t1 -> t2 -> t3 -> t4 -> t5 -> {
l.add(function.apply(t1).apply(t2).apply(t3).apply(t4).apply(t5));
return l;
});
}
public static <T, U> U foldLeft(Collection<T> c, U identity, Function<U, Function<T, U>> function) {
U result = identity;
Iterator<T> iterator1 = c.iterator();
while (iterator1.hasNext()) {
result = function.apply(result).apply(iterator1.next());
}
return result;
}
public static <T, T2, U> U foldLeft(Collection<T> c, Collection<T2> c2, U identity, Function<U, Function<T, Function<T2, U>>> function) {
U result = identity;
Iterator<T> iterator1 = c.iterator();
Iterator<T2> iterator2 = c2.iterator();
while (iterator1.hasNext() && iterator2.hasNext()) {
result = function.apply(result).apply(iterator1.next()).apply(iterator2.next());
}
return result;
}
public static <T, T2, T3, U> U foldLeft(Collection<T> c, Collection<T2> c2, Collection<T3> c3, U identity,
Function<U, Function<T, Function<T2, Function<T3, U>>>> function) {
U result = identity;
Iterator<T> iterator1 = c.iterator();
Iterator<T2> iterator2 = c2.iterator();
Iterator<T3> iterator3 = c3.iterator();
while (iterator1.hasNext() && iterator2.hasNext() && iterator3.hasNext()) {
result = function.apply(result).apply(iterator1.next()).apply(iterator2.next()).apply(iterator3.next());
}
return result;
}
public static <T, T2, T3, T4, U> U foldLeft(Collection<T> c, Collection<T2> c2, Collection<T3> c3, Collection<T4> c4, U identity,
Function<U, Function<T, Function<T2, Function<T3, Function<T4, U>>>>> function) {
U result = identity;
Iterator<T> iterator1 = c.iterator();
Iterator<T2> iterator2 = c2.iterator();
Iterator<T3> iterator3 = c3.iterator();
Iterator<T4> iterator4 = c4.iterator();
while (iterator1.hasNext() && iterator2.hasNext() && iterator3.hasNext() && iterator4.hasNext()) {
result = function.apply(result).apply(iterator1.next()).apply(iterator2.next()).apply(iterator3.next()).apply(iterator4.next());
}
return result;
}
public static <T, T2, T3, T4, T5, U> U foldLeft(Collection<T> c, Collection<T2> c2, Collection<T3> c3, Collection<T4> c4, Collection<T5> c5, U identity,
Function<U, Function<T, Function<T2, Function<T3, Function<T4, Function<T5, U>>>>>> function) {
U result = identity;
Iterator<T> iterator1 = c.iterator();
Iterator<T2> iterator2 = c2.iterator();
Iterator<T3> iterator3 = c3.iterator();
Iterator<T4> iterator4 = c4.iterator();
Iterator<T5> iterator5 = c5.iterator();
while (iterator1.hasNext() && iterator2.hasNext() && iterator3.hasNext() && iterator4.hasNext() && iterator5.hasNext()) {
result = function.apply(result).apply(iterator1.next()).apply(iterator2.next()).apply(iterator3.next()).apply(iterator4.next()).apply(iterator5.next());
}
return result;
}
public static <T, U> U foldRight(List<T> list, U identity, Function<T, Function<U, U>> function) {
U result = identity;
ListIterator<T> iterator = list.listIterator(list.size());
while (iterator.hasPrevious()) {
T t = iterator.previous();
result = function.apply(t).apply(result);
}
return result;
}
/* 非破坏性地倒转元素 */
public static <T> List<T> reverse(@NonNull List<T> list) {
return foldRight(list, new ArrayList<>(list.size()), (T a) -> (List<T> b) -> {
b.add(a);
return b;
});
}
public static <T> List<T> unfold(T seed, Function<T, T> f, Predicate<T> p) {
List<T> result = new LinkedList<>();
T temp = seed;
while (p.test(temp)) {
result.add(temp);
temp = f.apply(temp);
}
return new ArrayList<>(result);
}
/**
* 得到指定范围的整数列表
*
* @param start 开始大小(包含)
* @param end 结束大小(不包含)
* @return 整数列表
*/
public static List<Integer> range(int start, int end) {
return unfold(start, integer -> integer + 1, integer -> integer < end);
}
/**
* 按指定条件过滤出集合中的元素
*
* @param collection 目标集合
* @param predicate 结果元素所满足的断言
* @return 过滤后的列表
*/
public static <T> List<T> filter(@NonNull Collection<T> collection, @NonNull Predicate<? super T> predicate) {
return new ArrayList<>(foldLeft(collection, new LinkedList<>(), l -> t -> {
if (predicate.test(t)) {
l.add(t);
}
return l;
}));
}
/**
* 统计集合中满足条件的元素个数
*
* @param collection 目标集合
* @param predicate 条件对应的断言
* @return 满足条件的元素个数
*/
public static <T> int count(Collection<T> collection, Predicate<? super T> predicate) {
return foldLeft(collection, 0, i -> t -> predicate.test(t)
? i + 1
: i);
}
/**
* 判断集合中是否包含满足指定条件的元素
*
* @param collection 目标集合
* @param predicate 条件对应的断言
* @return 如果包含就返回true,否则返回false
*/
public static <T> boolean contains(Collection<T> collection, Predicate<? super T> predicate) {
return foldAny(collection, predicate, t -> true).getOrElse(false);
}
public static <T, U> U reduce(Collection<T> list, U identity, BiFunction<U, T, U> f) {
return foldLeft(list, identity, u -> t -> f.apply(u, t));
}
/* 集合拼接 */
@SafeVarargs
public static <T> List<T> concat(@Nullable List<T> list, @Nullable List<T>... lists) {
List<T> resultList = list == null ? new ArrayList<>() : new ArrayList<>(list);
if (lists != null && lists.length > 0) {
for (List<T> l : lists) {
if (isNotEmpty(l)) {
resultList.addAll(l);
}
}
}
return resultList;
}
/**
* 将函数function执行count次,并将结果收集到列表中
*
* @param count 执行的次数
* @param function 要执行的函数
* @return 收集的结果
*/
public static <T> List<T> doTimes(int count, Function<? super Integer, T> function) {
ArrayList<T> list = new ArrayList<>(count);
for (int i = 0; i < count; i++) {
list.add(function.apply(i));
}
return list;
}
/**
* 将过程consumer执行count次,忽略结果
*
* @param count 执行的次数
* @param consumer 要执行的过程
*/
public static void doTimes(int count, Consumer<? super Integer> consumer) {
for (int i = 0; i < count; i++) {
consumer.accept(i);
}
}
/* 确保List不为null*/
@NonNull
public static <T> List<T> ensure(List<T> list) {
return list == null ? new ArrayList<>() : list;
}
/* 确保Set不为null */
@NonNull
public static <T> Set<T> ensure(Set<T> set) {
return set == null ? new HashSet<>() : set;
}
/*确保Map不为null*/
public static <K, V> Map<K, V> ensure(Map<K, V> map) {
return map == null ? new HashMap<>() : map;
}
}
版权声明:本文为zssrxt原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。