This commit is contained in:
Looly 2023-05-06 02:41:53 +08:00
parent 78d4a6ee1d
commit 854f1d064d
7 changed files with 194 additions and 5 deletions

View File

@ -0,0 +1,59 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.lang.selector;
import java.util.ArrayList;
/**
* 简单的轮询选择器
*
* @param <T> 元素类型
* @author Looly
* @since 6.0.0
*/
public class IncrementSelector<T> extends ArrayList<T> implements Selector<T> {
private static final long serialVersionUID = 1L;
private int position;
// region ----- Constructors
/**
* 构造
*/
public IncrementSelector() {
super();
}
/**
* 构造
*
* @param objList 对象列表
*/
public IncrementSelector(final Iterable<T> objList) {
this();
for (final T obj : objList) {
add(obj);
}
}
// endregion
@Override
public T select() {
final T result = get(position);
if(position >= size()){
position = 0;
}
return result;
}
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.lang.selector;
import org.dromara.hutool.core.util.RandomUtil;
import java.util.ArrayList;
/**
* 随机选择器
*
* @param <T> 元素类型
* @author Looly
* @since 6.0.0
*/
public class RandomSelector<T> extends ArrayList<T> implements Selector<T> {
private static final long serialVersionUID = 1L;
// region ----- Constructors
/**
* 构造
*/
public RandomSelector() {
super();
}
/**
* 构造
*
* @param objList 对象列表
*/
public RandomSelector(final Iterable<T> objList) {
this();
for (final T obj : objList) {
add(obj);
}
}
// endregion
@Override
public T select() {
return get(RandomUtil.randomInt(0, size()));
}
}

View File

@ -26,5 +26,5 @@ public interface Selector<T> {
*
* @return 下一个对象
*/
T next();
T select();
}

View File

@ -121,7 +121,7 @@ public class SmoothWeightSelector<T> implements Selector<T> {
* @return 选中的对象
*/
@Override
public T next() {
public T select() {
if (CollUtil.isEmpty(this.objList)) {
return null;
}

View File

@ -145,7 +145,7 @@ public class WeightRandomSelector<T> implements Selector<T>, Serializable {
* @return 随机对象
*/
@Override
public T next() {
public T select() {
final int randomWeight = (int) (this.weightMap.lastKey() * Math.random());
final SortedMap<Integer, T> tailMap = this.weightMap.tailMap(randomWeight, false);
return this.weightMap.get(tailMap.firstKey());

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2023 looly(loolly@aliyun.com)
* Hutool is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
package org.dromara.hutool.core.lang.selector;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class SmoothWeightSelectorTest {
@Test
public void selectTest() {
final SmoothWeightSelector<String> selector = SmoothWeightSelector.of();
selector.add("A", 10);
selector.add("B", 50);
selector.add("C", 100);
final String result = selector.select();
Assertions.assertTrue(ListUtil.of("A", "B", "C").contains(result));
}
@Test
public void selectCountTest() {
final SmoothWeightSelector<String> selector = SmoothWeightSelector.of();
selector.add("A", 10);
selector.add("B", 50);
selector.add("C", 100);
final List<String> resultList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
resultList.add(selector.select());
}
final Map<String, Integer> countMap = CollUtil.countMap(resultList);
Assertions.assertEquals(63, countMap.get("A"));
Assertions.assertEquals(312, countMap.get("B"));
Assertions.assertEquals(625, countMap.get("C"));
}
}

View File

@ -12,20 +12,42 @@
package org.dromara.hutool.core.lang.selector;
import org.dromara.hutool.core.collection.CollUtil;
import org.dromara.hutool.core.collection.ListUtil;
import org.dromara.hutool.core.lang.Console;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import java.util.ArrayList;
import java.util.List;
public class WeightRandomSelectorTest {
@Test
public void weightRandomTest() {
public void selectTest() {
final WeightRandomSelector<String> random = WeightRandomSelector.of();
random.add("A", 10);
random.add("B", 50);
random.add("C", 100);
final String result = random.next();
final String result = random.select();
Assertions.assertTrue(ListUtil.of("A", "B", "C").contains(result));
}
@Test
@Disabled
public void selectCountTest() {
final WeightRandomSelector<String> random = WeightRandomSelector.of();
random.add("A", 10);
random.add("B", 50);
random.add("C", 100);
final List<String> resultList = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
resultList.add(random.select());
}
Console.log(CollUtil.countMap(resultList));
}
}