带你了解Java数据结构和算法之数组
作者:YSOcean 发布时间:2022-09-29 21:18:33
1、Java数组介绍
在Java中,数组是用来存放同一种数据类型的集合,注意只能存放同一种数据类型(Object类型数组除外)。
①、数组的声明
第一种方式:
数据类型 [] 数组名称 = new 数据类型[数组长度];
这里 [] 可以放在数组名称的前面,也可以放在数组名称的后面,我们推荐放在数组名称的前面,这样看上去 数据类型 [] 表示的很明显是一个数组类型,而放在数组名称后面,则不是那么直观。
第二种方式:
数据类型 [] 数组名称 = {数组元素1,数组元素2,......}
这种方式声明数组的同时直接给定了数组的元素,数组的大小由给定的数组元素个数决定。
//声明数组1,声明一个长度为3,只能存放int类型的数据
int [] myArray = new int[3];
//声明数组2,声明一个数组元素为 1,2,3的int类型数组
int [] myArray2 = {1,2,3};
②、访问数组元素以及给数组元素赋值
数组是存在下标索引的,通过下标可以获取指定位置的元素,数组小标是从0开始的,也就是说下标0对应的就是数组中第1个元素,可以很方便的对数组中的元素进行存取操作。
前面数组的声明第二种方式,我们在声明数组的同时,也进行了初始化赋值。
//声明数组,声明一个长度为3,只能存放int类型的数据
int [] myArray = new int[3];
//给myArray第一个元素赋值1
myArray[0] = 1;
//访问myArray的第一个元素
System.out.println(myArray[0]);
上面的myArray 数组,我们只能赋值三个元素,也就是下标从0到2,如果你访问 myArray[3] ,那么会报数组下标越界异常。
③、数组遍历
数组有个 length 属性,是记录数组的长度的,我们可以利用length属性来遍历数组。
//声明数组2,声明一个数组元素为 1,2,3的int类型数组
int [] myArray2 = {1,2,3};
for(int i = 0 ; i < myArray2.length ; i++){
System.out.println(myArray2[i]);
}
2、用类封装数组实现数据结构
上一篇博客我们介绍了一个数据结构必须具有以下基本功能:
①、如何插入一条新的数据项
②、如何寻找某一特定的数据项
③、如何删除某一特定的数据项
④、如何迭代的访问各个数据项,以便进行显示或其他操作
而我们知道了数组的简单用法,现在用类的思想封装一个数组,实现上面的四个基本功能:
ps:假设操作人是不会添加重复元素的,这里没有考虑重复元素,如果添加重复元素了,后面的查找,删除,修改等操作只会对第一次出现的元素有效。
package com.ys.array;
public class MyArray {
//定义一个数组
private int [] intArray;
//定义数组的实际有效长度
private int elems;
//定义数组的最大长度
private int length;
//默认构造一个长度为50的数组
public MyArray(){
elems = 0;
length = 50;
intArray = new int[length];
}
//构造函数,初始化一个长度为length 的数组
public MyArray(int length){
elems = 0;
this.length = length;
intArray = new int[length];
}
//获取数组的有效长度
public int getSize(){
return elems;
}
/**
* 遍历显示元素
*/
public void display(){
for(int i = 0 ; i < elems ; i++){
System.out.print(intArray[i]+" ");
}
System.out.println();
}
/**
* 添加元素
* @param value,假设操作人是不会添加重复元素的,如果有重复元素对于后面的操作都会有影响。
* @return添加成功返回true,添加的元素超过范围了返回false
*/
public boolean add(int value){
if(elems == length){
return false;
}else{
intArray[elems] = value;
elems++;
}
return true;
}
/**
* 根据下标获取元素
* @param i
* @return查找下标值在数组下标有效范围内,返回下标所表示的元素
* 查找下标超出数组下标有效值,提示访问下标越界
*/
public int get(int i){
if(i<0 || i>elems){
System.out.println("访问下标越界");
}
return intArray[i];
}
/**
* 查找元素
* @param searchValue
* @return查找的元素如果存在则返回下标值,如果不存在,返回 -1
*/
public int find(int searchValue){
int i ;
for(i = 0 ; i < elems ;i++){
if(intArray[i] == searchValue){
break;
}
}
if(i == elems){
return -1;
}
return i;
}
/**
* 删除元素
* @param value
* @return如果要删除的值不存在,直接返回 false;否则返回true,删除成功
*/
public boolean delete(int value){
int k = find(value);
if(k == -1){
return false;
}else{
if(k == elems-1){
elems--;
}else{
for(int i = k; i< elems-1 ; i++){
intArray[i] = intArray[i+1];
}
elems--;
}
return true;
}
}
/**
* 修改数据
* @param oldValue原值
* @param newValue新值
* @return修改成功返回true,修改失败返回false
*/
public boolean modify(int oldValue,int newValue){
int i = find(oldValue);
if(i == -1){
System.out.println("需要修改的数据不存在");
return false;
}else{
intArray[i] = newValue;
return true;
}
}
}
测试:
package com.ys.test;
import com.ys.array.MyArray;
public class MyArrayTest {
public static void main(String[] args) {
//创建自定义封装数组结构,数组大小为4
MyArray array = new MyArray(4);
//添加4个元素分别是1,2,3,4
array.add(1);
array.add(2);
array.add(3);
array.add(4);
//显示数组元素
array.display();
//根据下标为0的元素
int i = array.get(0);
System.out.println(i);
//删除4的元素
array.delete(4);
//将元素3修改为33
array.modify(3, 33);
array.display();
}
}
打印结果为:
3、分析数组的局限性
通过上面的代码,我们发现数组是能完成一个数据结构所有的功能的,而且实现起来也不难,那数据既然能完成所有的工作,我们实际应用中为啥不用它来进行所有的数据存储呢?那肯定是有原因呢。
数组的局限性分析:
①、插入快,对于无序数组,上面我们实现的数组就是无序的,即元素没有按照从大到小或者某个特定的顺序排列,只是按照插入的顺序排列。无序数组增加一个元素很简单,只需要在数组末尾添加元素即可,但是有序数组却不一定了,它需要在指定的位置插入。
②、查找慢,当然如果根据下标来查找是很快的。但是通常我们都是根据元素值来查找,给定一个元素值,对于无序数组,我们需要从数组第一个元素开始遍历,直到找到那个元素。有序数组通过特定的算法查找的速度会比无需数组快,后面我们会讲各种排序算法。
③、删除慢,根据元素值删除,我们要先找到该元素所处的位置,然后将元素后面的值整体向前面移动一个位置。也需要比较多的时间。
④、数组一旦创建后,大小就固定了,不能动态扩展数组的元素个数。如果初始化你给一个很大的数组大小,那会白白浪费内存空间,如果给小了,后面数据个数增加了又添加不进去了。
很显然,数组虽然插入快,但是查找和删除都比较慢,而且扩展性差,所以我们一般不会用数组来存储数据,那有没有什么数据结构插入、查找、删除都很快,而且还能动态扩展存储个数大小呢,答案是有的,但是这是建立在很复杂的算法基础上,后面我们也会详细讲解。
4、总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
来源:https://www.cnblogs.com/ysocean/p/7894448.html
猜你喜欢
- 本文实例为大家分享了Java实现猜数字游戏的具体代码,供大家参考,具体内容如下完成猜数字游戏需要实现以下几点:获得一个随机数作为“答案数”;
- Struts2的核心功能是action,对于开发人员来说,使用Struts2主要就是编写action,action类通常都要实现com.op
- 话不多说,请看代码:package com.lxj.demo;import java.io.BufferedReader;import ja
- 前言:在新增的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题。通过这些高效并且线程
- Spring内置 * 对于 Web 应用来说,ServletContext 对象是唯一的,一个 Web 应用,只有一个ServletCont
- IDEA版本:2020.3具体步骤一、开启IDEA的自动编译【静态】1.File->Settings。2.直接搜索Compiler,选
- 本文实例讲述了java使用Hashtable过滤数组中重复值的方法。分享给大家供大家参考,具体如下:package org.eline.co
- 本文实例讲述了java数据结构与算法之快速排序。分享给大家供大家参考,具体如下:交换类排序的另一个方法,即快速排序。快速排序:改变了冒泡排序
- 1. 概述为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。2. 模式中的角色2.1 外
- 在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题:class Grandpa{static{System.o
- 本文实例讲述了java统计字符串中重复字符出现次数的方法。分享给大家供大家参考,具体如下:package com;import org.ju
- 采集器概貌,如下:最近做一个项目,功能类似于CNZZ站长统计功能,要求显示Ip所在的省份市区/提供商等信息。网上的Ip纯真数据库,下载下来一
- JPA连接到数据库,调用存储过程,这样的需求很常见。本文就针对这一点,讲述如何使用spring Data JPA调用存储过程的方法。1、存储
- 中断线程线程的thread.interrupt()方法是中断线程,将会设置该线程的中断状态位,即设置为true,中断的结果线程是死亡、还是等
- 在一些允许用户自定义栏目顺序的app(如:凤凰新闻、网易云音乐等),我们可以方便地拖拽列表项来完成列表的重新排序,进而完成对栏目顺序的重排。
- SpringBoot启动yaml报错报错找不到org.yaml里的一个方法10:45:54.742 [main] ERROR org.spr
- 悲观锁、乐观锁简介: 悲观锁:同步操作。即用户A在操作某条数据时,为其上锁,限制其他用户操作,用户A操作完成提交事务后其他用户方可
- 这里并未涉及到JSR 181 Annotations 的相关应用,具体的三种方式如下① 通过WSDL地址来创建动态客户端 ② 通过服务端提供
- 使用过 mybatis 框架的小伙伴们都知道,mybatis 是个半 orm 框架,通过写 mapper 接口就能自动实现数据库的增删改查,
- 前言之前用简书的时候一直是在web端,后来下载了客户端,看到了搜索的那个动画,就尝试的去写了,没写之前感觉挺容易的,写了之后,就感觉里面还是