文章目录
- 初步准备
- 实际应用
在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())