在java程序设计中,经常需要用到数组,数组的存储和读取速度是数据结构中最快的一种。但是,在稍为复杂的程序设计中,我们就会发现数组的局限性,其局限性有一部分是其优点所带来的。例如:数组的长度是固定的,而且数组所存储的数据类型也是固定的。然而,在实际应用中,经常需要根据所要存储的数据的长度确定要开辟的内存空间,而且,需要存储不同类型的数据,例如存储对象。另一方面,我们需要一些通用的方法,以便对不同类型的对象进行处理,例如:一种通用的排序方法,对所有类型的对象都可以进行排序。这样,就可以增加代码的重用度,减少工作量。
由于在java中,Object是所有类的父类,因此在这些方法中,要把参数,返回值设为Object类型的,以便接收所有类型的对象。
为深入体会泛型的作用,我们先在不使用泛型的前提下,写一个数组队列类,对所有类型的传人对象都能进行处理。数组队列具有数组所不具有的灵活性,其长度可变,存储的数据类型可变。
下面是一个自定义的数组队列类,具有增删查改功能
package cn.lzj0724; /** * 纯粹的数组队列,实行增删改查等功能,一个第三方的类 * * @author lzj * */ public class MyArrayList{ private Object[] array;// 声明对象数组 private int size = 0;// 声明size属性,设置初值为0 /** * 构造方法 */ public MyArrayList() { array = new Object[0];// 初始化 } public MyArrayList(int size) { array = new Object[size];// 初始化 } /** * 向数组队列中添加元素的方法 * * @param elements要添加的元素 */ public void add(Object element) { // 创建一个新的数组,长度为size+1 Object[] newArray = new Object[size + 1]; for (int i = 0; i < size; i++) { newArray[i] = array[i];// 赋值 } newArray[size] = element;// 添加元素至数组最后的位置 size++;// size加1 array = newArray;// 把newArray的地址给array } /** * 根据索引删除对应的元素(删除区别于移除,删除需要释放空间) * * @param index要删除的元素的索引 * @return */ public Object delete(int index) { if (index < 0 || index >= size)// 防止所给下标为负值或超出size return null; Object temp;// Object类型变量 temp = array[index];// 将被删除的元素赋予临时变量temp Object[] newArray = new Object[size - 1];// 创建Object类数组,数组长度减1 // 小于索引时,照搬过去 for (int i = 0; i < index; i++) { newArray[i] = array[i];// 把值移到新数组中 } // 大于索引时 for (int i = index; i < size - 1; i++) { array[i] = array[i + 1];// 移位填补空位 newArray[i] = array[i];// 把值移到新数组中 } array = newArray;// 把newArray的地址给array size--; return temp;// 返回被删除的元素 } /** * 根据索引插入对应的元素 * * @param index要插入的位置的索引 * @return */ public Object ins(int index, Object element) { Object[] newArray = new Object[size + 1];// 创建Object类数组,数组长度减1 // 小于索引时,照搬过去 for (int i = 0; i < index; i++) { newArray[i] = array[i];// 把值移到新数组中 } newArray[index] = element; // 大于索引时 for (int i = index; i < size; i++) { newArray[i + 1] = array[i];// 把值移到新数组中 } array = newArray;// 把newArray的地址给array size++; return element;// 返回被插入的元素 } // 得到数组队列的长度的方法 public int size() { return size; } // 根据索引和传人的元素设定相应的元素 public void set(int index, Object obj) { array[index] = obj; } // 根据索引得到相应的元素 public Object get(int index) { if (index < 0 || index >= size)// 防止所给下标为负值或超出size return null; return array[index]; } public Object find(Object obj) { for (int i = 0; i < size; i++) { if (array[i].equals(obj)) return array[i]; } return null; } // 修改元素,根据元素和下标 public void modify(Object element, int index) { array[index] = element; } }
测试数组队列:
package cn.lzj0724; import java.util.Scanner; /** * 测试数组队列的类 * * @author lzj * */ public class TestArrayList { public static void main(String[] args) { // 实例化MyArrayList类的对象 数组队列对象 MyArrayList list = new MyArrayList(); Student[] stu = new Student[5];//实例化一个Student类型的数组 // 实例化一个随机类对象 java.util.Random rand = new java.util.Random(); int size = stu.length; // 循环添加元素 for (int i = 0; i < size; i++) { stu[i] = new Student("张" + i, "male", i, rand.nextInt(100), rand.nextInt(100), rand.nextInt(100));// 创建学生数组,随机分数 list.add(stu[i]);// 将Student元素添加到数组队列之中 System.out.println(list.get(i));// 输出 } System.out.println("------------------------"); list.delete(2);// 删除数组队列中下标为2的元素 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i));// 输出 } System.out.println("------------------------"); list.modify(stu[1], 3);// 把数组队列中下标为3的元素修改为下标为1的元素 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("----排序后-------"); sort(list);//调用排序方法 for (int i = 0; i < list.size(); i++) {// 输出 System.out.println(list.get(i)); } System.out.println("------------------------"); Student stu9 =new Student("张六", "male", 9, rand.nextInt(100), rand.nextInt(100), rand.nextInt(100)); list.ins(3,stu9);// 创建学生数组,随机分数) for (int i = 0; i < list.size(); i++) {// 输出 System.out.println(list.get(i)); } // 选择排序 public static void sort(MyArrayList list) { Student[] stu = new Student[list.size()];// 定义Student类型数组 for (int i = 0; i < list.size(); i++) { stu[i] = (Student) list.get(i);// 强制转换为Student类型 } for (int i = 0; i < list.size(); i++) { int minIndex = i; // 找出最小的一个索引 for (int j = i + 1; j < list.size(); j++) { if (stu[j].getAverage() < stu[minIndex].getAverage()) { minIndex = j; } } // 交换 Student temp = stu[i]; stu[i] = stu[minIndex]; stu[minIndex] = temp; } for (int i = 0; i < list.size(); i++) { list.set(i, stu[i]);//把改变后的stu数组应用到list中 } } }
运行结果如下:
代码实现了对学生信息的管理和排序处理,也可以看出,由于list不能直接调用Student类的子方法,该代码排序时事实上是对学生数组进行了排序处理,然后才逐个add到数组队列list中的。若不能实现对list的直接处理的话,代码的冗余度将会很高,在对不同的类进行处理时,也要修改,添加很多行的代码。
那么如何解决这个问题呢?
需要用到泛型。对MyArrayList类进行修改
泛型可以泛指java中的任意一种引用类型(不能指代基本数据类型)。
泛型的格式:
类名<引用数据类型> 对象名 = new 类名<引用数据类型> ( );
Java中的泛型有三种,分别为E、K、V,E是element,代表元素的数据类型;K即key,代表键值类型;V即value,代表值的类型。
声明支持泛型的类的方法:
Public class 类名 <E> { }
为方法添加元素的时候,形参表中应将元素声明为泛型型,泛指任意一种引用类型,即用户可以在实参表中填入任意数据类型。方法的返回值类型也应为泛型,在返回之前需要强制转型为泛型。
对于支持泛型的类,在创建类的对象时为了防止任意类型的元素被传入,可以再创建对象时使用尖括号指定特定的引用数据类型,此时如果向对象中传入非指定的引用类型的数据类型便会引发错误提示。
例如:
public E get(int index){ E st = (E)array[index]; return st; }
这样,在使用该队列对象前,只要指定要放入对象的类型,之后,这个队列就只能放入这种类型的对象,而且,取出后,也是这种类型的对象
使用泛型的数组队列类如下:
package cn.lzj0724; /** * 纯粹的数组队列,实行增删改查等功能,一个第三方的类 * * @author lzj * */ public class MyArrayList<E> { private Object[] array;// 声明对象数组 private int size = 0;// 声明size属性,设置初值为0 /** * 构造方法 */ public MyArrayList() { array = new Object[0];// 初始化 } public MyArrayList(int size) { array = new Object[size];// 初始化 } /** * 向数组队列中添加元素的方法 * * @param elements要添加的元素 */ public void add(E element) { // 创建一个新的数组,长度为size+1 Object[] newArray = new Object[size + 1]; for (int i = 0; i < size; i++) { newArray[i] = array[i];// 赋值 } newArray[size] = element;// 添加元素至数组最后的位置 size++;// size加1 array = newArray;// 把newArray的地址给array } /** * 根据索引删除对应的元素(删除区别于移除,删除需要释放空间) * * @param index要删除的元素的索引 * @return */ public E delete(int index) { if (index < 0 || index >= size)// 防止所给下标为负值或超出size return null; Object temp;// Object类型变量 temp = array[index];// 将被删除的元素赋予临时变量temp Object[] newArray = new Object[size - 1];// 创建Object类数组,数组长度减1 // 小于索引时,照搬过去 for (int i = 0; i < index; i++) { newArray[i] = array[i];// 把值移到新数组中 } // 大于索引时 for (int i = index; i < size - 1; i++) { array[i] = array[i + 1];// 移位填补空位 newArray[i] = array[i];// 把值移到新数组中 } array = newArray;// 把newArray的地址给array size--; return (E) temp;// 返回被删除的元素 } /** * 根据索引插入对应的元素 * * @param index要插入的位置的索引 * @return */ public E ins(int index, E element) { Object[] newArray = new Object[size + 1];// 创建Object类数组,数组长度减1 // 小于索引时,照搬过去 for (int i = 0; i < index; i++) { newArray[i] = array[i];// 把值移到新数组中 } newArray[index] = element; // 大于索引时 for (int i = index; i < size; i++) { newArray[i + 1] = array[i];// 把值移到新数组中 } array = newArray;// 把newArray的地址给array size++; return element;// 返回被插入的元素 } // 得到数组队列的长度的方法 public int size() { return size; } // 根据索引和传人的元素设定相应的元素 public void set(int index, E obj) { array[index] = obj; } // 根据索引得到相应的元素 public E get(int index) { if (index < 0 || index >= size)// 防止所给下标为负值或超出size return null; return (E) array[index]; } public E find(E obj) { for (int i = 0; i < size; i++) { if (array[i].equals(obj)) return (E) array[i]; } return null; } // 修改元素,根据元素和下标 public void modify(E element, int index) { array[index] = element; } }
使用泛型的测试类如下:
package cn.lzj0724; import java.util.Scanner; /** * 测试数组队列的类 * * @author lzj * */ public class TestArrayList { public static void main(String[] args) { // 实例化MyArrayList类的对象 数组队列对象 MyArrayList<Student> list = new MyArrayList<Student>(); Student[] stu = new Student[5];// 实例化一个Student类型的数组 // 实例化一个随机类对象 java.util.Random rand = new java.util.Random(); int size = stu.length; // 循环添加元素 for (int i = 0; i < size; i++) { stu[i] = new Student("张" + i, "male", i, rand.nextInt(100), rand.nextInt(100), rand.nextInt(100));// 创建学生数组,随机分数 list.add(stu[i]);// 将Student元素添加到数组队列之中 System.out.println(list.get(i));// 输出 } System.out.println("------------------------"); list.delete(2);// 删除数组队列中下标为2的元素 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("------------------------"); list.modify(stu[1], 3);// 把数组队列中下标为3的元素修改为下标为1的元素 // 输出 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("----排序后-------"); sort(list);// 调用排序方法,传人MyArrayList类型对象 // 输出 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } System.out.println("------------------------"); Student stu9 = new Student("张六", "male", 9, rand.nextInt(100), rand.nextInt(100), rand.nextInt(100)); list.ins(3, stu9);// 把学生对象stu9插入数组队列3处 // 输出 for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } // 修改学生信息 Scanner read = new Scanner(System.in);// 实例化Scanner int i = -1; System.out.println(" 修改学生信息"); System.out.println(); System.out.println("======================="); System.out.println(); System.out.println("请输入要修改的学生学号:"); int number1 = read.nextInt();// 得到键盘输入的数字 for (i = 0; i < size; i++) { if (list.get(i).getNumber() == number1) { System.out.println(number1 + "学号的学生姓名为:" + list.get(i).getName()); System.out.println("1 姓名 2 性别 3 语文成绩 4 数学成绩 5 英语成绩"); System.out.println("该学生的哪一项信息需要修改:"); int r = read.nextInt();// 得到键盘输入的数字 switch (r) { case 1: System.out.println("原姓名为" + list.get(i).getName() + "现姓名修改为:"); String s1 = read.nextLine(); s1 = read.nextLine(); list.get(i).setName(s1);// 调用数组队列的第i个元素的setName方法,把name属性设置为s1 break; case 2: System.out.println("原姓别为" + list.get(i).getSex() + "现姓别修改为:"); String s2 = read.nextLine(); s2 = read.nextLine(); list.get(i).setSex(s2);// 调用数组队列的第i个元素的setSex方法,把sex属性设置为s2 break; case 3: System.out.println("原语文成绩为" + list.get(i).getChinese() + "现语文修改为:"); double d1 = read.nextDouble(); list.get(i).setChinese(d1);// 调用数组队列的第i个元素的setChinese方法,把Chinese属性设置为d1 break; case 4: System.out.println("原数学成绩为" + list.get(i).getChinese() + "现数学修改为:"); double d2 = read.nextDouble(); list.get(i).setMath(d2);// 调用数组队列的第i个元素的setMath方法,把Math属性设置为d2 break; case 5: System.out.println("原英语成绩为" + list.get(i).getChinese() + "现英语修改为:"); double d3 = read.nextDouble(); list.get(i).setEnglish(d3);// 调用数组队列的第i个元素的setEnglish方法,把English属性设置为d3 break; } } } for (int j = 0; j < list.size(); j++) {// 输出list数组队列中的内容 System.out.println(list.get(j)); } // 查找学生信息 Scanner read1 = new Scanner(System.in);// 实例化Scanner int j = -1; System.out.println(" 查找学生信息"); System.out.println(); System.out.println("======================="); System.out.println(); System.out.println("请输入要查找的学生学号:"); int number2 = read.nextInt(); System.out.println(number2 + "学号的学生姓名为:" + list.get(number2).getName()); System.out.println(list.get(number2));// 输出所查找的学生的全部信息 } // 选择排序 public static void sort(MyArrayList<Student> list) { for (int i = 0; i < list.size(); i++) { int minIndex = i; // 找出最小的一个索引 for (int j = i + 1; j < list.size(); j++) { if (list.get(j).getAverage() < list.get(minIndex).getAverage()) {// 调用第i个元素的getAverage方法,与下标为minIndex的元素的Average比较,若前者小于后者 minIndex = j;//把minIndex的值改为j } } // 交换 Student temp = list.get(i); list.set(i, list.get(minIndex)); list.set(minIndex, temp); } } }
所使用的学生类如下:
package cn.lzj0724; public class Student { private String name;// 姓名 private String sex;// 性别 private int number;// 学号 private double chinese, math, english;// 科目 private double average;// 平均分 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getNumber() { return number; } public void setNumber(int number) { this.number = number; } public double getChinese() { return chinese; } public void setChinese(double chinese) { this.chinese = chinese; } public double getMath() { return math; } public void setMath(double math) { this.math = math; } public double getEnglish() { return english; } public void setEnglish(double english) { this.english = english; } public double getAverage() { return average; } public void setAverage(double average) { this.average = average; } public Student() { } public Student(String name, String sex, int number, double chinese, double math, double english) { this.name = name; this.sex = sex; this.number = number; this.chinese = chinese; this.math = math; this.english = english; average = (chinese + math + english) / 3; } // 控制输出格式 public String toString() { return name + " " + "性别:" + sex + " 学号:" + number + " " + "语文:" + chinese + " " + "数学:" + math + " " + "英语:" + english + "平均分" + average; } /** * 重写比较方法,然后进行比较时调用 * @param stu * @return */ public boolean equals(Student [] stu){ return false; } }
收获:
1.学会了泛型的使用
2.学会了编写和使用数组队列,为五子棋的悔棋的实现打下了基础
不足:
1.对泛型的理解还不够深刻透彻
2.未实现学生信息管理的图形界面
相关推荐
hhhhh安卓开发教程大全
avem-labs_Avem_1740990015.zip
微信群机器人管理系统源码 微信群机器人管理系统源码 支持同登陆多个微信 源码类型: C/S 开发环境: VS2010 SQL2008R2 菜单功能 1、支持同时登录多个微信 2、支持机器人聊天(笑话,成语接龙、故事会、智力等等) 3、支持签到 4、可自定义回复 5、可自定义红包语 6、支持定期发送公告(如群规,广告)等 1、WeChatRobots后台配置web版 2、数据库在WeiChartGroup.Net/app_data中,附加即可
https://upload.csdn.net/creation/uploadResources?spm=1003.2018.3001.4314
名字微控制器_STM32_课程_DeepBlue_1740989720.zip
S7-200Smart恒压供水程序示例与485通讯实践:操作指南与案例解析,S7-200 Smart可编程控制器恒压供水程序设计与实现,附带485通讯范例,S7-200Smart 恒压供水程序样例+485通讯样例 ,S7-200Smart; 恒压供水程序样例; 485通讯样例,S7-200Smart程序样例:恒压供水及485通讯应用示例
Java使用JNA、JNI两种不同方式调用DLL、SO动态库方式读写M1卡源码,支持读写M1卡扇区数据、修改IC卡扇区密钥、改写UID卡卡号等功能,支持Windows系统,同时支持龙芯Mips、LoongArch、海思麒麟鲲鹏飞腾Arm、海光兆芯x86_Amd64等架构平台的国产统信、麒麟等Linux系统,内有jna-4.5.0.jar包,vx13822155058 qq954486673
UDP协议接收和发送数据示例JAVA
本文介绍了范德堡大学深脑刺激器(DBS)项目,该项目旨在开发和临床评估一个系统,以辅助从规划到编程的整个过程。DBS是一种高频刺激治疗,用于治疗运动障碍,如帕金森病。由于目标区域在现有成像技术中可见性差,因此DBS电极的植入和编程过程复杂且耗时。项目涉及使用计算机辅助手术技术,以及一个定制的微定位平台(StarFix),该平台允许在术前进行图像采集和目标规划,提高了手术的精确性和效率。此外,文章还讨论了系统架构和各个模块的功能,以及如何通过中央数据库和网络接口实现信息共享。
图像识别”项目源码资源(Python和C++)
虚拟同步电机与并电网模型的Simulink仿真参数配置与直接使用指南,虚拟同步电机与并电网模型的Simulink仿真:参数齐全,直接使用,同步电机simulink仿真 并电网模型仿真 参数设置好了,可直接使用 ,虚拟同步电机; simulink仿真; 并电网模型仿真; 参数设置; 使用,虚拟同步电机Simulink仿真与并电网模型参数化应用
三菱FX3U与力士乐VFC-x610变频器通讯案例详解:PLC控制下的变频器操作与设置程序,含接线方式及昆仑通态触摸屏操作指南,三菱FX3U与力士乐VFC-x610变频器通讯案例详解:接线、设置与程序注解,实现频率设定、启停控制与实时数据读取功能。,三菱FX3U与力士乐VFC-x610变频器通讯程序三菱FX3U与力士乐VFC-x610变频器通讯案例程序,有注释。 并附送程序,有接线方式,设置。 器件:三菱FX3U的PLC,力士乐VFCx610变频器,昆仑通态,威纶通触摸屏。 功能:实现频率设定,启停控制,实际频率读取等。 ,三菱FX3U;力士乐VFC-x610变频器;通讯程序;案例程序;注释;接线方式;设置;频率设定;启停控制;实际频率读取;昆仑通态;威纶通触摸屏。,三菱FX3U与力士乐VFC-x610变频器通讯程序及案例:频率控制与读取实践
xmselect测试用例~~~~~~~~~~~~~~
总共包含 32 款 AAA 级科幻武器。四种武器类型,每种有 8 种不同的纹理变化! 所有内容均采用 PBR 材质,可直接用于开发游戏!
python词云生成器,将txt文本自动分割生成词云图
智慧园区,作为现代城市发展的新形态,旨在通过高度集成的信息化系统,实现园区的智能化管理与服务。该方案提出,利用智能手环、定制APP、园区管理系统及物联网技术,将园区的各类设施与设备紧密相连,形成一个高效、便捷、安全的智能网络。从智慧社区到智慧酒店,从智慧景区到智慧康养,再到智慧生态,五大应用板块覆盖了园区的每一个角落,为居民、游客及工作人员提供了全方位、个性化的服务体验。例如,智能手环不仅能实现定位、支付、求助等功能,还能监测用户健康状况,让科技真正服务于生活。而智慧景区的建设,更是通过大数据分析、智能票务、电子围栏等先进技术,提升了游客的游玩体验,确保了景区的安全有序。 尤为值得一提的是,方案中的智慧康养服务,展现了科技对人文关怀的深刻体现。通过智慧手环与传感器,自动感知老人身体状态,及时通知家属或医疗机构,有效解决了“空巢老人”的照护难题。同时,智慧生态管理系统的应用,实现了对大气、水、植被等环境要素的实时监测与智能调控,为园区的绿色发展提供了有力保障。此外,方案还提出了建立全域旅游营销平台,整合区域旅游资源,推动旅游业与其他产业的深度融合,为区域经济的转型升级注入了新的活力。 总而言之,这份智慧园区建设方案以其前瞻性的理念、创新性的技术和人性化的服务设计,为我们展示了一个充满智慧与活力的未来园区图景。它不仅提升了园区的运营效率和服务质量,更让科技真正融入了人们的生活,带来了前所未有的便捷与舒适。对于正在规划或实施智慧园区建设的决策者而言,这份方案无疑提供了一份宝贵的参考与启示,激发了他们对于未来智慧生活的无限遐想与憧憬。
使用 SignalR 在 .NET Core 8 最小 API 中构建实时通知,构建实时应用程序已成为现代 Web 开发中必不可少的部分,尤其是对于通知、聊天系统和实时更新等功能。SignalR 是 ASP.NET 的一个强大库,可实现服务器端代码和客户端 Web 应用程序之间的无缝实时通信。 参考文章:https://blog.csdn.net/hefeng_aspnet/article/details/145990801
自适应网址导航网站发布页单页网页模板html源码,超级好看自适应清新网址导航网站发布页单页网页模板html源码!无论电脑还是手机,这是一个网页单页源码!! 模板无后台模板,无需数据库,上传服务器直接能用。
不用花钱,不拐弯抹角。
三菱FX3U PLC画圆程序详解:子程序循环插补技术绘制高精度圆及其他图形,三菱FX3U PLC画圆程序详解:以子程序循环调用实现高精度图形插补技术,三菱FX3U的plc画圆程序,程序将圆分为360等份进行插补,才用子程序循环调用的方式,根据这个原理可自行编写多种图形的程序 ,三菱FX3U; PLC画圆程序; 圆等份插补; 子程序循环调用; 图形程序编写,三菱FX3U PLC画圆子程序插补,多图形绘制可自定义调用循环编程法