所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式。这些按序排列的同类数据元素的集合称为数组。
归纳如下:
type var[] 或 type[] var;
代码示例1:
int a[];
int[] a1;
double b[];
Mydate []c;
注意:
Java语言中声明数组时不能指定其长度(数组中元素的个数).
代码示例2:
int a[5]; //非法
声明了一个一维数组,仅仅是给出了数组名称和元素的数据类型,要想真正使用数组还必须为它内存空间,即创建数组。在为数组分配内存空间时,必须指明数组的长度。创建数组要用到运算符new.
代码示例3:
arrayName = new type[size]; 如:
page = new int[3];
创建一维数组内存模式如下图:
定义并用运算符new为之分配空间后后,才可以引用数组中的每个元素;
数组元素的引用方式:arrayName[index]
备注:每个数组都有一个属性length指明它的长度
代码示例4:
//创建数组
int arr[]=new int[4];
//数组的length属性
System.out.println(arr.length);
动态初始化
数组定义与为数组元素分配空间并赋值的操作分开进行。
代码示例5:
int a[];
a = new int[3];
a[0] = 3;
a[1] = 9;
a[2] = 8;
MyDate dates[]= new MyDate[3];
dates[0] = new MyDate(22, 7, 1964);
dates[1] = new MyDate(1, 1, 2000);
dates[2] = new MyDate(22, 12, 1964);
静态初始化
在定义数组的同时就为数组元素分配空间并赋值。
代码示例6:
int a[] = { 3, 9, 8};
MyDate dates[] = {
new MyDate(22, 7, 1964),
new MyDate(1, 1, 2000),
new MyDate(22, 12, 1964)
};
简单数据类型数组的定义
在定义数组的时候,系统会给这个数组分配用于存放这个数组的内存空间
如图所示:
int arr[];
简单数据类型数组的创建
在创建简单数据类型的数组的时候,系统会分配合适的空间用来存放该种数据类型数据的内存空间,并且将这个数组的各个元素赋一个和数组类型匹配的初值
如图所示:
arr=new int[10];
3. 简单数据类型数组的初始化
对于简单数据类型的数组,当对其进行初始化时,会将对应的值赋给对应的各个数组元素
如图所示:
arr[0]=1;
arr[1]=2;
arr[2]=3;
......
arr[9]=10;
基本数据类型数组代码示例
public class Test {
public static void main(String args[]) {
//数组声明
int[] s;
//创建
s = new int[10];
for (int i = 0; i < 10; i++) {
//初始化
s[i] = 2 * i + 1;
//输出结果
System.out.print(s[i]+",");
}
}
}
运行结果:
1,3,5,7,9,11,13,15,17,19,
备注:分析示例中数组对象在内存中的变化
引用数据类型数组的定义
引用类型数组的定义和简单类型数据类型数组的定义并无二致
如图所示:
String arr[];
引用数据类型数组的创建
引用数据类型数组在创建的时候也是首先给数组元素分配内存空间,然后给这些数组元素一个默认的初始值null
arr=new String[10];
引用数据类型数组的初始化
在进行引用数据类型数组的初始化的时候,和简单数据类型数组的初始化有些不同,因为数组本身是引用类型,而现在数组元素也是引用类型,所以这个时候需要给数组元素所引用的对象也分配内存空间。
arr[0]=new String("one");
arr[1]=new String("two");
... ...
arr[9]=new String("ten");
数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化
引用数据类型数组代码示例
/**
* 自定义日期类
*
* @author change
*
*/
class MyDate {
// 月中的天
private int day;
// 年中的月
private int month;
// 年
private int year;
/**
* 构造函数
*
* @param d
* @param m
* @param y
*/
public MyDate(int d, int m, int y) {
day = d;
month = m;
year = y;
}
/**
* 打印对象信息
*/
public void display() {
System.out.println(year + "-" + month + "-" + day);
}
}
public class TestDemo {
public static void main(String args[]) {
//声明数组
MyDate[] m;
//创建数组
m = new MyDate[5];
for (int i = 0; i < 5; i++) {
//数组赋值
m[i] = new MyDate(i + 1, i + 1, 1990 + i);
//打印对象信息
m[i].display();
}
}
}
运行结果:
1990-1-1
1991-2-2
1992-3-3
1993-4-4
1994-5-5
备注:分析示例中数组对象在内存中的变化
案例1:解剖数组
public class ArrDemo{
public static void main(String[] args) {
//数组的创建
String arr[]=new String[5];
//数组的初始化
arr[0]="唐僧";
arr[1]="悟空";
arr[2]="白龙马";
arr[3]="八戒";
arr[4]="沙僧";
//数组的具体的某个元素值
System.out.println("数组的第四个元素:"+arr[3]);
//数组的长度属性
System.out.println("数组的长度是:"+arr.length);
//遍历数组的第一种方式
for(int i=0;i<arr.length;i++){
System.out.print(arr[i]+",");
}
//换行 考虑上边的输出去掉最后一个逗号的问题
System.out.println();
//遍历数组的方式
for(int i=0;i<arr.length;i++){
if(i<arr.length-1){
System.out.print(arr[i]+",");
}else{
System.out.print(arr[i]);
}
}
//换行
System.out.println();
//遍历数组的第二种方式
for(String ar:arr){
System.out.print(ar+" ");
}
//思考第一种方式与第二种方式的区别
}
}
运行结果:
数组的第四个元素:八戒
数组的长度是:5
唐僧,悟空,白龙马,八戒,沙僧,
唐僧,悟空,白龙马,八戒,沙僧
唐僧 悟空 白龙马 八戒 沙僧
利用一维数组来进行冒泡排序:
冒泡排序
案例2:冒泡排序
public static void main(String[] args) {
int[] a={1,3,5,75,1,6,9,8,5,2,2,1,4,2};
for(int i=0;i<a.length-1;i++){
for(int j=i;j<a.length-1;j++){
if(a[i]>a[j+1]){
int temp=a[i];
a[i]=a[j+1];
a[j+1]=temp;
}
}
}
for(int b:a){
System.out.println(b);
}
}
案例3: 从键盘读入学生成绩,找出最高分,并输出学生成绩等级。
等级说明:
成绩>=最高分-10 等级为’A’
成绩>=最高分-20 等级为’B’
成绩>=最高分-30 等级为’C’
其余 等级为’D’
提示:先读入学生人数,根据人数创建int数组,存放学生成绩。
/**
* 此操作都是在正确输入参数的情况测试的!
* @author change
*
*/
public class StudentDemo {
public static void main(String[] args) {
// 扫描对象
Scanner scanner = new Scanner(System.in);
//提示输入录入学生的人数
System.out.println("请输入录入学生的人数");
//扫描输入的学生的人数
String snum = scanner.nextLine();
//转换成数字
int num = Integer.parseInt(snum);
//创建数组
int arr[]=new int[num];
System.out.println("请输入"+num+"位学生的成绩");
//遍历数组
for(int i=0;i<num;i++){
//接受输入的学生成绩
String score = scanner.nextLine();
//初始化赋值
arr[i]=Integer.parseInt(score);
}
//数组排序
Arrays.sort(arr);
//获取最高的成绩5
int maxScore = arr[num-1];
System.out.println("学生等级划分结果");
//遍历数组
for(int i=0;i<num;i++){
if(arr[i]>maxScore-10){
System.out.println(arr[i]+"等级为A");
}else if(arr[i]>maxScore-20){
System.out.println(arr[i]+"等级为B");
}else if(arr[i]>maxScore-30){
System.out.println(arr[i]+"等级为C");
}else{
System.out.println(arr[i]+"等级为D");
}
}
}
}
测试运行:
请输入录入学生的人数
5
请输入5位学生的成绩
98
88
85
75
65
学生等级划分结果
65等级为D
75等级为C
85等级为B
88等级为B
98等级为A
Java语言中,多维数组被看作是数组的数组。例如二维数组被看作是一个特殊的一维数组,其每个元素又是一个一维数组。下面主要以二维数组为例进行说明。
二维数组的声明方式:
type var[][] 或 type[][] var;
其中type是定义数组包含元素的数据类型,它可以是Java支持的任何一种数据类型,
可以是基本数据类型,也可以是引用数据类型;
var是数组的名字,可以是任何一个合法的标识符。
二维数组举例:
int a[][] = {{1,2},{3,4,0,9},{5,6,7}};
图解说明如下:
注意事项
Java中二维数组的声明和初始化应按从高维到低维的顺序进行
int t [][] = new int [4][];
t[0] = new int[5];
t[1] = new int[5];
int t1[][] = new int [][4]; //非法
Java中二维数组不必须是规则矩阵形式
int[][] tt = new int[4][];
tt[0] = new int[2];
tt[1] = new int[4];
tt[2] = new int[6];
tt[3] = new int[8];
int tt[][] = new int[4][5];
二维数组初始
静态初始化
int intArray[][] = {{1,2},{2,3},{3,4,5}};
int intArray1[3][2] = {{1,2},{2,3},{4,5}}; //非法定义
动态初始化
int a[][] = new int[4][5];
int b[][] = new int[3][]
b[0] = new int[2];
b[1] = new int[3];
b[2] = new int[5];
二维数组示例:
public class ArrsDemo {
public static void main(String[] args) {
//创建二维数组
int[][] a = new int[3][];
//遍历数组
for (int i = 0; i < a.length; i++) {
// 创建一维数组的数组元素
a[i] = new int[i + 2];
//元素赋值
for (int j = 0; j < a[i].length; j++) {
a[i][j] = i + j;
}
}
// 打印
for (int i = 0; i < a.length; i++) {// 代表的是行
for (int j = 0; j < a[i].length; j++) {// 代表行中的元素:即就是几列。
System.out.print(a[i][j] + " ");
}
System.out.println();
}
}
}
运行结果:
0 1
1 2 3
2 3 4 5
案例4:使用二维数组打印一个 10 行杨辉三角
分析:
从第三行开始, 对于非第一个元素和最后一个元素的元素,其它元素的值的公式如下:
yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
代码实现:
/*杨辉三角实现*/
public class YangHuiDemo {
public static void main(String[] args) {
//定义二维数组
int yanghui[][] =new int[10][];
//遍历二维数组
for(int row=0;row<yanghui.length;row++){
//每行有n个元素
yanghui[row]=new int[row+1]; //第一行有一个元素,依次类推.
//位每行元素赋值
for(int col=0;col<yanghui[row].length;col++){
if(row==col||col==0){
yanghui[row][col]=1;
}
else{
yanghui[row][col]=yanghui[row-1][col-1]+yanghui[row-1][col];
}
//遍历元素 \t水平制表符
System.out.print(yanghui[row][col]+"\t");
}
System.out.println();
}
}
}
运行结果:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
1 9 36 84 126 126 84 36 9 1
扩展思考:怎么实现规则的输出?
数组脚标越界异常(ArrayIndexOutOfBoundsException)
示例代码:
public class ArrException {
public static void main(String[] args) {
int[] arr = new int[2];
System.out.println(arr[2]);
}
}
运行结果:
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at arr.ArrException.main(ArrException.java:7)
空指针异常(NullPointerException)
示例代码:
public class ArrException {
public static void main(String[] args) {
String[] arr = null;
System.out.println(arr[0]);
}
}
运行结果:
Exception in thread "main" java.lang.NullPointerException
at arr.ArrException.main(ArrException.java:7)
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
简单的说:一个类有多个组成部分,例如:成员变量,方法,构造方法等。反射就是加载类,并解剖出类的各个组成部分
Java反射机制主要提供了以下功能:
备注:程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言”。从这个观点看,Perl,Python,Ruby是动态语言,C++,Java,C#不是动态语言
Java反射所需要的类并不多,主要有java.lang.Class类和java.lang.reflect包中的Field、Constructor、Method、Array类。
注意:Class类是Java反射的起源,针对任何一个你想探勘的类,只有先为它产生一个Class类的对象,接下来才能通过Class对象获取其他想要的信息。
解剖类
Class对象提供了如下常用方法
Public Constructor getConstructor(Class<?>... parameterTypes)
Public Method getMethod(String name, Class<?>... parameterTypes)
Public Field getField(String name) public
public Constructor getDeclaredConstructor(Class... parameterTypes)
public Method getDeclaredMethod(String name,Class... parameterTypes)
public Field getDeclaredField(String name)
这些方法分别用于从类中解剖出构造函数、方法和成员变量(属性)。解剖出的成员分别使用Constructor、 Method 、 Field 对象表示。
**案例5:**Java反射案例
class Person {
private int age;
private String name;
public Person() {
}
public Person(int age, String name) {
this.age = age;
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
interface ActionInterface {
public void walk(int m);
}
class SuperMan extends Person implements ActionInterface {
private boolean blueBriefs;
public void fly() {
System.out.println("超人会飞耶~~");
}
public boolean isBlueBriefs() {
return blueBriefs;
}
public void setBlueBriefs(boolean blueBriefs) {
this.blueBriefs = blueBriefs;
}
@Override
public void walk(int m) {
System.out.println("超人会走耶~~走了" + m + "米就走不动了!");
}
}
示例1:通过Java反射机制得到类的包名和类名
public static void main(String[] args){
Person person = new Person();
System.out.println("包名:" + person.getClass().getPackage().getName());
System.out.println("完整类名:" + person.getClass().getName());
}
示例2:验证所有的类都是Class类的实例对象
public static void main(String[] args){
// 定义两个类型都未知的Class,设置初值为null,看看如何给它们赋值成Person类
Class<?> class1 = null;
Class<?> class2 = null;
// 写法1,可能抛出 ClassNotFoundException 异常,多用这个写法
try {
class1 = Class.forName("shuang.com.demo.Person");//包名要写正确,不然抛异常
System.out.println("写法1,包名:" + class1.getPackage().getName() + " , 完整类名:" + class1.getName());
} catch (ClassNotFoundException e) {
System.out.println("写法1找不到类");
}
// 写法2
class2 = Person.class;
System.out.println("写法2,包名:" + class2.getPackage().getName() + " , 完整类名:" + class2.getName());
}
示例3:通过Java反射机制,用 Class 创建类对象,这也就是反射存在的意义所在
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException{
Class<?> class1 = null;
class1 = Class.forName("shuang.com.demo.Person");
// 由于这里不能带参数,所以你要实例化的这个类Person,一定要有无参构造函数
Person person = (Person) class1.newInstance();
person.setName("xiaoming");
person.setAge(20);
System.out.println(person.getName() + " , " + person.getAge());
}
示例4:通过Java反射机制得到一个类的构造函数,并实现创建带参实例对象
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,IllegalArgumentException, InvocationTargetException{
Class<?> class1 = null;
Person person1 = null;
Person person2 = null;
class1 = Class.forName("shuang.com.demo.Person");
Constructor<?>[] constructors = class1.getConstructors();
person1 = (Person) constructors[0].newInstance();
person1.setName("xiaoming");
person1.setAge(20);
System.out.println(person1.getName() + " , " + person1.getAge());
person2 = (Person) constructors[1].newInstance(21, "xiaohong");
System.out.println(person2.getName() + " , " + person2.getAge());
}
示例5:通过Java反射机制操作成员变量, set 和 get
public static void main(String args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, SecurityException{
Class<?> class1 = Class.forName("shuang.com.demo.Person");
Object obj = class1.newInstance();
Field personNameField = class1.getDeclaredField("name");
personNameField.setAccessible(true); // 取消访问检查
personNameField.set(obj, "小虎");
System.out.println("修改属性之后得到属性变量的值:" + personNameField.get(obj));
}
示例6:通过Java反射机制得到类的一些属性:继承的接口、父类、函数信息、成员信息、类型等
public static void main(String[] args) throws ClassNotFoundException{
Class<?> class1 = Class.forName("shuang.com.demo.SuperMan");
// 取得父类名称
Class<?> superclass = class1.getSuperclass();
System.out.println("SuperMan类的父类名:" + superclass.getName());
Field[] fields = class1.getDeclaredFields();
for (int i = 0; i < fields.length; i++) {
System.out.println("类中的成员" + i + ": " + fields[i]);
}
// 取得类方法
Method[] methods = class1.getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
System.out.println("取得SuperMan类的方法" + i + ":");
System.out.println("函数名:" + methods[i].getName());
System.out.println("函数返回类型:" + methods[i].getReturnType());
System.out.println("函数访问修饰符:" + Modifier.toString(methods[i].getModifiers()));
System.out.println("函数代码写法: " + methods[i]);
}
// 取得类实现的接口,因为接口类也属于Class,所以得到接口中的方法也是一样的方法得到哈
Class<?> interfaces[] = class1.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
System.out.println("实现的接口类名: " + interfaces[i].getName());
}
}
示例7:通过Java反射机制调用类方法
public static void main(String[] args)throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException,InstantiationException, InvocationTargetException{
Class<?> class1 = Class.forName("shuang.com.demo.SuperMan");
System.out.println("调用无参方法fly():");
Method method = class1.getMethod("fly");
method.invoke(class1.newInstance());
System.out.println("调用有参方法walk(int m):");
method = class1.getMethod("walk", int.class);
method.invoke(class1.newInstance(), 100);
}
以上都是个人整理资料部分,有问题欢迎大家留言!如需转载,请注明出处!