Flutter能否生成不重复随机数并持久化存储?如何实现?
Flutter生成不重复随机数并持久化实现
Flutter完全支持生成随机数并通过本地持久化存储确保重启后不重复生成,核心思路是每次生成随机数前先校验历史存储记录,仅当新数未存在时才保留并更新存储。下面是具体实现方案:
一、依赖选择
优先使用shared_preferences(轻量、适合存储简单数据列表),也可以用Hive、Isar等NoSQL本地数据库(适合更复杂场景)。这里以shared_preferences为例。
添加依赖
在pubspec.yaml中添加:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2
执行flutter pub get完成依赖安装。
二、封装随机数工具类
创建工具类封装生成、校验、存储的核心逻辑:
import 'dart:math'; import 'package:shared_preferences/shared_preferences.dart'; class UniqueRandomGenerator { // 存储历史随机数的key static const String _historyKey = 'generated_random_numbers'; static final Random _random = Random(); static List<int>? _historyNumbers; // 初始化历史数据 static Future<void> _initHistory() async { if (_historyNumbers != null) return; final prefs = await SharedPreferences.getInstance(); _historyNumbers = prefs.getStringList(_historyKey)?.map(int.parse).toList() ?? []; } // 生成指定范围内的不重复随机数 static Future<int> generateUniqueRandom(int min, int max) async { await _initHistory(); // 检查范围内是否还有未生成的数,避免死循环 final totalPossible = max - min + 1; if (_historyNumbers!.length >= totalPossible) { throw Exception('范围内所有随机数已生成完毕'); } int newNumber; do { newNumber = min + _random.nextInt(max - min + 1); } while (_historyNumbers!.contains(newNumber)); // 更新历史列表并持久化 _historyNumbers!.add(newNumber); final prefs = await SharedPreferences.getInstance(); await prefs.setStringList(_historyKey, _historyNumbers!.map((e) => e.toString()).toList()); return newNumber; } // 清空历史记录(可选) static Future<void> clearHistory() async { final prefs = await SharedPreferences.getInstance(); await prefs.remove(_historyKey); _historyNumbers = []; } }
三、页面中使用示例
import 'package:flutter/material.dart'; class RandomNumberPage extends StatefulWidget { const RandomNumberPage({super.key}); @override State<RandomNumberPage> createState() => _RandomNumberPageState(); } class _RandomNumberPageState extends State<RandomNumberPage> { int? _currentRandom; Future<void> _generateNumber() async { try { final number = await UniqueRandomGenerator.generateUniqueRandom(1, 100); setState(() { _currentRandom = number; }); } catch (e) { ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(e.toString()))); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('不重复随机数生成')), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Text(_currentRandom != null ? '生成的随机数:$_currentRandom' : '点击按钮生成随机数'), const SizedBox(height: 20), ElevatedButton( onPressed: _generateNumber, child: const Text('生成随机数'), ), TextButton( onPressed: () async { await UniqueRandomGenerator.clearHistory(); setState(() { _currentRandom = null; }); }, child: const Text('清空历史记录'), ) ], ), ), ); } }
关键注意事项
- 范围限制处理:如果随机数范围有限(比如1-10),必须添加判断逻辑,避免因所有数已生成导致死循环。
- 持久化选择:如果需要存储大量随机数或更复杂的数据结构,建议使用Hive/Isar替代
shared_preferences,性能更优。 - 线程安全:如果在多线程场景下使用,需要添加锁机制避免并发读写冲突。
内容的提问来源于stack exchange,提问作者EBENEZER OCANSEY
相关产品推荐
相关产品推荐

