|
@@ -17,48 +17,27 @@ import java.util.concurrent.ConcurrentHashMap;
|
|
|
*/
|
|
*/
|
|
|
public class FixedWaterLevelGenerator {
|
|
public class FixedWaterLevelGenerator {
|
|
|
|
|
|
|
|
- // 使用 ConcurrentHashMap 保证线程安全
|
|
|
|
|
- private static final Map<String, Double> deviceLevelMap = new ConcurrentHashMap<>();
|
|
|
|
|
|
|
+ private static final Map<String, Double> DEVICE_LEVEL_MAP = new ConcurrentHashMap<>();
|
|
|
|
|
|
|
|
- /** 水位最小值 */
|
|
|
|
|
private static final double MIN_VALUE = 0.02;
|
|
private static final double MIN_VALUE = 0.02;
|
|
|
- /** 水位最大值 */
|
|
|
|
|
private static final double MAX_VALUE = 0.05;
|
|
private static final double MAX_VALUE = 0.05;
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 获取设备固定水位(同一设备始终返回相同值)
|
|
|
|
|
- * <p>
|
|
|
|
|
- * 算法:基于 deviceId 的 hashCode 确定性映射到 [MIN_VALUE, MAX_VALUE] 区间内,
|
|
|
|
|
- * 无需做去重检查,天然保证不同设备大概率获得不同值。
|
|
|
|
|
- *
|
|
|
|
|
- * @param deviceId 设备ID
|
|
|
|
|
- * @return 固定水位值(保留2位小数)
|
|
|
|
|
- */
|
|
|
|
|
public static double getSensorValue(String deviceId) {
|
|
public static double getSensorValue(String deviceId) {
|
|
|
- return deviceLevelMap.computeIfAbsent(deviceId, id -> generateDeterministicValue(id));
|
|
|
|
|
|
|
+ return DEVICE_LEVEL_MAP.computeIfAbsent(deviceId, FixedWaterLevelGenerator::generateValue);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- /**
|
|
|
|
|
- * 基于设备ID确定性生成水位值
|
|
|
|
|
- * <p>
|
|
|
|
|
- * 使用 hashCode + 取模将任意 deviceId 均匀映射到目标区间,
|
|
|
|
|
- * 避免原 do-while + containsValue 在设备数量超过可选值数量时的死循环问题
|
|
|
|
|
- *
|
|
|
|
|
- * @param deviceId 设备ID
|
|
|
|
|
- * @return 映射后的水位值(保留2位小数,范围 [0.02, 0.09])
|
|
|
|
|
- */
|
|
|
|
|
- private static double generateDeterministicValue(String deviceId) {
|
|
|
|
|
- long hash = deviceId.hashCode();
|
|
|
|
|
- // 用正 hash 值确保非负
|
|
|
|
|
- long positiveHash = hash == Long.MIN_VALUE ? 0L : (hash ^ (hash >>> 32)) & 0x7FFFFFFFL;
|
|
|
|
|
- // 映射到 [0, 100] 整数空间,再缩放到目标区间(精度 0.01)
|
|
|
|
|
- int bucket = (int) (positiveHash % 101); // 0 ~ 100
|
|
|
|
|
- double val = MIN_VALUE + (bucket / 100.0) * (MAX_VALUE - MIN_VALUE);
|
|
|
|
|
- // 保留2位小数
|
|
|
|
|
- val = Math.round(val * 100) / 100.0;
|
|
|
|
|
- // 边界保护
|
|
|
|
|
- if (val > MAX_VALUE) val = MAX_VALUE;
|
|
|
|
|
- if (val < MIN_VALUE) val = MIN_VALUE;
|
|
|
|
|
- return val;
|
|
|
|
|
|
|
+ private static double generateValue(String deviceId) {
|
|
|
|
|
+ // 稳定、均匀的哈希
|
|
|
|
|
+ int hash = deviceId.hashCode();
|
|
|
|
|
+ int positiveHash = hash & 0x7FFFFFFF;
|
|
|
|
|
+
|
|
|
|
|
+ // 映射到 0~99,共 100 个台阶
|
|
|
|
|
+ int step = positiveHash % 100;
|
|
|
|
|
+
|
|
|
|
|
+ // 均匀分布在 0.02 ~ 0.05
|
|
|
|
|
+ double value = MIN_VALUE + (step / 100.0) * (MAX_VALUE - MIN_VALUE);
|
|
|
|
|
+
|
|
|
|
|
+ // 保留 2 位小数
|
|
|
|
|
+ return Math.round(value * 100) / 100.0;
|
|
|
}
|
|
}
|
|
|
-}
|
|
|
|
|
|
|
+}
|