You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 09:32:20