在Lua中,没有类的概念,因为它是基于原型的语言。不过,我们可以使用表(table)来模拟类和对象
Lua中的数组索引是从1开始的,而不是从0开始,
Lua的表是动态大小的,因此我们没有在Lua实现中强制数组的容量。
我们在Array.new函数中初始化了一个具有指定容量大小的数组,并且当尝试添加超过该容量的元素时,会抛出一个错误。在实际Lua使用中,通常不需要这样做,因为Lua表会自动扩展。此外,我们在移除元素时显式地将最后一个元素设置为nil,以避免潜在的内存泄漏,这是Lua中管理内存的一种好习惯。
初步准备
-- 这里创建了一个空表Array,它将被用作自定义数组类的原型。
-- __index元方法用于当访问表中不存在的字段时,Lua会调用这个元方法来查找值。
Array = {}
Array.__index = Array
-- 构造函数
-- 这个函数是Array的构造函数,用于创建一个新的Array实例。
-- setmetatable函数设置了self的元表为Array,这样self就可以访问Array中定义的方法。
function Array.new(capacity)
if capacity == nil then
capacity = 10
end
local self = {
data = {},
size = 0,
capacity = capacity
}
setmetatable(self, Array)
for i = 1, capacity do
self.data[i] = nil
end
return self
end
-- 成员方法
-- 在Lua中,冒号:语法用于定义对象的方法
-- 这个方法返回数组的大小。self关键字代表调用该方法的对象实例。
function Array:getSize()
return self.size
end
function Array:getCapacity()
return self.capacity
end
function Array:isEmpty()
return self.size == 0
end
function Array:addLast(e)
self:add(self.size + 1, e)
end
function Array:addFirst(e)
self:add(1, e)
end
function Array:add(index, e)
if self.size == self.capacity then
error("Add failed. Array is full.")
end
if index < 1 or index > self.size + 1 then
error("Add failed. Require index >= 1 and index <= size + 1.")
end
for i = self.size, index, -1 do
self.data[i + 1] = self.data[i]
end
self.data[index] = e
self.size = self.size + 1
end
function Array:get(index)
if index < 1 or index > self.size then
error("Get failed. Index is illegal.")
end
return self.data[index]
end
function Array:set(index, e)
if index < 1 or index > self.size then
error("Set failed. Index is illegal.")
end
self.data[index] = e
end
function Array:contains(e)
for i = 1, self.size do
if self.data[i] == e then
return true
end
end
return false
end
function Array:find(e)
for i = 1, self.size do
if self.data[i] == e then
return i
end
end
return -1
end
function Array:remove(index)
if index < 1 or index > self.size then
error("Remove failed. Index is illegal.")
end
local ret = self.data[index]
for i = index, self.size - 1 do
self.data[i] = self.data[i + 1]
end
self.size = self.size - 1
self.data[self.size + 1] = nil -- Explicitly nil the last element to avoid memory leak
return ret
end
function Array:removeFirst()
return self:remove(1)
end
function Array:removeLast()
return self:remove(self.size)
end
function Array:removeElement(e)
local index = self:find(e)
if index ~= -1 then
self:remove(index)
end
end
function Array:toString()
local res = "Array: size = " .. self.size .. ", capacity = " .. self.capacity .. "\n["
for i = 1, self.size do
res = res .. self.data[i]
if i ~= self.size then
res = res .. ", "
end
end
res = res .. "]"
return res
end
-- Example usage:
local arr = Array.new(5)
arr:add(1, 10)
arr:add(2, 20)
arr:add(3, 30)
print(arr:toString()) -- Output: Array: size = 3, capacity = 5 [10, 20, 30]
实际应用
由于Lua的表会自动进行扩展,我们不需要像在Java中那样显式地管理数组的容量。
在Lua中,我们通常使用ipairs来遍历数组部分(即,具有连续整数键的部分)的表。
由于Lua的表本身就是动态的,我们不需要像Java中那样处理数组的扩容。
Array = {}
Array.__index = Array
function Array.new()
local self = {}
self.size = 0
self.data = {}
setmetatable(self, Array)
return self
end
function Array:getSize()
return self.size
end
function Array:isEmpty()
return self.size == 0
end
function Array:addLast(e)
table.insert(self.data, e)
self.size = self.size + 1
end
function Array:addFirst(e)
table.insert(self.data, 1, e)
self.size = self.size + 1
end
function Array:add(index, e)
if index < 1 or index > self.size + 1 then
error("Add failed. Require index >= 1 and index <= size + 1.")
end
table.insert(self.data, index, e)
self.size = self.size + 1
end
function Array:get(index)
if index < 1 or index > self.size then
error("Get failed. Index is illegal.")
end
return self.data[index]
end
function Array:set(index, e)
if index < 1 or index > self.size then
error("Set failed. Index is illegal.")
end
self.data[index] = e
end
function Array:contains(e)
for _, v in ipairs(self.data) do
if v == e then
return true
end
end
return false
end
function Array:find(e)
for i, v in ipairs(self.data) do
if v == e then
return i
end
end
return -1
end
function Array:remove(index)
if index < 1 or index > self.size then
error("Remove failed. Index is illegal.")
end
local ret = table.remove(self.data, index)
self.size = self.size - 1
return ret
end
function Array:removeFirst()
return self:remove(1)
end
function Array:removeLast()
return self:remove(self.size)
end
function Array:removeElement(e)
local index = self:find(e)
if index ~= -1 then
self:remove(index)
end
end
function Array:toString()
local res = "Array: size = " .. self.size .. "\n["
for i, v in ipairs(self.data) do
res = res .. v
if i ~= self.size then
res = res .. ", "
end
end
res = res .. "]"
return res
end
-- Example usage:
local arr = Array.new()
arr:add(1, 10)
arr:add(2, 20)
arr:add(3, 30)
print(arr:toString()) -- Output: Array: size = 3 [10, 20, 30]
Array = {}
Array.__index = Array
function Array.new(capacity)
local self = {}
setmetatable(self, Array)
-- Initialize the array-like table
self.data = {}
self.size = 0
self.capacity = capacity or 10
return self
end
function Array:getSize()
return self.size
end
function Array:getCapacity()
return self.capacity
end
function Array:isEmpty()
return self.size == 0
end
function Array:addLast(element)
self:add(self.size + 1, element)
end
function Array:addFirst(element)
table.insert(self.data, 1, element)
self.size = self.size + 1
-- Handle capacity increase if needed (omitted for simplicity)
end
function Array:add(index, element)
if index < 1 or index > self.size + 1 then
error("Index out of bounds")
end
table.insert(self.data, index, element)
self.size = self.size + 1
-- Handle capacity increase if needed (omitted for simplicity)
end
function Array:get(index)
if index < 1 or index > self.size then
error("Index out of bounds")
end
return self.data[index]
end
function Array:set(index, element)
if index < 1 or index > self.size then
error("Index out of bounds")
end
self.data[index] = element
end
function Array:remove(index)
if index < 1 or index > self.size then
error("Index out of bounds")
end
local element = table.remove(self.data, index)
self.size = self.size - 1
return element
end
function Array:removeFirst()
return self:remove(1)
end
function Array:removeLast()
return self:remove(self.size)
end
function Array:toString()
local str = "Array: size = " .. self.size .. ", capacity = " .. self.capacity .. "\n["
for i = 1, self.size do
str = str .. tostring(self.data[i])
if i ~= self.size then
str = str .. ", "
end
end
str = str .. "]"
return str
end
-- Usage example
local arr = Array.new()
arr:addLast(10)
arr:addLast(20)
arr:addFirst(5)
print(arr:toString())