1.什么是NPE,什么情况会发生NPE
NPE就是空指针异常,当出现使用null进入数组或者对象时会出现NPE。
如何防止NPE?当你使用指针进行操作的时候,如果不确定指针是否为null,应该对指针做非空判断,判断指针为null时,使用new关键字开辟内存空间
if(指针 == null){指针 = new ···}
2.new关键字的作用
1.用于在堆区造数组
new 数据类型[长度]
数组的构造器是系统默认就有的,任何一种数据类型都可以使用数组构造器来构造数组
例如:new int[10]
2.用于在堆区造对象
new 构造方法()
对象的构造器是类里面提供的
例如:new Student();
这个new后面的Student()是一个无参构造方法,是编译器给你自动生成的;在字节码文件中可以看到它
对象的构造方法可以自定义
1.构造方法使用public修饰
2.构造方法没有返回值类型(连void都没有)
3.构造方法的名字必须与当前类名相同
4.构造方法的内部有一个特殊的this指针,指向当前对象
5.如果一个类没有手动指定构造方法,则编译器会提供一个默认的无参构造方法。如果手动指定了构造方法,则编译器则不再提供默认的无参构造方法
3.数组和对象的区别
1、数组和对象的创建方式不同;
2、对象没有长度;
3、调用方式不同;
4、对象值唯一,数组值可以重复;
4.基本数据类型对应的应用数据类型
byte byte
short short
int Integer
long long
float float
double double
char character
boolean boolean
5.正序遍历数组,倒序遍历数组
public class text {
static Integer[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
System.out.println("正向遍历数组");
zheng();
System.out.println("\n反向遍历数组");
fan();
}
public static void zheng(){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
System.out.print(",");
}
}
public static void fan(){
for (int i = arr.length -1; i >= 0; i--) {
System.out.print(arr[i]);
System.out.print(",");
}
}
}
6.数组求和
public class text {
static Integer[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
sum();
}
public static void sum(){
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == null){
break;
}
sum += arr[i];
}
System.out.println("累加和为:" + sum);
}
7.数组求最大值和最小值
public class text {
static Integer[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
max();
min();
}
public static void max(){
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] == null){
break;
}
if (arr[i] >max){
max = arr[i];
}
}
System.out.println("最大数为" + max);
}
public static void min(){
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] == null){
break;
}
if (arr[i] <min){
min = arr[i];
}
}
System.out.println("最小数为" + min);
}
}
8.数组求平均数
public class text {
static Integer[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
avg();
}
public static void avg(){
int sum = 0;
for (int i = 0; i < arr.length; i++) {
if (arr[i] == null){
break;
}
sum += arr[i];
}
System.out.println("平均数为:" + sum / arr.length);
}
}
9.数组扩容的策略
(1)创建新数组
(2)把原数组的元素转移到新数组中
(3)把新数组的地址赋给原数组的指针
public class text {
static Integer[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
kuorong();
}
public static void kuorong(){
System.out.println("\n原数组长度为:" + arr.length);
Integer[] xin = new Integer[arr.length * 2];
for (int i = 0;i<arr.length;i++){
xin[i] = arr[i];
}
arr = xin;
System.out.println("扩容后的长度为:" + arr.length);
}
}
10.数组中插入元素
1.在数组中指定位置插入元素,要把指定位置之后的元素全部向后移一位(包括指定位置)
2.这样的话数组原来的长度就不够了,因此我们要先对数组进行扩容
3.创建一个新的数组,创建新数组,把原数组的元素转移到新数组中,把新数组的地址赋给原数组的指针
4.找到数组中第一个空的位置
5.从第一个空的位置开始向后移
6.对数组进行遍历打印结果
public class text {
static Integer[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
kuorong();
System.out.println("原数组遍历结果:");
zheng();
System.out.println("\n插入元素10后的遍历结果:");
charu(4,10);
}
public static void zheng(){
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]);
System.out.print(",");
}
}
public static void kuorong(){
Integer[] xin = new Integer[arr.length * 2];
for (int i = 0;i<arr.length;i++){
xin[i] = arr[i];
}
arr = xin;
}
public static void charu(int xuhao,int zhi){
// 找到数组中第一个空的位置
int kong = 0;
for (int i = 0; i < arr.length; i++) {
if(arr[i] == null){
kong = i;
break;
}
}
// 从第一个为空的位置开始后移
for (int i = kong; i > 4; i--) {
arr[i]= arr[i - 1];
}
arr[xuhao] = zhi;
zheng();
}
}
11.数组中删除元素
1.删除指定的元素之后要把删除元素后面的所有元素数据向前移一位
2.做了一个for循环,把从指定的索引开始往后的数据的值赋给前一位
3.把最后一位的数据的值变成0(因为创建的数组是int类型)
4.对数组进行遍历打印结果
public class text {
static int[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
shan(4);
}
public static void shan(int xuhao){
for (int i = xuhao; i < arr.length-1; i++) {
arr[i] = arr[i+1];
}
arr[arr.length]=0;
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+",");
}
}
}
出现了数组下标越界的异常
public class text {
static int[] arr = {1,5,6,3,4,8,9};
public static void main(String[] args) {
shan(4);
}
public static void shan(int xuhao){
for (int i = xuhao; i < arr.length-1; i++) {
arr[i] = arr[i+1];
}
arr[arr.length-1]=0;
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i]+",");
}
}
}
12.反转数组
1.把最后一个元素的数据赋值给第一个元素,把倒数第二个元素的数据赋值给第二个元素,依次类推
2.创建一个新的数组接受新的数据
3.把新的数组地址给旧的数组的指针
4.遍历旧的数组把结果打印出来
public class text2 {
/* 反转数组*/
static void reverse(int arr[], int n)
{
int[] newarr = new int[n];
int j = n;
for (int i = 0; i < n; i++) {
newarr[j - 1] = arr[i];
j = j - 1;
}
arr = newarr;
/*输入反转数组*/
System.out.println("反转后数组是: \n");
for (int i = 0; i < n; i++) {
System.out.println(arr[i]);
}
}
public static void main(String[] args)
{
int [] arr = {10, 20, 30, 40, 50};
reverse(arr, arr.length);
}
}
13.使用冒泡排序算法排序数组
public class text03 {
public static void main(String args[]) {
int[] arr= {9,8,3,5,2};
System.out.print("原数组为:");
//冒泡排序前先循环打印原数组元素
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
System.out.println();
//进行冒泡排序
//外层循环定义需要比较的轮数(两数比较,需要比较n-1轮)
for(int i=1;i<arr.length;i++) {
System.out.print("第"+i+"轮:");
//内层循环定义第i轮需要比较的两元素
for(int j=0;j<arr.length-1;j++) {
//如果前一个元素大于后一个元素则进行交换
if(arr[j]>arr[j+1]) {
int temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
for(int k=0;k<arr.length;k++) {
System.out.print(arr[k]+" ");;
}
System.out.println();
}
//完成冒泡排序后循环打印数组元素
System.out.print("冒泡排序后数组为:");
for(int i=0;i<arr.length;i++) {
System.out.print(arr[i]+" ");
}
}
}
14.官方Arrays工具类
* Arrays:针对数组进行操作的工具类。比如说排序和查找。没有构造,方法全部是静态。
* 1:public static String toString(int[] a) 把数组转成字符串(不只是int[]类型,只要是数组类型就可以用)
* 2:public static void sort(int[] a) 对数组进行排序
* 3:public static int binarySearch(int[] a,int key) 二分查找
补充:
* 4:public static <T> List<T> asList(T... a):把数组转成集合
*
* 注意事项:
* 虽然可以把数组转成集合,但是集合的长度不能改变。
// 定义一个数组
List<String> list = Arrays.asList("hello", "world", "java");
list.set(1, "javaee");
for (String s : list) {
System.out.println(s);
}
15.二维数组
有以下几种表示二维数组元素的方法:
int brr [3] [4] ={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int crr [3] [4] = {1,2,3,4,5,6,7,8,9,10,11,12};
Int err [3][4] = {1,2,3,4,5};
当表示某一特定元素时,例如2行1列的元素1时,可用以下两种方式来表示
frr [2][1]=1;
int hrr[3][4]={0,0,0,0,0,0,0,0,0,1};
int grr[][4]={1,2,3,4,5,6,7,8,9,10};//二维数组中行可以省略,至少写出列,编译器可以推断出来行
//输出crr的内容
for(int i=0;i<3;i++)//遍历行
{
for(int j=0;j<4;j++)//遍历列
{
printf(“%-3d”,crr[i][j]);//-3表示左对齐
}
printf(“\n”);
}
16.类和对象
类是对象的模板,类是方法区的字节码文件;
对象是new关键字在堆区开辟的内存空间。
17.成员变量
成员变量在一个类中并且在函数外面,没有使用static修饰成静态变量,这样的变量称为成员变量。
18.构造方法
就是类用来构造对象时调用的方法,分为无参构造和有参构造。
无参构造方法存在的意义?
new Student ()在堆区里面构造一个对象,对象中的元素存储的数据还未知的时候,可以使用无参构造方法,后续的代码在获得数据以后,可以通过指针操作对象,读写数据
带参构造方法存在的意义?
在堆区里面构造一个对象的时候,已经明确知道对象存储中是什么内容,就可以使用带参构造,更加便捷。
例如:new Student();
这个new后面的Student()是一个无参构造方法,是编译器给你自动生成的,在字节码文件中可以看到他。
对象的构造方法可以自定义
1.构造方法使用public修饰
2.构造方法没有返回值类型(连void都没有)
3.构造方法的名字必须与当前类名相同
4.构造方法的内部有一个特殊的this指针,指向当前对象
5.如果一个类没有手动指定构造方法,则编译器会提供一个默认的无参构造方法。如果手动指定了构造方法,则编译器则不再提供默认的无参构造方法
19.成员方法
访问修饰符 返回参数类型 方法名(形参列表){
语句;
return 返回值;
}
20.this关键字
作用:1、当成员变量和局部变量重名的时候,使用this关键字区分;
2、哪个对象调用了this所在的函数,this就指代哪个对象
21.什么是零值
零值是null。