数据结构之数组
1. 什么是数组?(python中的列表)
分类:线性表(Linear List)。在内存中体现为一段连续的空间。在Java、Python、Javascript有共同点,也有不同点。
2. 数组/列表的特点
- 根据下标访问是O(1),其他访问是O(n)--遍历
- 修改是O(1)(根据下标修改)
- 删除、插入涉及数据的移位 O(n):平均移动的数据的个数:E=1 * 1/n + 2 * 1/n + 3 * 1/n …… + n * 1/n=(n+1)/2。其中1/n是可以插入位置的概率都一样都是1/n。
- 下标都是从0开始。
3. Python语言中的数组
3.1 Python中的数组就是我们所说的列表(list)
- 在Python中,数组是一种有序的集合,可以存储相同或不同类型的元素(Java只能存储相同类型的元素)。
- 它是一个可变长度的数据结构(Java声明时指定数组的长度/大小),可以根据需要动态调整大小。
- 在Python中,数组通常被称为列表(list),它用方括号[]表示,并且可以包含任意类型的元素。
例如,下面是一个包含整数和字符串的数组的示例:
arr = [1, 2, 3, "hello", "world"]
数组的优点是可以在O(1)的时间复杂度内访问和修改元素,而不需要遍历整个数组。此外,数组还提供了许多内置的方法,如添加元素、删除元素、查找元素等。
需要注意的是,在Python中的数组(列表)与其他编程语言中的数组有一些区别。Python的数组可以存储不同类型的元素,并且可以根据需要动态调整大小,这使得它更加灵活
3.1.1 声明
1. 使用方括号 [] 声明一个空列表
1 | arr = [] |
2. 在方括号内添加元素来声明具有初始值的列表:
arr = [1, 2, 3, 4, 'Allen']
3. 使用 list() 函数声明一个空列表:
arr = list()
4. 使用 list() 函数和可迭代对象(如字符串、元组等)来声明具有初始值的列表:
arr = list("hello") # ['h', 'e', 'l', 'l', 'o']
Python的列表可以存储不同类型的元素,并且可以根据需要动态调整大小。Java声明时必须指定类型、大小。
3.1.2 获取列表的长度: len(arr)
获取列表的长度:可以使用 len() 函数获取列表中元素的个数。
arr = [1, 2, 3, 4, 5] print(len(arr)) # 输出: 5
3.1.3 访问列表中的元素
有2种方式:
1. 根据下标访问,从0开始。
2. for、for-each、range等遍历
1. 访问列表中的元素:可以使用索引操作符 [] 来访问列表中的元素,索引从0开始计数。
arr = [1, 2, 3, 4, 5] print(arr[0]) # 输出: 1
2. 使用for
循环遍历数组
arr = [1, 2, 3, 4, 5] for i in range(len(arr)): print(arr[i])
使用for
循环和range()
函数来遍历数组arr
。range(len(arr))
将会生成一个从0到len(arr)-1
的整数序列,然后通过索引i
访问数组中的元素。
输出:
1 2 3 4 5 | 1 2 3 4 5 |
3. 使用for-each
循环遍历数组:
arr = [1, 2, 3, 4, 5] for num in arr: print(num)
使用for-each
循环直接遍历数组arr
中的元素,每次迭代时将当前元素赋值给变量num。
特别需要注意2点:
1. for-each遍历时,不要修改元素
2. python的for-each是按列表顺序遍历。而Java是随机遍历
输出:
1 2 3 4 5 | 1 2 3 4 5 |
坑: 在循环中修改列表时,需要小心。如果在迭代过程中添加或删除元素会导致迭代出错。
my_list = [1, 2, 3, 4, 5] for num in my_list: if num % 2 == 0: my_list.remove(num) print(my_list) # 输出: [1, 3, 5]
试图在循环中删除所有偶数。但是,由于在循环过程中修改了列表,导致循环跳过了某些元素(如2),结果不如预期。
要解决这个问题,可以创建一个新的列表来存储要删除的元素,然后在循环结束后统一删除它们。或者,可以使用列表推导式或filter()
函数来过滤出要保留的元素。
my_list = [1, 2, 3, 4, 5] to_remove = [] for num in my_list: if num % 2 == 0: to_remove.append(num) # 循环结束后删除要删除的元素 for num in to_remove: my_list.remove(num) print(my_list) # 输出: [1, 3, 5]
my_list = [1, 2, 3, 4, 5] # 使用列表推导式过滤出要保留的奇数 my_list = [num for num in my_list if num % 2 != 0] print(my_list) # 输出: [1, 3, 5]
my_list = [1, 2, 3, 4, 5]
# 使用列表推导式过滤出要保留的奇数
my_list = [num for num in my_list if num % 2 != 0]
print(my_list) # 输出: [1, 3, 5]
3.1.4 修改列表中的元素
修列表是可变的,可以通过索引操作符 [] 来修改其中的元素。
1 2 3 | arr = [ 1 , 2 , 3 , 4 , 5 ] arr[ 0 ] = 10 print (arr) # 输出: [10, 2, 3, 4, 5] |
salaries[1:3] = [6500, 7500] # 将第二个和第三个员工的工资修改为6500和7500
3.1.5 列表添加元素
1. 使用 append() 方法将元素添加到列表的末尾。
arr = [1, 2, 3] arr.append(4) print(arr) # 输出: [1, 2, 3, 4]
2. 使用insert(索引,元素)方法在指定位置插入数据
1 2 3 4 5 6 | my_list = [ 1 , 2 , 3 ] # 在索引为1的位置插入元素4 my_list.insert( 1 , 4 ) print (my_list) # 输出: [1, 4, 2, 3] |
3. 使用extend()
方法或使用+=
操作符一次添加多个元素
my_list = [1, 2, 3] # 使用extend()方法添加多个元素 my_list.extend([4, 5, 6]) print(my_list) # 输出: [1, 2, 3, 4, 5, 6] # 使用+=操作符添加多个元素 my_list += [7, 8, 9] print(my_list) # 输出: [1, 2, 3, 4, 5, 6, 7, 8, 9]
3.1.6 删除元素
删除列表中的元素:可以使用 del 关键字、pop(index)或 remove() 方法删除列表中的元素。
arr = [1, 2, 3, 4, 5] del arr[0] print(arr) # 输出: [2, 3, 4, 5] arr.remove(3) print(arr) # 输出: [2, 4, 5]
1 ''' 2 列表的pop()函数用于删除并返回列表中指定位置的元素 3 4 语法: 5 list.pop(index) 其中,index是要删除的元素的索引值。如果不指定索引值,默认删除并返回列表中的最后一个元素。 6 7 返回值: 8 pop()函数会返回被删除的元素 9 10 注意事项: 11 1. 如果指定的索引值超出了列表的范围,会引发IndexError异常。 12 2. 如果列表为空,也会引发IndexError异常。 13 ''' 14 15 fruits = ['apple', 'banana', 'orange'] 16 17 # 删除并返回最后一个元素 18 last_fruit = fruits.pop() 19 print(last_fruit) # 输出结果为 'orange' 20 print(fruits) # 输出结果为 ['apple', 'banana'] 21 22 # 删除并返回指定位置的元素 23 second_fruit = fruits.pop(1) 24 print(second_fruit) # 输出结果为 'banana' 25 print(fruits) # 输出结果为 ['apple'] 26 27 # 删除越界的元素 28 out_of_range_fruit = fruits.pop(2) # 引发 IndexError 异常 29 30 # 删除空列表的元素 31 empty_list = [] 32 empty_list.pop() # 引发 IndexError 异常
3.1.7 列表当作实参传递时
列表是可变对象,在函数参数传递时要特别注意。如果将列表作为参数传递给函数,函数可能会修改原始列表。
如果不想修改原始列表,可以使用切片操作符或创建副本来传递一个新的列表给函数。
1. 使用切片操作符创建一个新的列表并将其传递给函数。
def func(my_list): # 在函数中对my_list进行操作 my_list = [1, 2, 3, 4, 5] new_list = my_list[:] func(new_list )
2. 使用列表的copy()
方法创建一个副本,并将其传递给函数
def func(my_list): new_list = my_list.copy() # 浅拷贝 # 在函数中对new_list进行操作 my_list = [1, 2, 3, 4, 5] func(my_list)
3. 深拷贝
import copy def func(my_list): new_list = copy.deepcopy(my_list) # 在函数中对new_list进行操作 my_list = [1, 2, 3, 4, 5] func(my_list)
3.1.8 列表的合并与拆分
使用+操作符可以将两个列表合并为一个新的列表。这个操作符非常简单,只需要将两个列表用+连接在一起即可
# 创建两个列表 list1 = [1, 2, 3] list2 = [4, 5, 6] # 使用+操作符合并两个列表 combined_list = list1 + list2 # 打印合并后的列表 print(combined_list)
输出结果:
1 | [ 1 , 2 , 3 , 4 , 5 , 6 ] |
通过使用+操作符,我们将list1和list2两个列表合并成了一个新的列表combined_list。合并后的列表包含了两个原始列表中的所有元素。
需要注意的是,这种方法创建了一个新的列表,而不是修改原始列表。原始列表list1和list2保持不变。
此外,你也可以使用这种方法合并多个列表,只需要依次使用+操作符连接它们即可
拆分列表的操作不是通过+操作符来实现的,而是通过切片来完成的。如果你想从一个列表中获取一部分元素,可以使用切片操作
# 创建一个列表 my_list = [1, 2, 3, 4, 5] # 使用切片获取列表的一部分 subset = my_list[1:4] # 打印获取的子列表 print(subset)
输出结果:
1 | [ 2 , 3 , 4 ] |
使用切片[1:4]
从my_list
中获取了索引1到3的元素,包括索引1但不包括索引4。这样就实现了从一个列表中拆分出一个子列表。
3.1.9 排序
sort()
方法用于对列表进行排序。默认情况下,它会按照升序(从小到大)的顺序对列表进行排序,但你也可以通过参数来指定降序排序。
列表的sort方法会改变原列表的内容
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] # 使用 sort() 方法对列表进行升序排序 numbers.sort() print(numbers)
输出结果:
1 | [ 1 , 1 , 2 , 3 , 3 , 4 , 5 , 5 , 5 , 6 , 9 ] |
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] # 使用 sort() 方法对列表进行降序排序 numbers.sort(reverse=True) print(numbers)
输出结果:
1 | [ 9 , 6 , 5 , 5 , 5 , 4 , 3 , 3 , 2 , 1 , 1 ] |
如果你想对一个列表进行排序但又不想改变原始列表,可以使用sorted()
函数。sorted()
函数会返回一个新的已排序列表,而不会修改原始列表
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] # 使用 sorted() 函数对列表进行升序排序 sorted_numbers = sorted(numbers) # 打印排序后的新列表 print(sorted_numbers) # 原始列表仍然保持不变 print(numbers)
输出:
1 2 | [ 1 , 1 , 2 , 3 , 3 , 4 , 5 , 5 , 5 , 6 , 9 ] [ 3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 , 5 , 3 , 5 ] |
如果你想要对列表进行降序排序,可以使用reverse=True
参数:
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5] # 使用 sorted() 函数对列表进行降序排序 sorted_numbers_descending = sorted(numbers, reverse=True) # 打印降序排序后的新列表 print(sorted_numbers_descending) # 原始列表仍然保持不变 print(numbers)
输出结果:
1 2 | [ 9 , 6 , 5 , 5 , 5 , 4 , 3 , 3 , 2 , 1 , 1 ] [ 3 , 1 , 4 , 1 , 5 , 9 , 2 , 6 , 5 , 3 , 5 ] |
3.1.10 颠倒顺序
reverse()
方法用于反转列表中的元素的顺序。它不会对元素进行排序,只是将列表中的元素颠倒顺序。
fruits = ["apple", "banana", "cherry", "date"] # 使用 reverse() 方法反转列表中的元素顺序 fruits.reverse() print(fruits)
输出结果:
1 | [ 'date' , 'cherry' , 'banana' , 'apple' ] |
需要注意的是,reverse()
方法只是颠倒元素的顺序,不会对元素进行排序。如果你想同时对列表进行排序和反转,可以先使用 sort()
方法排序,然后再使用 reverse()
方法反转。
3.2 python数组的内存模型
Python中的数组通常使用列表(List)来表示。Python的列表是一种动态数组,它可以容纳不同类型的元素,并且可以自动扩展以容纳更多的元素。列表的内存模型包括以下要点:
-
元素存储:列表内的元素可以是不同类型的对象,包括数字、字符串、对象引用等。每个元素都在内存中占据一定的空间。
-
内存分配:当创建一个新的列表时,Python会分配一块内存来存储列表的元素。这个内存块的大小通常会比实际需要的要大一些,以便在需要时扩展列表。
-
动态扩展:当列表需要添加新元素时,如果内存空间不足,Python会自动分配更多的内存,并将元素复制到新的内存块中。这个过程称为动态扩展。
-
索引:列表中的元素可以通过索引访问,索引从0开始。通过索引,Python可以直接访问内存中的元素,而无需遍历整个列表。
-
内存回收:当不再需要一个列表时,Python的垃圾回收机制会自动释放该列表占用的内存。
需要注意的是,Python的列表是可变的,这意味着您可以在列表中添加、删除或修改元素。
由于列表的动态性,它们在某些情况下可能会导致性能问题,特别是当操作大型列表时。
如果需要处理大量数据或需要高性能的数据操作,考虑使用NumPy数组或其他数据结构可能更合适。
NumPy数组是一种用于数值计算的高效多维数组结构,它在内存管理和性能方面提供了更多控制和优化。
3.3 Numpy模块
NumPy(Numerical Python)是Python中用于数值计算的一个强大库,它提供了多维数组对象(称为numpy.ndarray
或简称为ndarray
)和许多用于操作这些数组的函数。
使用NumPy,您可以进行高性能的数学和统计计算,以及处理多维数据。
NumPy数组的基本属性和操作:
1. 创建数组:使用numpy.array()
函数可以创建NumPy数组。您可以将Python列表或元组传递给此函数,或者使用NumPy提供的其他创建数组的方法。
1 import numpy as np 2 3 # 从Python列表创建数组 4 my_list = [1, 2, 3, 4, 5] 5 arr = np.array(my_list) 6 print(type(arr)) 7 print(arr) 8 9 # 创建一个包含零的数组 10 zeros_arr = np.zeros(5) 11 print(type(zeros_arr)) 12 print(zeros_arr) 13 14 # 创建一个包含一的数组 15 ones_arr = np.ones(5) 16 print(type(ones_arr)) 17 print(ones_arr) 18 19 # 创建一个包含随机数的数组 20 rand_arr = np.random.rand(5) 21 print(type(rand_arr)) 22 print(rand_arr)
输出:
1 2 3 4 5 6 7 8 | < class 'numpy.ndarray' > [ 1 2 3 4 5 ] < class 'numpy.ndarray' > [ 0. 0. 0. 0. 0. ] < class 'numpy.ndarray' > [ 1. 1. 1. 1. 1. ] < class 'numpy.ndarray' > [ 0.95300642 0.79525243 0.37338667 0.52057194 0.46075945 ] |
2. 数组属性:NumPy数组具有各种属性,如形状(shape
)、数据类型(dtype
)、维度(ndim
)、大小(size
)等,可以用于了解数组的特征。
1 ''' 2 数组属性:NumPy数组具有各种属性,如形状(shape)、数据类型(dtype)、维度(ndim)、大小(size)等,可以用于了解数组的特征。 3 ''' 4 5 import numpy as np 6 7 # 创建一个包含零的数组 8 arr = np.zeros(5) 9 shape = arr.shape # 数组形状 10 dtype = arr.dtype # 数组数据类型 11 ndim = arr.ndim # 数组维度 12 size = arr.size # 数组大小(元素数量) 13 print(f"数组内容:{arr};数组形状:{shape};数组数据类型:{dtype};数组维度:{ndim};数组大小:{size}") 14 15 print("----------------------------------") 16 arr = np.array([[1, 2], [3, 4]]) 17 shape = arr.shape # 数组形状 18 dtype = arr.dtype # 数组数据类型 19 ndim = arr.ndim # 数组维度 20 size = arr.size # 数组大小(元素数量) 21 print(f"数组内容:{arr};数组形状:{shape};数组数据类型:{dtype};数组维度:{ndim};数组大小(元素数量):{size}")
输出:
1 2 3 4 | 数组内容:[ 0. 0. 0. 0. 0. ];数组形状:( 5 ,);数组数据类型:float64;数组维度: 1 ;数组大小: 5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 数组内容:[[ 1 2 ] [ 3 4 ]];数组形状:( 2 , 2 );数组数据类型:int32;数组维度: 2 ;数组大小: 4 |
3. 数组索引和切片:与Python列表一样,您可以使用索引和切片操作来访问和修改NumPy数组中的元素。
1 import numpy as np 2 3 # 从Python列表创建数组 4 my_list = [1, 2, 3, 4, 5] 5 arr = np.array(my_list) 6 7 element = arr[2] # 获取索引为2的元素 8 print(element) # 3 9 sub_array = arr[1:4] # 获取索引1到3的子数组 10 print(f"sub_array={sub_array}") # sub_array=[2 3 4]
输出:
1 2 | 3 sub_array = [ 2 3 4 ] |
4. 数学运算:NumPy支持各种数学运算,包括加法、减法、乘法、除法等,这些运算可以应用于数组的元素级别。
1 import numpy as np 2 3 # 创建两个数组 4 arr1 = np.array([1, 2, 3]) 5 arr2 = np.array([4, 5, 6]) 6 7 result = arr1 + arr2 # 数组加法 8 print(f"result的type={type(result)},其内容={result}") # result的type=<class 'numpy.ndarray'>,其内容=[5 7 9] 9 result = arr1 * 2 # 数组与标量相乘,每个元素都乘以标量 10 print(f"result内容={result}") # result内容=[2 4 6]
最佳实践:
-
使用矢量化操作:NumPy鼓励使用矢量化操作,而不是显式循环遍历数组。这样可以提高性能,因为底层库通常会针对整个数组进行操作,而不是单个元素。
-
了解数据类型:在创建数组时,了解所需的数据类型很重要,因为它可以影响内存使用和计算性能。可以使用
dtype
参数指定数据类型。 -
避免修改原始数组:NumPy数组是可变的,但最好避免直接修改原始数组,以免产生意外结果。使用数组的拷贝来进行修改操作。
-
利用广播:NumPy的广播机制允许您对不同形状的数组执行运算,但需要满足一定的条件。了解广播规则可以帮助您更有效地编写代码。
示例:
1 import numpy as np 2 3 # 0. 创建两个数组 4 arr1 = np.array([1, 2, 3]) 5 arr2 = np.array([4, 5, 6]) 6 7 # 1. 数组运算: 对应元素相加 8 result = arr1 + arr2 # [5 7 9] 9 print(f"result={result}") 10 # 2. 计算均值 11 mean_val = np.mean(arr1) # 2.0 12 print(f"数组arr1的平均值mean_val={mean_val}") 13 14 # 3. 生成等差数列 15 arange_arr = np.arange(0, 10, 2) # [0 2 4 6 8],不包括10哦 16 print(f"等差数列arange_arr={arange_arr}") 17 18 # 4. 生成随机数组 19 rand_arr = np.random.rand(3, 3) # 3x3的随机数组 20 print(f"随机数rand_arr={rand_arr}") 21 22 # 5. 计算矩阵乘法 23 mat1 = np.array([[1, 2], [3, 4]]) # 2 X 2 24 mat2 = np.array([[5, 6], [7, 8]]) # 2 X 2 25 mat_product = np.dot(mat1, mat2) # 矩阵乘法的结果2 X 2 26 print(f"计算矩阵乘法运算结果mat_product={mat_product}") 27 28 # 6. 通过布尔条件选择元素 29 bool_arr = arr1 > 2 30 print(f"bool_arr={bool_arr}") # [False False True] 31 filtered_arr = arr1[bool_arr] # [3],只要对应位置是True的 32 print(f"filtered_arr={filtered_arr}") 33 34 # 7. 修改数组形状 35 reshape_arr = arr1.reshape(3, 1) # 将数组形状改为3x1 即2维数组(1个数组有3个元素,每个元素也是数组并且只有1个元素) 36 print(f"reshape_arr={reshape_arr}") 37 38 # 8.求和 39 sum_val = np.sum(arr1) # 6 40 print(f"sum_val={sum_val}")
这些示例涵盖了NumPy数组的一些常见操作,但NumPy提供了许多其他功能,用于线性代数、统计分析、数据处理等。了解NumPy的文档和教程可以帮助您更深入地掌握这个强大的库。
4. Java语言中的数组
在Java中,数组是一种用于存储多个相同数据类型元素的数据结构。数组具有固定的大小,一旦创建,大小不能更改(ArrayList可以动态扩容)。
严格上讲Java中的数组是包括ArrayList
4.1 创建数组:
在Java中,有两种方法来创建数组:
1. 使用数组初始化器:使用大括号 {}
来初始化一个数组,并在大括号内放置元素的值。例如:
int[] numbers = {1, 2, 3, 4, 5};
2. 使用new
关键字:使用new
关键字来创建一个新的数组,并指定数组的类型和大小。例如
int[] numbers = new int[5]; // 创建一个包含5个整数的数组
4.2 访问数组元素:
可以使用索引来访问数组中的元素,索引从0开始。例如,要访问上面示例中的数组元素:
int firstElement = numbers[0]; // 获取第一个元素,值为1 int secondElement = numbers[1]; // 获取第二个元素,值为2
4.3 修改指定位置元素的值
numbers[1] = 88;
4.4 数组长度:
可以使用length
属性来获取数组的长度(即元素的数量)。例如:
int length = numbers.length; // 获取数组的长度,值为5
4.5 遍历数组:
通常,您会使用循环来遍历数组中的元素。Java提供了多种循环方式,如for
循环、while
循环等。以下是一个使用for
循环遍历数组的示例:
for (int i = 0; i < numbers.length; i++) { System.out.println(numbers[i]); }
int[] numbers = {1, 2, 3, 4, 5}; for (int i : numbers) { System.out.println(i); }
for-each遍历是无法保证遍历的顺序的(随机的)
4.6 删除数组中的元素
在Java中,数组是一种固定大小的数据结构,因此删除数组元素的操作相对复杂。 一般都是修改数组的值,让其变成一个垃圾或无意义的值
通常,删除数组元素需要创建一个新的数组,然后将原始数组中不需要的元素排除在外。以下是删除Java数组元素的几种常见方法:
方法1:创建新数组
-
根据索引删除元素:要删除数组中特定索引位置的元素,您需要创建一个新数组,将不需要删除的元素复制到新数组中。
int[] originalArray = {1, 2, 3, 4, 5}; int indexToDelete = 2; // 要删除的元素的索引 // 创建一个新数组,大小比原始数组小1 int[] newArray = new int[originalArray.length - 1]; // 复制不需要删除的元素到新数组 for (int i = 0, j = 0; i < originalArray.length; i++) { if (i != indexToDelete) { newArray[j++] = originalArray[i]; } }
2. 根据值删除元素:如果要删除数组中特定值的元素,您需要遍历数组以找到该值的索引,然后使用上述方法删除索引处的元素。
int[] originalArray = {1, 2, 3, 4, 5}; int valueToDelete = 3; // 要删除的值 int indexToDelete = -1; // 初始化为-1,表示未找到 for (int i = 0; i < originalArray.length; i++) { if (originalArray[i] == valueToDelete) { indexToDelete = i; break; } } if (indexToDelete != -1) { // 创建一个新数组,大小比原始数组小1 int[] newArray = new int[originalArray.length - 1]; // 复制不需要删除的元素到新数组 for (int i = 0, j = 0; i < originalArray.length; i++) { if (i != indexToDelete) { newArray[j++] = originalArray[i]; } } }
方法2:使用ArrayList
另一种更方便的方法是使用ArrayList
,这是Java集合框架中的一个动态数组实现。ArrayList
可以自动调整大小,因此可以轻松添加和删除元素。
import java.util.ArrayList; ArrayList<Integer> arrayList = new ArrayList<>(); arrayList.add(1); arrayList.add(2); arrayList.add(3); arrayList.add(4); arrayList.add(5); int indexToDelete = 2; // 要删除的元素的索引 arrayList.remove(indexToDelete); // 删除指定索引的元素
或者,如果要删除特定值的元素:
int valueToDelete = 3; // 要删除的值 arrayList.remove(Integer.valueOf(valueToDelete)); // 删除特定值的元素
使用ArrayList
的优势是可以轻松添加和删除元素,而不需要手动管理数组大小。
总之,删除Java数组元素通常需要创建一个新数组,将不需要删除的元素复制到新数组中,或者使用ArrayList
来实现自动调整大小和元素删除。选择哪种方法取决于您的需求和应用场景。
4.6 多维数组:
Java支持多维数组,这是数组的数组。例如,您可以创建一个二维数组来表示矩阵:
int[][] matrix = { {1, 2, 3}, {4, 5, 6}, {7, 8, 9} };
要访问多维数组中的元素,您需要使用多个索引:
int element = matrix[1][2]; // 获取第二行第三列的元素,值为6
数组的限制:
Java数组具有以下限制:
-
大小固定:一旦创建,数组的大小不能更改。如果需要动态大小的集合,可以使用ArrayList等集合类。
-
同一类型元素:Java数组要求所有元素具有相同的数据类型。
-
下标越界:访问数组元素时,如果使用超出范围的索引,将引发
ArrayIndexOutOfBoundsException
异常。 -
数组是对象:在Java中,数组是对象,因此它们具有一些与对象相关的特性,如
equals()
方法、hashCode()
方法等。
示例:
public class ArrayExample { public static void main(String[] args) { // 创建一个整数数组 int[] numbers = {1, 2, 3, 4, 5}; // 访问数组元素 int firstElement = numbers[0]; int secondElement = numbers[1]; // 遍历数组并打印元素 for (int i = 0; i < numbers.length; i++) { System.out.println("Element at index " + i + ": " + numbers[i]); } } }
5. JavaScript中的数组
JavaScript中的数组是一种动态的数据结构,用于存储多个值。
JavaScript数组可以包含不同类型的数据,包括数字、字符串、对象等,并且数组的大小可以动态调整。
5.1 创建数组:
JavaScript数组可以使用以下方式创建:
1. 使用数组字面量:使用方括号 []
创建一个新数组,并在方括号内放置数组的元素。java是花括号{},例如:
let numbers = [1, 2, 3, 4, 5];
2. 使用Array
构造函数:使用new Array()
构造函数创建一个新数组。您可以传递数组的大小或元素给构造函数。例如:
let numbers = new Array(1, 2, 3, 4, 5);
或者
let numbers = new Array(5); // 创建一个长度为5的空数组,元素都是undefined
5.2 访问数组元素:
可以使用索引来访问数组中的元素,索引从0开始。例如,要访问上面示例中的数组元素:
let firstElement = numbers[0]; // 获取第一个元素,值为1 let secondElement = numbers[1]; // 获取第二个元素,值为2
5.3 数组长度:
可以使用length
属性来获取数组的长度(即元素的数量)。例如:
let length = numbers.length; // 获取数组的长度,值为5
5.4 遍历数组:
通常,您会使用循环来遍历数组中的元素。JavaScript提供了多种循环方式,如for
循环、while
循环、for...of
循环等。以下是一个使用for
循环遍历数组的示例:
for (let i = 0; i < numbers.length; i++) { console.log(numbers[i]); }
或者使用for...of
循环:
for (let number of numbers) { console.log(number); }
5.5 多维数组:
JavaScript支持多维数组,这是数组的数组。例如,您可以创建一个二维数组来表示矩阵:
let matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ];
要访问多维数组中的元素,您需要使用多个索引:
let element = matrix[1][2]; // 获取第二行第三列的元素,值为6
数组的方法:
JavaScript数组有许多内置方法,用于执行各种操作,如添加、删除、修改、搜索和排序元素。以下是一些常用的数组方法:
push()
: 在数组末尾添加一个元素。pop()
: 删除最后一个元素并返回数组的最后一个元素。shift()
: 删除并返回数组的第一个元素。unshift()
: 在数组开头添加一个元素。splice()
: 在指定位置插入、删除或替换元素。concat()
: 连接两个或多个数组。join()
: 将数组元素连接成一个字符串。slice()
: 返回数组的一部分(浅复制)。indexOf()
: 查找元素在数组中的索引。includes()
: 检查数组是否包含某个元素。forEach()
: 遍历数组并执行指定的函数。map()
: 遍历数组并创建一个新数组,其中包含对原始数组的每个元素应用函数后的结果。filter()
: 遍历数组并创建一个新数组,其中包含满足指定条件的元素。reduce()
: 对数组中的元素执行累积操作。sort()
: 对数组元素进行排序。reverse()
: 反转数组元素的顺序。
示例:
1. push()
: 在数组末尾添加一个或多个元素,并返回新的数组长度。
let fruits = ["apple", "banana"]; let newLength = fruits.push("cherry"); // fruits 数组现在是 ["apple", "banana", "cherry"] // newLength 值为 3
2. pop()
: 删除数组末尾的元素并返回该元素的值。
let fruits = ["apple", "banana", "cherry"]; let removedFruit = fruits.pop(); // removedFruit 值为 "cherry" // fruits 数组现在是 ["apple", "banana"]
3. shift()
: 删除数组开头的元素并返回该元素的值。
let fruits = ["apple", "banana", "cherry"]; let removedFruit = fruits.shift(); // removedFruit 值为 "apple" // fruits 数组现在是 ["banana", "cherry"]
4. unshift()
: 在数组开头添加一个或多个元素,并返回新的数组长度。
let fruits = ["banana", "cherry"]; let newLength = fruits.unshift("apple"); // fruits 数组现在是 ["apple", "banana", "cherry"] // newLength 值为 3
5. splice()
: 在指定位置插入、删除或替换元素。
let fruits = ["apple", "banana", "cherry"]; fruits.splice(1, 1, "orange", "grape"); // 在索引 1 处删除一个元素并插入 "orange" 和 "grape" // fruits 数组现在是 ["apple", "orange", "grape", "cherry"]
6. concat()
: 连接两个或多个数组,并返回一个新的数组。
let fruits1 = ["apple", "banana"]; let fruits2 = ["cherry", "orange"]; let allFruits = fruits1.concat(fruits2); // allFruits 数组现在是 ["apple", "banana", "cherry", "orange"]
7. join()
: 将数组元素连接成一个字符串,使用指定的分隔符。
let fruits = ["apple", "banana", "cherry"]; let joinedString = fruits.join(", "); // joinedString 值为 "apple, banana, cherry"
8. slice()
: 返回数组的一部分(浅复制)。
let fruits = ["apple", "banana", "cherry", "orange"]; let slicedFruits = fruits.slice(1, 3); // 从索引 1 开始,到索引 2 结束(不包含索引 3) // slicedFruits 数组现在是 ["banana", "cherry"]
9. indexOf()
: 查找元素在数组中的索引,如果不存在返回 -1。
let fruits = ["apple", "banana", "cherry"]; let index = fruits.indexOf("banana"); // index 值为 1
10. includes()
: 检查数组是否包含某个元素,返回布尔值。
let fruits = ["apple", "banana", "cherry"]; let includesBanana = fruits.includes("banana"); // includesBanana 值为 true
11. forEach()
: 遍历数组并执行指定的函数。
let numbers = [1, 2, 3]; numbers.forEach(function(number) { console.log(number); }); // 输出:1 2 3
12. map()
: 遍历数组并创建一个新数组,其中包含对原始数组的每个元素应用函数后的结果。
let numbers = [1, 2, 3]; let squaredNumbers = numbers.map(function(number) { return number * number; }); // squaredNumbers 数组现在是 [1, 4, 9]
13. filter()
: 遍历数组并创建一个新数组,其中包含满足指定条件的元素。
let numbers = [1, 2, 3, 4, 5]; let evenNumbers = numbers.filter(function(number) { return number % 2 === 0; }); // evenNumbers 数组现在是 [2, 4]
14. reduce()
: 对数组中的元素执行累积操作。
let numbers = [1, 2, 3, 4, 5]; let sum = numbers.reduce(function(accumulator, currentValue) { return accumulator + currentValue; }, 0); // sum 值为 15
15. sort()
: 对数组元素进行排序,默认按字符顺序。
let fruits = ["cherry", "apple", "banana"]; fruits.sort(); // fruits 数组现在是 ["apple", "banana", "cherry"]
16. reverse()
: 反转数组元素的顺序。
let fruits = ["apple", "banana", "cherry"]; fruits.reverse(); // fruits 数组现在是 ["cherry", "banana", "apple"]
这些是JavaScript中一些常见的数组方法,它们可以用于对数组进行各种操作,从添加和删除元素到转换和搜索元素。根据您的需求,选择适当的方法以实现所需的功能
示例:
以下是一个完整的JavaScript数组示例,演示了数组的创建、访问、遍历和使用一些常见方法:
// 创建一个数组 let fruits = ["apple", "banana", "cherry"]; // 访问数组元素 let firstFruit = fruits[0]; // 获取第一个元素,值为 "apple" // 遍历数组并打印元素 for (let i = 0; i < fruits.length; i++) { console.log(fruits[i]); } // 使用数组方法添加元素 fruits.push("orange"); // 在末尾添加 "orange" fruits.unshift("strawberry"); // 在开头添加 "strawberry" // 使用数组方法删除元素 fruits.pop(); // 删除末尾元素 fruits.shift(); // 删除开头元素 // 使用数组方法查找元素 let index = fruits.indexOf("banana"); // 查找 "banana" 的索引,值为 1 // 使用数组方法连接数组 let moreFruits = ["grape", "kiwi"]; let allFruits = fruits.concat(moreFruits); // 连接两个数组 // 使用数组方法遍历并执行函数 fruits.forEach(function(fruit) { console.log("I love " + fruit); });
这个示例展示了JavaScript数组的创建、访问、遍历以及如何使用一些常见的数组方法。JavaScript数组是非常灵活且强大的数据结构,用于处理各种数据和任务。
分类
一维
二维
三维
n维
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!