mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-04-19 03:01:48 +08:00
commit
25196520d6
@ -11,6 +11,42 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* 日期格式化类,提供常用的日期格式化对象
|
||||
*
|
||||
* <p>所有的jdk日期格式模式字符串 jdk18 date format pattern
|
||||
* <a href="https://docs.oracle.com/en/java/javase/18/docs/api/java.base/java/time/format/DateTimeFormatter.html">
|
||||
* <i>jdk date format pattern (Pattern Letters and Symbols) 日期格式模式字符串</i>
|
||||
* </a>
|
||||
* </p>
|
||||
*
|
||||
* <h2>工具类,提供格式化字符串很多,但是对于具体什么含义,不够清晰,这里进行说明:</h2>
|
||||
* <p>
|
||||
* <b>常见日期格式模式字符串:</b>
|
||||
* <ul>
|
||||
* <li>yyyy-MM-dd 示例:2022-08-05</li>
|
||||
* <li>yyyy年MM月dd日 示例:2022年08月05日</li>
|
||||
* <li>yyyy-MM-dd HH:mm:ss 示例:2022-08-05 12:59:59</li>
|
||||
* <li>yyyy-MM-dd HH:mm:ss.SSS 示例:2022-08-05 12:59:59.559</li>
|
||||
* <li>yyyy-MM-dd HH:mm:ss.SSSZ 示例:2022-08-05 12:59:59.559+0800, 年月日 时分秒 毫秒 时区</li>
|
||||
* <li>yyyy-MM-dd HH:mm:ss.SSSz 示例:2022-08-05 12:59:59.559UTC+08:00,年月日 时分秒 毫秒 时区</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ss.SSS'Z' 示例:2022-08-05T12:59:59.559Z, 其中:''单引号表示转义字符,T:分隔符,Z:一般值UTC,0时区的时间含义</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ss.SSSZ 示例:2022-08-05T11:59:59.559+0800, 其中:Z,表示时区</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ss.SSSX 示例:2022-08-05T12:59:59.559+08, 其中:X:两位时区,+08表示:东8区,中国时区</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ss.SSSXX 示例:2022-08-05T12:59:59.559+0800, 其中:XX:四位时区</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ss.SSSXXX 示例:2022-08-05T12:59:59.559+08:00, 其中:XX:五位时区</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ss 示例:2022-08-05T12:59:59+08</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ssXXX 示例:2022-08-05T12:59:59+08:00</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ssZ 示例:2022-08-05T12:59:59+0800</li>
|
||||
* <li>yyyy-MM-dd'T'HH:mm:ss'Z' 示例:2022-08-05T12:59:59Z</li>
|
||||
* <li>EEE MMM dd HH:mm:ss z yyyy 示例:周五 8月 05 12:59:00 UTC+08:00 2022</li>
|
||||
* <li>EEE MMM dd HH:mm:ss zzz yyyy 示例:周五 8月 05 12:59:00 UTC+08:00 2022,其中z表示UTC时区,但:1~3个z没有任何区别</li>
|
||||
* <li>EEE, dd MMM yyyy HH:mm:ss z 示例:周五, 05 8月 2022 12:59:59 UTC+08:00</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
*
|
||||
* 系统提供的,请查看,有大量定义好的格式化对象,可以直接使用,如:
|
||||
* {@link DateTimeFormatter#ISO_DATE}
|
||||
* {@link DateTimeFormatter#ISO_DATE_TIME}
|
||||
* 查看更多,请参阅上述官方文档
|
||||
*
|
||||
* @author Looly
|
||||
*/
|
||||
public class DatePattern {
|
||||
@ -291,11 +327,11 @@ public class DatePattern {
|
||||
public static final FastDateFormat UTC_MS_FORMAT = FastDateFormat.getInstance(UTC_MS_PATTERN, TimeZone.getTimeZone("UTC"));
|
||||
|
||||
/**
|
||||
* UTC时间:yyyy-MM-dd'T'HH:mm:ssZ
|
||||
* UTC时间:yyyy-MM-dd'T'HH:mm:ss.SSSZ
|
||||
*/
|
||||
public static final String UTC_MS_WITH_ZONE_OFFSET_PATTERN = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
|
||||
/**
|
||||
* UTC时间{@link FastDateFormat}:yyyy-MM-dd'T'HH:mm:ssZ
|
||||
* UTC时间{@link FastDateFormat}:yyyy-MM-dd'T'HH:mm:ss.SSSZ
|
||||
*/
|
||||
public static final FastDateFormat UTC_MS_WITH_ZONE_OFFSET_FORMAT = FastDateFormat.getInstance(UTC_MS_WITH_ZONE_OFFSET_PATTERN, TimeZone.getTimeZone("UTC"));
|
||||
|
||||
|
@ -158,7 +158,7 @@ public class FastStream<T> implements Stream<T>, Iterable<T> {
|
||||
public static <T> FastStream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) {
|
||||
Objects.requireNonNull(next);
|
||||
Objects.requireNonNull(hasNext);
|
||||
return new FastStream<>(StreamHelper.iterate(seed, hasNext, next));
|
||||
return new FastStream<>(StreamUtil.iterate(seed, hasNext, next));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -674,10 +674,8 @@ public class FastStream<T> implements Stream<T>, Iterable<T> {
|
||||
* @param <A> 给定的数组类型
|
||||
* @return 包含此流元素的指定的数组
|
||||
* @throws ArrayStoreException 如果元素转换失败,例如不是该元素类型及其父类,则抛出该异常
|
||||
* <p>
|
||||
* 例如以下代码编译正常,但运行时会抛出 {@link ArrayStoreException}
|
||||
* <pre>{@code String[] strings = Stream.<Integer>builder().add(1).build().toArray(String[]::new); }</pre>
|
||||
* </p>
|
||||
* 例如以下代码编译正常,但运行时会抛出 {@link ArrayStoreException}
|
||||
* <pre>{@code String[] strings = Stream.<Integer>builder().add(1).build().toArray(String[]::new); }</pre>
|
||||
*/
|
||||
@Override
|
||||
public <A> A[] toArray(IntFunction<A[]> generator) {
|
||||
@ -1441,7 +1439,7 @@ public class FastStream<T> implements Stream<T>, Iterable<T> {
|
||||
*/
|
||||
public FastStream<T> takeWhile(Predicate<? super T> predicate) {
|
||||
Objects.requireNonNull(predicate);
|
||||
return of(StreamHelper.takeWhile(stream, predicate));
|
||||
return of(StreamUtil.takeWhile(stream, predicate));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1477,7 +1475,7 @@ public class FastStream<T> implements Stream<T>, Iterable<T> {
|
||||
*/
|
||||
public FastStream<T> dropWhile(Predicate<? super T> predicate) {
|
||||
Objects.requireNonNull(predicate);
|
||||
return of(StreamHelper.dropWhile(stream, predicate));
|
||||
return of(StreamUtil.dropWhile(stream, predicate));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1492,6 +1490,24 @@ public class FastStream<T> implements Stream<T>, Iterable<T> {
|
||||
return dropWhile(predicate);
|
||||
}
|
||||
|
||||
/**
|
||||
* 流是否为空
|
||||
*
|
||||
* @return 流是否为空
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return !findAny().isPresent();
|
||||
}
|
||||
|
||||
/**
|
||||
* 流是否不为空
|
||||
*
|
||||
* @return 流是否不为空
|
||||
*/
|
||||
public boolean isNotEmpty() {
|
||||
return !isEmpty();
|
||||
}
|
||||
|
||||
public interface FastStreamBuilder<T> extends Consumer<T>, cn.hutool.core.builder.Builder<FastStream<T>> {
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,9 @@ package cn.hutool.core.stream;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.io.IORuntimeException;
|
||||
import cn.hutool.core.lang.Assert;
|
||||
import cn.hutool.core.stream.spliterators.DropWhileSpliterator;
|
||||
import cn.hutool.core.stream.spliterators.IterateSpliterator;
|
||||
import cn.hutool.core.stream.spliterators.TakeWhileSpliterator;
|
||||
import cn.hutool.core.util.CharsetUtil;
|
||||
|
||||
import java.io.File;
|
||||
@ -10,16 +13,20 @@ import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.stream.StreamSupport;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
/**
|
||||
* {@link Stream} 工具类
|
||||
*
|
||||
* @author looly
|
||||
* @author looly emptypoint VampireAchao
|
||||
* @since 5.6.7
|
||||
*/
|
||||
public class StreamUtil {
|
||||
@ -141,4 +148,84 @@ public class StreamUtil {
|
||||
final Function<T, ? extends CharSequence> toStringFunc) {
|
||||
return stream.collect(CollectorUtil.joining(delimiter, toStringFunc));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回无限有序流
|
||||
* 该流由 初始值 然后判断条件 以及执行 迭代函数 进行迭代获取到元素
|
||||
*
|
||||
* @param <T> 元素类型
|
||||
* @param seed 初始值
|
||||
* @param hasNext 条件值
|
||||
* @param next 用上一个元素作为参数执行并返回一个新的元素
|
||||
* @return 无限有序流
|
||||
*/
|
||||
public static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) {
|
||||
requireNonNull(next);
|
||||
requireNonNull(hasNext);
|
||||
return StreamSupport.stream(IterateSpliterator.create(seed, hasNext, next), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保留 与指定断言 匹配时的元素, 在第一次不匹配时终止, 抛弃当前(第一个不匹配元素)及后续所有元素
|
||||
* <p>与 jdk9 中的 takeWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作</p>
|
||||
* <p>本环节中是顺序执行的, 但是后续操作可以支持并行流</p>
|
||||
* <p>但是不建议在并行流中使用, 除非你确定 takeWhile 之后的操作能在并行流中受益很多</p>
|
||||
*
|
||||
* @param source 源流
|
||||
* @param <T> 元素类型
|
||||
* @param predicate 断言
|
||||
* @return 与指定断言匹配的元素组成的流
|
||||
*/
|
||||
public static <T> Stream<T> takeWhile(Stream<T> source, Predicate<? super T> predicate) {
|
||||
requireNonNull(source);
|
||||
requireNonNull(predicate);
|
||||
return createStatefulNewStream(source, TakeWhileSpliterator.create(source.spliterator(), predicate));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除 与指定断言 匹配的元素, 在第一次不匹配时终止, 返回当前(第一个不匹配元素)及剩余元素组成的新流
|
||||
* <p>与 jdk9 中的 dropWhile 方法不太一样, 这里的实现是个 顺序的、有状态的中间操作</p>
|
||||
* <p>本环节中是顺序执行的, 但是后续操作可以支持并行流</p>
|
||||
* <p>但是不建议在并行流中使用, 除非你确定 dropWhile 之后的操作能在并行流中受益很多</p>
|
||||
*
|
||||
* @param source 源流
|
||||
* @param <T> 元素类型
|
||||
* @param predicate 断言
|
||||
* @return 剩余元素组成的流
|
||||
*/
|
||||
public static <T> Stream<T> dropWhile(Stream<T> source, Predicate<? super T> predicate) {
|
||||
requireNonNull(source);
|
||||
requireNonNull(predicate);
|
||||
return createStatefulNewStream(source, DropWhileSpliterator.create(source.spliterator(), predicate));
|
||||
}
|
||||
|
||||
// region 私有方法
|
||||
/* ================================================== 私有方法 =================================================== */
|
||||
|
||||
/**
|
||||
* 根据 源流 和 新的Spliterator 生成新的流
|
||||
* <p>这是一个 顺序的、有状态的流</p>
|
||||
* <p>在新流的第一个节点是顺序执行的, 但是后续操作可以支持并行流</p>
|
||||
*
|
||||
* @param source 源流
|
||||
* @param newSpliterator 新流的Spliterator
|
||||
* @param <T> 旧流的元素类型
|
||||
* @param <R> 新流的元素类型
|
||||
* @return 新流
|
||||
*/
|
||||
private static <T, R> Stream<R> createStatefulNewStream(Stream<T> source, Spliterator<R> newSpliterator) {
|
||||
// 创建新流
|
||||
Stream<R> newStream = StreamSupport.stream(newSpliterator, source.isParallel());
|
||||
// 如果旧流是并行流, 新流主动调用一个有状态的操作, 虽然没有意义, 但是可以让后续的无状态节点正常并发
|
||||
if (source.isParallel()) {
|
||||
newStream = newStream.limit(Long.MAX_VALUE);
|
||||
}
|
||||
// 由于新流不与旧流的节点关联, 所以需要主动设置旧流的close方法, 哪怕几乎不可能有人在旧流上设置onClose操作
|
||||
return newStream.onClose(source::close);
|
||||
}
|
||||
|
||||
/* ============================================================================================================== */
|
||||
// endregion
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
package cn.hutool.core.stream.spliterators;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* dropWhile 的 Spliterator
|
||||
* <p>借鉴自StreamEx</p>
|
||||
*
|
||||
* @author emptypoint
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class DropWhileSpliterator<T> implements Spliterator<T> {
|
||||
|
||||
public static <T> DropWhileSpliterator<T> create(Spliterator<T> source, Predicate<? super T> predicate) {
|
||||
return new DropWhileSpliterator<>(source, predicate);
|
||||
}
|
||||
|
||||
private final Spliterator<T> source;
|
||||
private final Predicate<? super T> predicate;
|
||||
private boolean isFound = false;
|
||||
|
||||
private DropWhileSpliterator(Spliterator<T> source, Predicate<? super T> predicate) {
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super T> action) {
|
||||
boolean hasNext = true;
|
||||
// 如果 还没找到 并且 流中还有元素 继续找
|
||||
while (!isFound && hasNext) {
|
||||
hasNext = source.tryAdvance(e -> {
|
||||
if (!predicate.test(e)) {
|
||||
// 第一次不匹配
|
||||
isFound = true;
|
||||
action.accept(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// 对找到的元素进行后续处理
|
||||
if (isFound) {
|
||||
source.forEachRemaining(action);
|
||||
}
|
||||
|
||||
// 该环节已经处理完成
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<T> trySplit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
return Long.MAX_VALUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return source.characteristics() & ~Spliterator.SIZED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<? super T> getComparator() {
|
||||
return source.getComparator();
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package cn.hutool.core.stream.spliterators;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Spliterator;
|
||||
import java.util.Spliterators;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
/**
|
||||
* 无限有序流 的Spliterator
|
||||
*
|
||||
* @author VampireAchao
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class IterateSpliterator<T> extends Spliterators.AbstractSpliterator<T> {
|
||||
private final T seed;
|
||||
private final Predicate<? super T> hasNext;
|
||||
private final UnaryOperator<T> next;
|
||||
private T prev;
|
||||
private boolean started;
|
||||
private boolean finished;
|
||||
|
||||
/**
|
||||
* Creates a spliterator reporting the given estimated size and
|
||||
* additionalCharacteristics.
|
||||
*/
|
||||
IterateSpliterator(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) {
|
||||
super(Long.MAX_VALUE, Spliterator.ORDERED | Spliterator.IMMUTABLE);
|
||||
this.seed = seed;
|
||||
this.hasNext = hasNext;
|
||||
this.next = next;
|
||||
}
|
||||
|
||||
public static <T> IterateSpliterator<T> create(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next) {
|
||||
return new IterateSpliterator<>(seed, hasNext, next);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super T> action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (finished) {
|
||||
return false;
|
||||
}
|
||||
T t;
|
||||
if (started) {
|
||||
t = next.apply(prev);
|
||||
} else {
|
||||
t = seed;
|
||||
started = true;
|
||||
}
|
||||
if (!hasNext.test(t)) {
|
||||
prev = null;
|
||||
finished = true;
|
||||
return false;
|
||||
}
|
||||
prev = t;
|
||||
action.accept(prev);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEachRemaining(Consumer<? super T> action) {
|
||||
Objects.requireNonNull(action);
|
||||
if (finished) {
|
||||
return;
|
||||
}
|
||||
finished = true;
|
||||
T t = started ? next.apply(prev) : seed;
|
||||
prev = null;
|
||||
while (hasNext.test(t)) {
|
||||
action.accept(t);
|
||||
t = next.apply(t);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
package cn.hutool.core.stream.spliterators;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.Spliterator;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* takeWhile 的 Spliterator
|
||||
* <p>借鉴自StreamEx</p>
|
||||
*
|
||||
* @author emptypoint
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public class TakeWhileSpliterator<T> implements Spliterator<T> {
|
||||
|
||||
public static <T> TakeWhileSpliterator<T> create(Spliterator<T> source, Predicate<? super T> predicate) {
|
||||
return new TakeWhileSpliterator<>(source, predicate);
|
||||
}
|
||||
|
||||
private final Spliterator<T> source;
|
||||
private final Predicate<? super T> predicate;
|
||||
private boolean isContinue = true;
|
||||
|
||||
TakeWhileSpliterator(Spliterator<T> source, Predicate<? super T> predicate) {
|
||||
this.source = source;
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tryAdvance(Consumer<? super T> action) {
|
||||
boolean hasNext = true;
|
||||
// 如果 还可以继续 并且 流中还有元素 则继续遍历
|
||||
while (isContinue && hasNext) {
|
||||
hasNext = source.tryAdvance(e -> {
|
||||
if (predicate.test(e)) {
|
||||
action.accept(e);
|
||||
} else {
|
||||
// 终止遍历剩下的元素
|
||||
isContinue = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
// 该环节已经处理完成
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<T> trySplit() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long estimateSize() {
|
||||
return isContinue ? source.estimateSize() : 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int characteristics() {
|
||||
return source.characteristics() & ~(Spliterator.SIZED | Spliterator.SUBSIZED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Comparator<? super T> getComparator() {
|
||||
return source.getComparator();
|
||||
}
|
||||
}
|
||||
|
@ -575,11 +575,11 @@ public class RandomUtil {
|
||||
if (StrUtil.isEmpty(baseString)) {
|
||||
return StrUtil.EMPTY;
|
||||
}
|
||||
final StringBuilder sb = new StringBuilder(length);
|
||||
|
||||
if (length < 1) {
|
||||
if(length < 1){
|
||||
length = 1;
|
||||
}
|
||||
|
||||
final StringBuilder sb = new StringBuilder(length);
|
||||
final int baseLength = baseString.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
final int number = randomInt(baseLength);
|
||||
|
@ -140,4 +140,5 @@ public class DateTimeTest {
|
||||
final String a = "2021-09-27 00:00:99";
|
||||
new DateTime(a, DatePattern.NORM_DATETIME_FORMAT, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,13 +8,7 @@ import lombok.NoArgsConstructor;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
@ -24,6 +18,12 @@ import java.util.stream.Stream;
|
||||
*/
|
||||
public class OptTest {
|
||||
|
||||
@Test
|
||||
public void ofTest() {
|
||||
Assert.assertTrue(Opt.of(Optional.empty()).isEmpty());
|
||||
Assert.assertTrue(Opt.of(Optional.of(1)).isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ofBlankAbleTest() {
|
||||
// ofBlankAble相对于ofNullable考虑了字符串为空串的情况
|
||||
|
@ -193,6 +193,8 @@ public class FastStreamTest {
|
||||
|
||||
flatMapIter = FastStream.of(list).flatMapIter(e -> Arrays.asList(e, e * 10)).toList();
|
||||
Assert.assertEquals(ListUtil.of(1, 10, 2, 20, 3, 30), flatMapIter);
|
||||
// 不报npe测试
|
||||
Assert.assertTrue(FastStream.of(list).flatMapIter(e -> null).isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -310,6 +312,9 @@ public class FastStreamTest {
|
||||
List<String> list = Arrays.asList("dromara", "hutool", "sweet");
|
||||
List<String> zip = FastStream.of(orders).zip(list, (e1, e2) -> e1 + "." + e2).toList();
|
||||
Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), zip);
|
||||
|
||||
zip = FastStream.iterate(1, i -> i + 1).zip(list, (e1, e2) -> e1 + "." + e2).toList();
|
||||
Assert.assertEquals(Arrays.asList("1.dromara", "2.hutool", "3.sweet"), zip);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -388,4 +393,9 @@ public class FastStreamTest {
|
||||
Assert.assertEquals(Arrays.asList(5, 7, 9), res2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsNotEmpty() {
|
||||
Assert.assertTrue(FastStream.of(1).isNotEmpty());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -75,6 +75,12 @@ public class RandomUtilTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void randomStringOfLengthTest(){
|
||||
final String s = RandomUtil.randomString("123", -1);
|
||||
Assert.assertNotNull(s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void generateRandomNumberTest(){
|
||||
final int[] ints = RandomUtil.randomPickInts(5, NumberUtil.range(5, 20));
|
||||
|
@ -195,4 +195,10 @@ public class CRUDTest {
|
||||
MapUtil.of("ids", new int[]{1, 2, 3}));
|
||||
Assert.assertEquals(2, results.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void findWithDotTest(){
|
||||
db.find(Entity.of("user").set("WTUR.Other.Rg.S.WTName", "value"));
|
||||
}
|
||||
}
|
||||
|
17
hutool-json/src/test/java/cn/hutool/json/Issue2507Test.java
Executable file
17
hutool-json/src/test/java/cn/hutool/json/Issue2507Test.java
Executable file
@ -0,0 +1,17 @@
|
||||
package cn.hutool.json;
|
||||
|
||||
import cn.hutool.core.lang.Console;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class Issue2507Test {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void xmlToJsonTest(){
|
||||
String xml = "<MsgInfo> <Msg> <![CDATA[<msg><body><row action=\"select\"><DIET>低盐饮食[嘱托]]><![CDATA[]</DIET></row></body></msg>]]> </Msg> <Msg> <![CDATA[<msg><body><row action=\"select\"><DIET>流质饮食</DIET></row></body></msg>]]> </Msg> </MsgInfo>";
|
||||
JSONObject jsonObject = JSONUtil.xmlToJson(xml);
|
||||
|
||||
Console.log(jsonObject.toStringPretty());
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user