一、核心小知识和架构设计

1.1 数据结构特性

在这里插入图片描述

添加元素

查询元素

删除元素

需要扩容

初始化

容量分配

存储结构

操作类型

二分查找插入位置

二分查找定位

二分查找目标位置

扩容检查

双倍扩容

数据迁移

插入新元素

返回键值对

标记删除位置

数据压缩

PlainArray是鸿蒙ArkTS框架提供的有序键值对容器,其核心特征包括:

  • 键值唯一性:仅支持number类型键,保证键的唯一性
  • 二分查找机制:基于有序数组实现,查找时间复杂度O(log n)
  • 内存优化:采用紧凑存储结构,相比对象字面量节省30%内存
  • 动态扩容:自动处理容量扩展,初始容量建议设置为预期元素量的1.5倍

1.2 与LightWeightMap对比

特性 PlainArray LightWeightMap
键类型 仅支持number 支持string/number
查找算法 二分查找 哈希表查找
元素顺序 插入顺序 无序
内存占用 更低(约28字节/元素) 较高(约42字节/元素)
适用场景 数值键关联场景 通用键值存储

二、基础使用小实操

2.1 环境配置

最低API版本:API 8(需在config.json声明)
模块导入

import { PlainArray } from '@ohos.util.PlainArray';

2.2 核心API详解

2.2.1 构造与初始化
// 基础构造
const pa1 = new PlainArray<number>();

// 带初始容量构造
const pa2 = new PlainArray<number>(100); // 预分配100元素空间
2.2.2 元素操作

一般的元素添加流程是这样子滴

PlainArray Developer PlainArray Developer alt [容量不足] add(key: number, value: T) 二分查找插入位置 确定插入索引 检查容量是否充足 执行双倍扩容 数据迁移 插入新元素 返回操作结果

一般的元素查找流程又是这样子滴

PlainArray Developer PlainArray Developer alt [找到键] [未找到] get(key: number) 二分查找键位置 返回对应value 返回undefined
// 添加元素
pa.add(1001, "配置项A");
pa.add(1002, { value: 200 });

// 批量添加
pa.addBatch([1003, "配置项C"], [1004, 400]);

// 元素访问
const val = pa.get(1002); // { value: 200 }

// 元素更新
pa.setValueAt(1, "新配置值"); // 修改索引1的value
2.2.3 删除和清理
// 按key删除
pa.remove(1001);

// 按索引删除
pa.removeAt(2);

// 清空容器
pa.clear();

三、升级进阶功能实现

3.1 高效遍历方案

// 传统遍历
for (let i = 0; i < pa.size(); i++) {
  const [key, value] = pa.getKeyValueAt(i);
  console.log(`Key:${key}, Value:${value}`);
}

// 迭代器遍历
for (const [key, value] of pa) {
  console.log(`Key:${key}, Value:${value}`);
}

// 回调遍历
pa.forEach((value, index) => {
  console.log(`Index:${index}, Value:${value}`);
});

3.2 批量操作优化

// 批量插入
pa.addBatch(
  [2001, "batch1"], 
  [2002, "batch2"],
  [2003, "batch3"]
);

// 范围删除
pa.removeRangeFrom(5, 3); // 删除索引5-7的元素

3.3 数据持久化方案

// 序列化存储
const serialized = pa.serialize();
localStorage.setItem('config', serialized);

// 反序列化恢复
const restored = PlainArray.deserialize(localStorage.getItem('config'));

四、性能优化策略

4.1 插入性能优化

预分配策略

// 预分配1000元素空间
const largePa = new PlainArray<number>(1000);

// 分批插入
for (let i = 0; i < 1000; i++) {
  largePa.add(i, `item${i}`);
}

4.2 内存管理方案

对象池模式

class ConfigPool {
  private static pool = new PlainArray<Config>({ initialCapacity: 50 });

  static getConfig(id: number): Config {
    let config = this.pool.get(id);
    if (!config) {
      config = new Config(id);
      this.pool.add(id, config);
    }
    return config;
  }
}

4.3 并发访问控制

// 使用锁机制保证线程安全
const lock = new Mutex();

async function safeUpdate(key: number, value: any) {
  await lock.acquire();
  try {
    pa.setValueAt(key, value);
  } finally {
    lock.release();
  }
}

五、典型的应用

5.1 配置管理系统

// 初始化配置
const appConfig = new PlainArray<ConfigItem>({
  initialCapacity: 50
});

// 加载配置
function loadConfig() {
  const configFile = fs.readFileSync('config.json');
  const configData = JSON.parse(configFile);
  configData.forEach(({ key, value }) => {
    appConfig.add(key, value);
  });
}

// 动态更新
function updateConfig(key: number, value: any) {
  if (appConfig.has(key)) {
    appConfig.setValueAt(key, value);
  }
}

5.2 状态管理容器

// 定义状态类型
interface AppState {
  [key: number]: any;
}

// 创建状态容器
const state = new PlainArray<AppState>({ initialCapacity: 20 });

// 状态更新
function setState(key: number, newState: AppState) {
  state.setValueAt(key, { ...state.get(key), ...newState });
}

// 状态监听
state.forEach((value, index) => {
  console.log(`State[${index}]:`, value);
});

底层实现原理

数据存储

主键数组

值数组

二分查找模块

值访问模块

插入逻辑

删除逻辑

值更新逻辑

六、调试和小诊断

6.1 状态验证工具

// 验证元素唯一性
function validateUniqueness() {
  const keys = new Set<number>();
  pa.forEach((_, index) => {
    if (keys.has(index)) {
      console.error(`重复键值: ${index} 在索引 ${index} 处重复`);
    }
    keys.add(index);
  });
}

// 内存占用检测
const memoryUsage = process.memoryUsage();
console.log(`当前内存占用: ${memoryUsage.heapUsed / 1024 / 1024} MB`);

6.2 性能分析示例

// 性能基准测试
const testCases = @ref;

testCases.forEach(size => {
  console.time(`插入${size}元素`);
  const testPa = new PlainArray<number>();
  for (let i = 0; i < size; i++) {
    testPa.add(i, `item${i}`);
  }
  console.timeEnd(`插入${size}元素`);
});

七、小实践走起

7.1 命名规范建议

// 推荐命名方式
const userAgeMap = new PlainArray<number>();
const configValues = new PlainArray<{ key: string }>();

// 不推荐命名
const arr = new PlainArray();
const data = new PlainArray();

7.2 异常处理方案

// 安全访问模式
function getValueSafely(key: number, defaultValue: T): T {
  try {
    return pa.get(key) || defaultValue;
  } catch (error) {
    console.error(`获取键${key}失败:`, error);
    return defaultValue;
  }
}

// 批量操作防护
function batchAddSafely(items: [number, T][]) {
  if (!Array.isArray(items)) {
    throw new Error('参数必须是数组类型');
  }
  items.forEach(([key, value]) => {
    if (typeof key !== 'number') {
      throw new TypeError('键必须是number类型');
    }
  });
  pa.addBatch(...items.flat());
}

7.3 版本兼容策略

// 兼容旧版本API
function addWithFallback(key: number, value: T) {
  if (typeof pa.add === 'function') {
    pa.add(key, value);
  } else {
    // 旧版本兼容处理
    pa.setItem(key, value);
  }
}

// 弃用API警告
const deprecatedAdd = pa.add;
pa.add = function(key: number, value: T) {
  console.warn('plainArray.add 已弃用,请使用 addWithValidation');
  deprecatedAdd.call(this, key, value);
};
Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐