mirror of
https://gitee.com/dromara/hutool.git
synced 2025-04-05 17:37:59 +08:00
fix code
This commit is contained in:
parent
59b5a17ee6
commit
81cbb0d8a0
@ -53,7 +53,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
|
||||
treeEntryMap.forEach((k, v) -> {
|
||||
if (v.hasParent()) {
|
||||
final TreeEntry<K, V> parent = v.getDeclaredParent();
|
||||
putLinkedNode(parent.getKey(), parent.getValue(), v.getKey(), v.getValue());
|
||||
putLinkedNodes(parent.getKey(), parent.getValue(), v.getKey(), v.getValue());
|
||||
} else {
|
||||
putNode(v.getKey(), v.getValue());
|
||||
}
|
||||
@ -99,7 +99,7 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
|
||||
values.forEach(v -> {
|
||||
final K key = keyGenerator.apply(v);
|
||||
final K parentKey = parentKeyGenerator.apply(v);
|
||||
linkNode(parentKey, key);
|
||||
linkNodes(parentKey, key);
|
||||
get(key).setValue(v);
|
||||
});
|
||||
}
|
||||
@ -124,42 +124,54 @@ public interface ForestMap<K, V> extends Map<K, TreeEntry<K, V>> {
|
||||
* <li>若{@code parentKey}或{@code childKey}对应的节点存在,则会更新对应节点的值;</li>
|
||||
* </ul>
|
||||
* 该操作等同于:
|
||||
* <pre>
|
||||
* TreeEntry<K, V> parent = putNode(parentKey, parentValue);
|
||||
* TreeEntry<K, V> child = putNode(childKey, childValue);
|
||||
* linkNode(parentKey, childKey);
|
||||
* </pre>
|
||||
* <pre>{@code
|
||||
* putNode(parentKey, parentValue);
|
||||
* putNode(childKey, childValue);
|
||||
* linkNodes(parentKey, childKey);
|
||||
* }</pre>
|
||||
*
|
||||
* @param parentKey 父节点的key
|
||||
* @param parentValue 父节点的value
|
||||
* @param childKey 子节点的key
|
||||
* @param childValue 子节点的值
|
||||
*/
|
||||
default void putLinkedNode(K parentKey, V parentValue, K childKey, V childValue) {
|
||||
linkNode(parentKey, childKey, (parent, child) -> {
|
||||
parent.setValue(parentValue);
|
||||
child.setValue(childValue);
|
||||
});
|
||||
default void putLinkedNodes(K parentKey, V parentValue, K childKey, V childValue) {
|
||||
putNode(parentKey, parentValue);
|
||||
putNode(childKey, childValue);
|
||||
linkNodes(parentKey, childKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定的节点建立父子关系,若{@code parentKey}或{@code childKey}对应节点不存在,则会创建一个对应的值为null的空节点 <br>
|
||||
* 添加子节点,并为子节点指定父节点:
|
||||
* <ul>
|
||||
* <li>若{@code parentKey}或{@code childKey}对应的节点不存在,则会根据键值创建一个对应的节点;</li>
|
||||
* <li>若{@code parentKey}或{@code childKey}对应的节点存在,则会更新对应节点的值;</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param parentKey 父节点的key
|
||||
* @param childKey 子节点的key
|
||||
* @param childValue 子节点的值
|
||||
*/
|
||||
void putLinkedNodes(K parentKey, K childKey, V childValue);
|
||||
|
||||
/**
|
||||
* 为集合中的指定的节点建立父子关系
|
||||
*
|
||||
* @param parentKey 父节点的key
|
||||
* @param childKey 子节点的key
|
||||
*/
|
||||
default void linkNode(K parentKey, K childKey) {
|
||||
linkNode(parentKey, childKey, null);
|
||||
default void linkNodes(K parentKey, K childKey) {
|
||||
linkNodes(parentKey, childKey, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定的节点建立父子关系,若{@code parentKey}或{@code childKey}对应节点不存在,则会创建一个对应的值为null的空节点
|
||||
* 为集合中的指定的节点建立父子关系
|
||||
*
|
||||
* @param parentKey 父节点的key
|
||||
* @param childKey 子节点的key
|
||||
* @param consumer 对父节点和子节点的操作,允许为null
|
||||
*/
|
||||
void linkNode(K parentKey, K childKey, BiConsumer<TreeEntry<K, V>, TreeEntry<K, V>> consumer);
|
||||
void linkNodes(K parentKey, K childKey, BiConsumer<TreeEntry<K, V>, TreeEntry<K, V>> consumer);
|
||||
|
||||
/**
|
||||
* 若{@code parentKey}或{@code childKey}对应节点都存在,则移除指定该父节点与其直接关联的指定子节点间的引用关系
|
||||
|
@ -210,6 +210,48 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 同时添加父子节点:
|
||||
* <ul>
|
||||
* <li>若{@code parentKey}或{@code childKey}对应的节点不存在,则会根据键值创建一个对应的节点;</li>
|
||||
* <li>若{@code parentKey}或{@code childKey}对应的节点存在,则会更新对应节点的值;</li>
|
||||
* </ul>
|
||||
* 该操作等同于:
|
||||
* <pre>
|
||||
* TreeEntry<K, V> parent = putNode(parentKey, parentValue);
|
||||
* TreeEntry<K, V> child = putNode(childKey, childValue);
|
||||
* linkNodes(parentKey, childKey);
|
||||
* </pre>
|
||||
*
|
||||
* @param parentKey 父节点的key
|
||||
* @param parentValue 父节点的value
|
||||
* @param childKey 子节点的key
|
||||
* @param childValue 子节点的值
|
||||
*/
|
||||
@Override
|
||||
public void putLinkedNodes(K parentKey, V parentValue, K childKey, V childValue) {
|
||||
linkNodes(parentKey, childKey, (parent, child) -> {
|
||||
parent.setValue(parentValue);
|
||||
child.setValue(childValue);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加子节点,并为子节点指定父节点:
|
||||
* <ul>
|
||||
* <li>若{@code parentKey}或{@code childKey}对应的节点不存在,则会根据键值创建一个对应的节点;</li>
|
||||
* <li>若{@code parentKey}或{@code childKey}对应的节点存在,则会更新对应节点的值;</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param parentKey 父节点的key
|
||||
* @param childKey 子节点的key
|
||||
* @param childValue 子节点的值
|
||||
*/
|
||||
@Override
|
||||
public void putLinkedNodes(K parentKey, K childKey, V childValue) {
|
||||
linkNodes(parentKey, childKey, (parent, child) -> child.setValue(childValue));
|
||||
}
|
||||
|
||||
/**
|
||||
* 为指定的节点建立父子关系,若{@code parentKey}或{@code childKey}对应节点不存在,则会创建一个对应的值为null的空节点
|
||||
*
|
||||
@ -218,7 +260,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
|
||||
* @param consumer 对父节点和子节点的操作,允许为null
|
||||
*/
|
||||
@Override
|
||||
public void linkNode(K parentKey, K childKey, BiConsumer<TreeEntry<K, V>, TreeEntry<K, V>> consumer) {
|
||||
public void linkNodes(K parentKey, K childKey, BiConsumer<TreeEntry<K, V>, TreeEntry<K, V>> consumer) {
|
||||
consumer = ObjectUtil.defaultIfNull(consumer, (parent, child) -> {});
|
||||
final TreeEntryNode<K, V> parentNode = nodes.computeIfAbsent(parentKey, t -> new TreeEntryNode<>(null, t));
|
||||
TreeEntryNode<K, V> childNode = nodes.get(childKey);
|
||||
@ -358,6 +400,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
|
||||
*
|
||||
* @return 当前节点与根节点的距离
|
||||
*/
|
||||
@Override
|
||||
public int getWeight() {
|
||||
return weight;
|
||||
}
|
||||
@ -454,6 +497,17 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
|
||||
return traverseParentNodes(false, p -> {}, p -> p.equalsKey(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取以当前节点作为根节点的树结构,然后遍历所有节点
|
||||
*
|
||||
* @param includeSelf 是否处理当前节点
|
||||
* @param nodeConsumer 对节点的处理
|
||||
*/
|
||||
@Override
|
||||
public void forEachChild(boolean includeSelf, Consumer<TreeEntry<K, V>> nodeConsumer) {
|
||||
traverseChildNodes(includeSelf, (index, child) -> nodeConsumer.accept(child), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指定key与当前节点的key是否相等
|
||||
*
|
||||
@ -577,7 +631,7 @@ public class LinkedForestMap<K, V> implements ForestMap<K, V> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取以当前节点作为根节点的树结构,然后获取该树结构中的当前节点的全部子节点
|
||||
* 获取以当前节点作为根节点的树结构,然后按广度优先获取该树结构中的当前节点的全部子节点
|
||||
*
|
||||
* @return 节点
|
||||
*/
|
||||
|
@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* 允许拥有一个父节点与多个子节点的{@link Map.Entry}实现,
|
||||
@ -40,6 +41,13 @@ public interface TreeEntry<K, V> extends Map.Entry<K, V> {
|
||||
|
||||
// ===================== 父节点相关方法 =====================
|
||||
|
||||
/**
|
||||
* 获取以当前节点作为叶子节点的树结构,然后获取当前节点与根节点的距离
|
||||
*
|
||||
* @return 当前节点与根节点的距离
|
||||
*/
|
||||
int getWeight();
|
||||
|
||||
/**
|
||||
* 获取以当前节点作为叶子节点的树结构,然后获取该树结构的根节点
|
||||
*
|
||||
@ -81,6 +89,14 @@ public interface TreeEntry<K, V> extends Map.Entry<K, V> {
|
||||
return ObjectUtil.isNotNull(getParent(key));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取以当前节点作为根节点的树结构,然后遍历所有节点
|
||||
*
|
||||
* @param includeSelf 是否处理当前节点
|
||||
* @param nodeConsumer 对节点的处理
|
||||
*/
|
||||
void forEachChild(boolean includeSelf, Consumer<TreeEntry<K, V>> nodeConsumer);
|
||||
|
||||
// ===================== 子节点相关方法 =====================
|
||||
|
||||
/**
|
||||
|
@ -31,9 +31,9 @@ public class LinkedForestMapTest {
|
||||
@Before
|
||||
public void beforeTest() {
|
||||
// a -> b -> c -> d
|
||||
treeNodeMap.linkNode("a", "b");
|
||||
treeNodeMap.linkNode("b", "c");
|
||||
treeNodeMap.linkNode("c", "d");
|
||||
treeNodeMap.linkNodes("a", "b");
|
||||
treeNodeMap.linkNodes("b", "c");
|
||||
treeNodeMap.linkNodes("c", "d");
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -63,7 +63,7 @@ public class LinkedForestMapTest {
|
||||
Assert.assertEquals(CollUtil.newLinkedHashSet("a", "b", "c", "d"), transKey(treeNodeMap.getTreeNodes("d")));
|
||||
|
||||
// 循环依赖
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> treeNodeMap.linkNode("d", "a"));
|
||||
Assert.assertThrows(IllegalArgumentException.class, () -> treeNodeMap.linkNodes("d", "a"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -93,7 +93,7 @@ public class LinkedForestMapTest {
|
||||
@Test
|
||||
public void testReRegisterAfterRemove() {
|
||||
// a -> b -> c -> d
|
||||
treeNodeMap.linkNode("b", "c");
|
||||
treeNodeMap.linkNodes("b", "c");
|
||||
testRegisterBeforeRemove();
|
||||
}
|
||||
|
||||
@ -101,8 +101,8 @@ public class LinkedForestMapTest {
|
||||
public void testParallelRegister() {
|
||||
// a -> b -> c --> d
|
||||
// | -> c2 -> d2
|
||||
treeNodeMap.linkNode("b", "c2");
|
||||
treeNodeMap.linkNode("c2", "d2");
|
||||
treeNodeMap.linkNodes("b", "c2");
|
||||
treeNodeMap.linkNodes("c2", "d2");
|
||||
|
||||
// getDeclaredChildren
|
||||
Assert.assertEquals(CollUtil.newLinkedHashSet("b", "c", "d", "c2", "d2"), transKey(treeNodeMap.getChildNodes("a")));
|
||||
|
Loading…
Reference in New Issue
Block a user