CRC32 vs Java.HashCode

本文通过实验对比了CRC32与Java HashCode两种算法在27万中文词库上的冲突率及速度表现,并详细介绍了CRC的工作原理及Java String hashCode的计算方式。
找了容量为27万中文词库进行试验
   CRC32 中冲突率 < 0.01%
   而 Java.HashCode 有 4%
   hashCode 的速度 应该比 CRC 快 2-3 倍

CRC 实际上就是求余数,
   1)被除数是确定好的,被除数首位要求是1(可以理解,因为0,就相当于会少一位),尾数也要求是1(为何)
   2)CRC8 是指余数是8位,那么被除数就是9位,CRC16,被除数17位,32那么被除数应该是33位了
   3)CRC采用不借位,不进位的加减法,所有都变成了异或操作
   4)利用异或交换率,CRC可以由计算法改为查表法提高效率

 Java 的HashCode      
      java String hashCode 的算法       
      s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
      using int arithmetic, where s[i] is the ith character of the string, n is the length of the string, and ^ indicates exponentiation. (The hash value of the empty string is zero.)
你提供的这个代码启动后修改表结构不执行我的逻辑package com.example.warning.schedule; import javax.sql.DataSource; import java.sql.*; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Consumer; /** * 表变更监控工具 * 功能:检测表重建或数据变更事件 */ public class TableChangeMonitor { private final DataSource dataSource; private final String tableName; private final long checkInterval; private final Consumer<Void> onChangeHandler; private final Timer timer = new Timer(true); private final AtomicBoolean isMonitoring = new AtomicBoolean(false); private String lastDataHash; private boolean lastTableExists; public TableChangeMonitor(DataSource dataSource, String tableName, long checkInterval, Consumer<Void> onChangeHandler) { this.dataSource = dataSource; this.tableName = tableName; this.checkInterval = checkInterval; this.onChangeHandler = onChangeHandler; initializeState(); } /** * 初始化监控状态 */ private void initializeState() { this.lastTableExists = checkTableExists(); this.lastDataHash = lastTableExists ? calculateDataHash() : ""; } /** * 启动监控 */ public void start() { if (isMonitoring.compareAndSet(false, true)) { timer.scheduleAtFixedRate(new MonitorTask(), 0, checkInterval); } } /** * 停止监控 */ public void stop() { if (isMonitoring.compareAndSet(true, false)) { timer.cancel(); } } /** * 监控任务 */ private class MonitorTask extends TimerTask { @Override public void run() { boolean currentTableExists = checkTableExists(); String currentDataHash = currentTableExists ? calculateDataHash() : ""; // 检测变更:表重建或数据变化 if ((!lastTableExists && currentTableExists) || (lastTableExists && currentTableExists && !currentDataHash.equals(lastDataHash))) { onChangeHandler.accept(null); // 触发变更处理 } // 更新状态 lastTableExists = currentTableExists; lastDataHash = currentDataHash; } } /** * 检查表是否存在 */ private boolean checkTableExists() { try (Connection conn = dataSource.getConnection(); ResultSet rs = conn.getMetaData().getTables(null, null, tableName, null)) { return rs.next(); } catch (SQLException e) { return false; } } /** * 计算数据哈希(行数 + 数据校验和) */ private String calculateDataHash() { String sql = String.format( "SELECT COUNT(*) AS cnt, COALESCE(SUM(CRC32(CONCAT_WS(',', *))), 0) AS chk FROM %s", tableName ); try (Connection conn = dataSource.getConnection(); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql)) { if (rs.next()) { return rs.getLong("cnt") + ":" + rs.getLong("chk"); } } catch (SQLException e) { // 表存在但无数据 } return "0:0"; } } package com.example.warning.config; import com.example.warning.schedule.TableChangeMonitor; import com.example.warning.service.WarningService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; @Configuration public class MonitorConfig { @Autowired private WarningService warningService; @Bean public TableChangeMonitor tableChangeMonitor(DataSource dataSource) { return new TableChangeMonitor( dataSource, "ads_bpm_early_warning", // 替换为实际表名 5000, // 检查间隔(毫秒) event -> runYourProgram() // 变更处理 ); } private void runYourProgram() { // 实现您的业务逻辑 System.out.println("检测到表变更,执行业务程序"); warningService.processWarnings(); } }package com.example.warning.util; import com.example.warning.schedule.TableChangeMonitor; import jakarta.annotation.PostConstruct; import jakarta.annotation.PreDestroy; import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @Component public class MonitorStarter implements CommandLineRunner { private final TableChangeMonitor monitor; // 通过构造器注入依赖 public MonitorStarter(TableChangeMonitor monitor) { this.monitor = monitor; } @PostConstruct public void init() { System.out.println("✅ 监控组件初始化完成"); // 这里可以添加初始化逻辑(如:连接池预热) } @Override public void run(String... args) { monitor.start(); System.out.println("✅ 表变更监控已启动"); } @PreDestroy public void cleanup() { monitor.stop(); System.out.println("🛑 监控已停止,资源已释放"); // 这里可以添加清理逻辑(如:关闭文件句柄) } }
最新发布
10-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值