列表接口
概述
List
是有序的集合接口,允许重复元素。在KubeJS中常用于存储物品列表、实体序列等需要保持顺序的数据。
List特性
- 有序性: 元素按插入顺序排列
- 可重复: 允许相同元素多次出现
- 索引访问: 支持通过索引快速访问元素
- 动态大小: 可动态增减元素
基础操作
创建和基本方法
js
/**
* List基础操作
*/
function listBasicOperations() {
// 创建List
const itemList = [];
const playerList = new ArrayList();
// 添加元素
itemList.push('minecraft:stone');
itemList.push('minecraft:dirt');
playerList.add(player);
// 插入元素
itemList.splice(1, 0, 'minecraft:grass'); // 在索引1处插入
// 获取元素
const firstItem = itemList[0];
const lastItem = itemList[itemList.length - 1];
// 查找元素
const stoneIndex = itemList.indexOf('minecraft:stone');
const hasStone = itemList.includes('minecraft:stone');
// 删除元素
itemList.splice(1, 1); // 删除索引1的元素
itemList.pop(); // 删除最后一个元素
const removed = itemList.shift(); // 删除第一个元素
console.log(`列表大小: ${itemList.length}`);
console.log(`第一个物品: ${firstItem}`);
}
遍历方法
js
/**
* List遍历操作
* @param {Array} list
*/
function listIteration(list) {
// 方法1: for循环(最快)
for (let i = 0; i < list.length; i++) {
console.log(`索引${i}: ${list[i]}`);
}
// 方法2: forEach
list.forEach((item, index) => {
console.log(`索引${index}: ${item}`);
});
// 方法3: for-of循环
for (const item of list) {
console.log(`物品: ${item}`);
}
// 方法4: for-in循环(不推荐用于数组)
for (const index in list) {
console.log(`索引${index}: ${list[index]}`);
}
// 方法5: while循环
let i = 0;
while (i < list.length) {
console.log(`索引${i}: ${list[i]}`);
i++;
}
}
高级操作
排序和搜索
js
/**
* List排序和搜索
* @param {Array} list
*/
function listSortingAndSearching(list) {
// 基础排序
const numbers = [3, 1, 4, 1, 5, 9, 2, 6];
numbers.sort((a, b) => a - b); // 升序
numbers.sort((a, b) => b - a); // 降序
// 字符串排序
const items = ['stone', 'dirt', 'grass', 'wood'];
items.sort(); // 字典序
items.sort((a, b) => a.length - b.length); // 按长度排序
// 对象排序
const players = [
{ name: 'Alice', level: 10 },
{ name: 'Bob', level: 15 },
{ name: 'Charlie', level: 8 }
];
// 按等级排序
players.sort((a, b) => b.level - a.level);
// 多条件排序
players.sort((a, b) => {
if (a.level === b.level) {
return a.name.localeCompare(b.name);
}
return b.level - a.level;
});
// 二分查找(需要已排序)
function binarySearch(sortedArray, target) {
let left = 0;
let right = sortedArray.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
const midValue = sortedArray[mid];
if (midValue === target) {
return mid;
} else if (midValue < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // 未找到
}
const sortedNumbers = [1, 3, 5, 7, 9, 11, 13];
const index = binarySearch(sortedNumbers, 7);
console.log(`7的索引: ${index}`);
}
函数式编程
js
/**
* List函数式编程方法
* @param {Array} list
*/
function listFunctionalProgramming(list) {
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// map: 转换元素
const doubled = numbers.map(n => n * 2);
const squares = numbers.map(n => n * n);
// filter: 过滤元素
const evenNumbers = numbers.filter(n => n % 2 === 0);
const largeNumbers = numbers.filter(n => n > 5);
// reduce: 归约操作
const sum = numbers.reduce((acc, n) => acc + n, 0);
const product = numbers.reduce((acc, n) => acc * n, 1);
const max = numbers.reduce((acc, n) => Math.max(acc, n), -Infinity);
// find: 查找第一个匹配
const firstEven = numbers.find(n => n % 2 === 0);
const firstLarge = numbers.find(n => n > 5);
// findIndex: 查找索引
const firstEvenIndex = numbers.findIndex(n => n % 2 === 0);
// some: 检查是否有元素满足条件
const hasEven = numbers.some(n => n % 2 === 0);
const hasNegative = numbers.some(n => n < 0);
// every: 检查是否所有元素满足条件
const allPositive = numbers.every(n => n > 0);
const allEven = numbers.every(n => n % 2 === 0);
// 链式调用
const result = numbers
.filter(n => n % 2 === 0)
.map(n => n * n)
.reduce((acc, n) => acc + n, 0);
console.log(`偶数平方和: ${result}`);
}
实际应用
实体列表管理
js
/**
* 实体列表管理
* @param {Internal.Level} level
*/
function entityListManagement(level) {
// 获取区域内的实体
const entities = level.getEntitiesWithinAABB(
-100, 0, -100,
100, 256, 100
);
// 按类型分组
const entityGroups = new Map();
entities.forEach(entity => {
const type = entity.type;
if (!entityGroups.has(type)) {
entityGroups.set(type, []);
}
entityGroups.get(type).push(entity);
});
// 查找最近的玩家
const centerX = 0, centerZ = 0;
const players = entities.filter(e => e.type === 'minecraft:player');
if (players.length > 0) {
const nearestPlayer = players.reduce((nearest, player) => {
const nearestDist = Math.sqrt(nearest.x * nearest.x + nearest.z * nearest.z);
const playerDist = Math.sqrt(player.x * player.x + player.z * player.z);
return playerDist < nearestDist ? player : nearest;
});
console.log(`最近的玩家: ${nearestPlayer.username}`);
}
// 按距离排序实体
const sortedByDistance = entities
.map(entity => ({
entity: entity,
distance: Math.sqrt(entity.x * entity.x + entity.z * entity.z)
}))
.sort((a, b) => a.distance - b.distance)
.map(item => item.entity);
console.log(`最近的实体: ${sortedByDistance[0]?.type}`);
}
/**
* 物品库存管理
* @param {Internal.Player} player
*/
function inventoryListManagement(player) {
const inventory = player.inventory;
const items = [];
// 收集所有物品
for (let i = 0; i < inventory.containerSize; i++) {
const item = inventory.getItem(i);
if (!item.isEmpty()) {
items.push({
item: item,
slot: i,
count: item.count,
id: item.id
});
}
}
// 按数量排序
items.sort((a, b) => b.count - a.count);
// 查找特定物品
const stones = items.filter(item => item.id === 'minecraft:stone');
const totalStones = stones.reduce((sum, item) => sum + item.count, 0);
// 查找稀有物品
const rareItems = items.filter(item => {
const rarity = item.item.rarity;
return rarity === 'rare' || rarity === 'epic';
});
// 分组统计
const itemCounts = new Map();
items.forEach(item => {
const id = item.id;
itemCounts.set(id, (itemCounts.get(id) || 0) + item.count);
});
console.log(`物品种类: ${itemCounts.size}`);
console.log(`石头总数: ${totalStones}`);
console.log(`稀有物品数: ${rareItems.length}`);
}
任务队列管理
js
/**
* 任务队列系统
*/
class TaskQueue {
constructor() {
this.tasks = [];
this.running = false;
}
// 添加任务
addTask(task, priority = 0) {
this.tasks.push({ task, priority, id: Date.now() });
this.tasks.sort((a, b) => b.priority - a.priority);
}
// 批量添加任务
addTasks(tasks) {
tasks.forEach(task => this.addTask(task));
}
// 插入高优先级任务
insertUrgentTask(task) {
this.tasks.unshift({ task, priority: Infinity, id: Date.now() });
}
// 移除任务
removeTask(taskId) {
this.tasks = this.tasks.filter(item => item.id !== taskId);
}
// 获取下一个任务
getNextTask() {
return this.tasks.shift()?.task;
}
// 查看队列状态
getStatus() {
return {
totalTasks: this.tasks.length,
highPriorityTasks: this.tasks.filter(t => t.priority > 5).length,
isRunning: this.running
};
}
// 执行所有任务
async executeAll() {
this.running = true;
while (this.tasks.length > 0) {
const task = this.getNextTask();
if (task) {
try {
await this.executeTask(task);
} catch (error) {
console.error('任务执行失败:', error);
}
}
}
this.running = false;
}
async executeTask(task) {
if (typeof task === 'function') {
return await task();
} else if (task && typeof task.execute === 'function') {
return await task.execute();
}
}
// 清空队列
clear() {
this.tasks = [];
}
// 暂停执行
pause() {
this.running = false;
}
}
// 使用示例
const taskQueue = new TaskQueue();
taskQueue.addTask(() => console.log('普通任务1'), 1);
taskQueue.addTask(() => console.log('高优先级任务'), 10);
taskQueue.addTask(() => console.log('普通任务2'), 1);
taskQueue.executeAll();
列表工具类
js
/**
* 列表工具类
*/
class ListUtils {
/**
* 分页
*/
static paginate(list, pageSize, pageNumber) {
const startIndex = (pageNumber - 1) * pageSize;
const endIndex = startIndex + pageSize;
return {
items: list.slice(startIndex, endIndex),
totalPages: Math.ceil(list.length / pageSize),
currentPage: pageNumber,
totalItems: list.length,
hasNext: endIndex < list.length,
hasPrev: pageNumber > 1
};
}
/**
* 随机采样
*/
static sample(list, count) {
const shuffled = [...list].sort(() => 0.5 - Math.random());
return shuffled.slice(0, count);
}
/**
* 打乱顺序
*/
static shuffle(list) {
const result = [...list];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
/**
* 去重
*/
static unique(list, keyFn = null) {
if (keyFn) {
const seen = new Set();
return list.filter(item => {
const key = keyFn(item);
if (seen.has(key)) {
return false;
}
seen.add(key);
return true;
});
} else {
return [...new Set(list)];
}
}
/**
* 分组
*/
static groupBy(list, keyFn) {
const groups = new Map();
list.forEach(item => {
const key = keyFn(item);
if (!groups.has(key)) {
groups.set(key, []);
}
groups.get(key).push(item);
});
return groups;
}
/**
* 扁平化
*/
static flatten(nestedList, depth = 1) {
if (depth === 1) {
return nestedList.flat();
}
return nestedList.flat(depth);
}
/**
* 窗口滑动
*/
static window(list, size, step = 1) {
const windows = [];
for (let i = 0; i <= list.length - size; i += step) {
windows.push(list.slice(i, i + size));
}
return windows;
}
/**
* 最大值和最小值
*/
static minMax(list, keyFn = null) {
if (list.length === 0) return { min: null, max: null };
let min = list[0];
let max = list[0];
for (const item of list) {
const value = keyFn ? keyFn(item) : item;
const minValue = keyFn ? keyFn(min) : min;
const maxValue = keyFn ? keyFn(max) : max;
if (value < minValue) min = item;
if (value > maxValue) max = item;
}
return { min, max };
}
}
// 使用示例
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 分页
const page1 = ListUtils.paginate(numbers, 3, 1);
console.log('第一页:', page1.items); // [1, 2, 3]
// 随机采样
const sample = ListUtils.sample(numbers, 3);
console.log('随机3个:', sample);
// 分组
const grouped = ListUtils.groupBy(numbers, n => n % 2 === 0 ? 'even' : 'odd');
console.log('按奇偶分组:', grouped);
性能优化
性能对比和优化建议
js
/**
* 列表性能优化
*/
function listPerformanceOptimization() {
console.log(`
List性能优化建议:
1. 访问操作 (O(1)):
- 使用索引访问: list[i]
- 避免频繁的length计算
2. 插入删除:
- 末尾操作最快: push(), pop()
- 开头操作较慢: unshift(), shift()
- 中间插入最慢: splice()
3. 查找操作:
- 有序数组用二分查找
- 频繁查找考虑用Set或Map
4. 遍历优化:
- for循环最快
- forEach次之
- for-of和for-in较慢
5. 内存优化:
- 预分配容量避免重新分配
- 及时清理不用的引用
- 大数组考虑分批处理
`);
// 性能测试示例
function performanceTest() {
const size = 100000;
const arr = new Array(size);
// 填充数组
console.time('填充数组');
for (let i = 0; i < size; i++) {
arr[i] = i;
}
console.timeEnd('填充数组');
// for循环遍历
console.time('for循环');
let sum1 = 0;
for (let i = 0; i < arr.length; i++) {
sum1 += arr[i];
}
console.timeEnd('for循环');
// forEach遍历
console.time('forEach');
let sum2 = 0;
arr.forEach(n => sum2 += n);
console.timeEnd('forEach');
}
performanceTest();
}