!1385 修正开闭区间错误

Merge pull request !1385 from 身有光名/v7-dev
This commit is contained in:
Looly 2025-11-06 07:47:00 +00:00 committed by Gitee
commit 4e0d106e91
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
6 changed files with 96 additions and 24 deletions

View File

@ -200,8 +200,14 @@ class FiniteBound<T extends Comparable<? super T>> implements Bound<T> {
if (bt1 == bt2) {
return 0;
}
// 一为左边界一为右边界则左边界恒在右边界后
// 一为左边界一为右边界
if (bt1.isDislocated(bt2)) {
// 特殊情况右闭区间与左闭区间在同一点时认为它们重合用于区间相交判断
if ((bt1 == BoundType.CLOSE_UPPER_BOUND && bt2 == BoundType.CLOSE_LOWER_BOUND) ||
(bt1 == BoundType.CLOSE_LOWER_BOUND && bt2 == BoundType.CLOSE_UPPER_BOUND)) {
return 0;
}
// 一般情况左边界恒在右边界后
return bt1.isLowerBound() ? 1 : -1;
}
// 都为左边界则封闭边界在前若都为右边界则封闭边界在后

View File

@ -165,6 +165,10 @@ public class Range<T> implements Iterable<T>, Serializable {
* @return 下一步进
*/
private T safeStep(final T base) {
// 添加边界检查
if (base == null || (base.equals(end))) {
return null;
}
final int index = this.index;
T next = null;
try {

View File

@ -52,7 +52,8 @@ public class PhantomObj<T> extends PhantomReference<T> implements Ref<T>{
if (other == this) {
return true;
} else if (other instanceof PhantomObj) {
return ObjUtil.equals(((PhantomObj<?>) other).get(), get());
// 比较原始对象的哈希码因为虚引用无法获取原始对象
return this.hashCode == ((PhantomObj<?>)other).hashCode;
}
return false;
}

View File

@ -17,14 +17,28 @@
package cn.hutool.v7.core.lang.range;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* test for {@link Bound}
*/
@SuppressWarnings("EqualsWithItself")
public class BoundTest {
@Test
@DisplayName("测试相邻区间合并")
void testUnionIfIntersectedWithAdjacentRanges() {
BoundedRange<Integer> range1 = BoundedRange.close(1, 3);
BoundedRange<Integer> range2 = BoundedRange.close(3, 5);
BoundedRange<Integer> result = BoundedRangeOperation.unionIfIntersected(range1, range2);
assertEquals(Bound.atLeast(1), result.getLowerBound());
assertEquals(Bound.atMost(5), result.getUpperBound());
}
@Test
public void testEquals() {
final Bound<Integer> bound = new FiniteBound<>(1, BoundType.OPEN_UPPER_BOUND);

View File

@ -22,13 +22,17 @@ import cn.hutool.v7.core.date.DateTime;
import cn.hutool.v7.core.date.DateUtil;
import cn.hutool.v7.core.text.StrUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import static org.junit.jupiter.api.Assertions.assertEquals;
/**
* {@link Range} 单元测试
*
@ -36,6 +40,18 @@ import java.util.NoSuchElementException;
*/
public class RangeTest {
@Test
@DisplayName("测试不包含起始元素的迭代")
void testIteratorWithoutIncludeStart() {
Range<Integer> range = new Range<>(1, 5, (current, end, index) -> current + 1, false, true);
List<Integer> elements = new ArrayList<>();
for (Integer i : range) {
elements.add(i);
}
assertEquals(List.of(2, 3, 4, 5), elements);
}
@Test
public void dateRangeTest() {
final DateTime start = DateUtil.parse("2017-01-01");
@ -50,9 +66,9 @@ public class RangeTest {
final Iterator<DateTime> iterator = range.iterator();
Assertions.assertTrue(iterator.hasNext());
Assertions.assertEquals(DateUtil.parse("2017-01-01"), iterator.next());
assertEquals(DateUtil.parse("2017-01-01"), iterator.next());
Assertions.assertTrue(iterator.hasNext());
Assertions.assertEquals(DateUtil.parse("2017-01-02"), iterator.next());
assertEquals(DateUtil.parse("2017-01-02"), iterator.next());
Assertions.assertFalse(iterator.hasNext());
}
@ -75,11 +91,11 @@ public class RangeTest {
final StringBuilder sb = new StringBuilder();
DateUtil.rangeConsume(start, end, DateField.DAY_OF_YEAR, a -> sb.append(DateTime.of(a).dayOfMonth()).append("#"));
Assertions.assertEquals("1#2#3#", sb.toString());
assertEquals("1#2#3#", sb.toString());
final StringBuilder sb2 = new StringBuilder();
DateUtil.rangeConsume(null, null, DateField.DAY_OF_YEAR, a -> sb2.append(DateTime.of(a).dayOfMonth()).append("#"));
Assertions.assertEquals(StrUtil.EMPTY, sb2.toString());
assertEquals(StrUtil.EMPTY, sb2.toString());
}
@Test
@ -90,11 +106,11 @@ public class RangeTest {
final DateRange range = DateUtil.range(start, end, DateField.MONTH);
final Iterator<DateTime> iterator = range.iterator();
Assertions.assertTrue(iterator.hasNext());
Assertions.assertEquals(DateUtil.parse("2021-01-31"), iterator.next());
assertEquals(DateUtil.parse("2021-01-31"), iterator.next());
Assertions.assertTrue(iterator.hasNext());
Assertions.assertEquals(DateUtil.parse("2021-02-28"), iterator.next());
assertEquals(DateUtil.parse("2021-02-28"), iterator.next());
Assertions.assertTrue(iterator.hasNext());
Assertions.assertEquals(DateUtil.parse("2021-03-31"), iterator.next());
assertEquals(DateUtil.parse("2021-03-31"), iterator.next());
Assertions.assertFalse(iterator.hasNext());
}
@ -104,7 +120,7 @@ public class RangeTest {
final Iterator<Integer> iterator = range.iterator();
Assertions.assertTrue(iterator.hasNext());
Assertions.assertEquals(Integer.valueOf(1), iterator.next());
assertEquals(Integer.valueOf(1), iterator.next());
Assertions.assertFalse(iterator.hasNext());
}
@ -116,9 +132,9 @@ public class RangeTest {
// 测试包含开始和结束情况下步进为1的情况
DateRange range = DateUtil.range(start, end, DateField.DAY_OF_YEAR);
Iterator<DateTime> iterator = range.iterator();
Assertions.assertEquals(iterator.next(), DateUtil.parse("2017-01-01"));
Assertions.assertEquals(iterator.next(), DateUtil.parse("2017-01-02"));
Assertions.assertEquals(iterator.next(), DateUtil.parse("2017-01-03"));
assertEquals(iterator.next(), DateUtil.parse("2017-01-01"));
assertEquals(iterator.next(), DateUtil.parse("2017-01-02"));
assertEquals(iterator.next(), DateUtil.parse("2017-01-03"));
try {
iterator.next();
Assertions.fail("已超过边界,下一个元素不应该存在!");
@ -128,8 +144,8 @@ public class RangeTest {
// 测试多步进的情况
range = new DateRange(start, end, DateField.DAY_OF_YEAR, 2);
iterator = range.iterator();
Assertions.assertEquals(DateUtil.parse("2017-01-01"), iterator.next());
Assertions.assertEquals(DateUtil.parse("2017-01-03"), iterator.next());
assertEquals(DateUtil.parse("2017-01-01"), iterator.next());
assertEquals(DateUtil.parse("2017-01-03"), iterator.next());
}
@Test
@ -140,9 +156,9 @@ public class RangeTest {
// 测试不包含开始结束时间的情况
final DateRange range = new DateRange(start, end, DateField.DAY_OF_YEAR, 1, false, false);
final Iterator<DateTime> iterator = range.iterator();
Assertions.assertEquals(DateUtil.parse("2017-01-02"), iterator.next());
Assertions.assertEquals(DateUtil.parse("2017-01-03"), iterator.next());
Assertions.assertEquals(DateUtil.parse("2017-01-04"), iterator.next());
assertEquals(DateUtil.parse("2017-01-02"), iterator.next());
assertEquals(DateUtil.parse("2017-01-03"), iterator.next());
assertEquals(DateUtil.parse("2017-01-04"), iterator.next());
try {
iterator.next();
Assertions.fail("不包含结束时间情况下,下一个元素不应该存在!");
@ -156,8 +172,8 @@ public class RangeTest {
final Date end = DateUtil.parse("2017-01-31");
final List<DateTime> rangeToList = DateUtil.rangeToList(start, end, DateField.DAY_OF_YEAR);
Assertions.assertEquals(DateUtil.parse("2017-01-01"), rangeToList.get(0));
Assertions.assertEquals(DateUtil.parse("2017-01-02"), rangeToList.get(1));
assertEquals(DateUtil.parse("2017-01-01"), rangeToList.get(0));
assertEquals(DateUtil.parse("2017-01-02"), rangeToList.get(1));
}
@ -173,8 +189,8 @@ public class RangeTest {
final DateRange endRange = DateUtil.range(start1, end1, DateField.DAY_OF_YEAR);
// 交集
final List<DateTime> dateTimes = DateUtil.rangeContains(startRange, endRange);
Assertions.assertEquals(1, dateTimes.size());
Assertions.assertEquals(DateUtil.parse("2017-01-31"), dateTimes.get(0));
assertEquals(1, dateTimes.size());
assertEquals(DateUtil.parse("2017-01-31"), dateTimes.get(0));
}
@Test
@ -190,8 +206,8 @@ public class RangeTest {
// 差集
final List<DateTime> dateTimes1 = DateUtil.rangeNotContains(startRange, endRange);
Assertions.assertEquals(1, dateTimes1.size());
Assertions.assertEquals(DateUtil.parse("2017-01-31"), dateTimes1.get(0));
assertEquals(1, dateTimes1.size());
assertEquals(DateUtil.parse("2017-01-31"), dateTimes1.get(0));
}
}

View File

@ -0,0 +1,31 @@
package cn.hutool.v7.core.lang.ref;
import java.lang.ref.ReferenceQueue;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class PhantomObjTest {
private ReferenceQueue<String> queue;
private String testObject;
private PhantomObj<String> phantomObj;
@BeforeEach
void setUp() {
queue = new ReferenceQueue<>();
testObject = "test";
phantomObj = new PhantomObj<>(testObject, queue);
}
@Test
@DisplayName("测试 equals 方法与不同引用对象比较")
void testEqualsWithDifferentReferent() {
String differentObject = "different";
PhantomObj<String> anotherPhantomObj = new PhantomObj<>(differentObject, queue);
assertFalse(phantomObj.equals(anotherPhantomObj));
}
}