Java基础编程学习笔记(上)(二)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: Java基础编程学习笔记(上)(二)

第三章:数组


一.数组的概述


1.数组的理解:数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名

 并通过编号的方式对这些数据进行统一管理。

 

2.数组的相关概念:


>数组名

>元素

>角标,下表,索引

>数组的长度:元素的个数

 

3.数组的特点:


1>数组是有序排列的

2>数组属于引用数据类型的变量。既可以是基本数据类型,也可以是引用数据类型。

3>创建数组对象会在内存中开辟一整块连续的空间

4>数组长度一旦确定,就不能修改。

 

4.数组的分类:


    ①按照维数:一维数组,二维数组,三维数组....

    ②按照数组元素的类型:基本数据类型元素的数组,引用数据类型元素的数组

 


二.一维数组的使用


1.一维数组的使用:

     ①一维数组的初始化

     ②如何调用数组的指定位置元素

     ③如何获取数组长度

     ④如何遍历数组

     ⑤数组元素的默认初始化  

     ⑥数组的内存解析


代码实例实现:①~~④


public class ArrayTest {
    public static void main(String[] args) {
        int[] ids;//声明
        //1.1静态初始化:数组的初始化和数组元素的赋值操作同时运行
        ids = new int[]{1001,1002,1003,1004};
        //1.2动态初始化:数组的初始化和数组元素的赋值操作分开运行
        String[] names = new String[5];
        //错误的写法:
        //int[] arr1 = new int[];
        //int[5] arr2 = new int[];
        //int[] arr3 = new int[3]{1,2,3};
        //总结:数组一旦初始化完成,其长度就确定了。
        //2.如何调用数组的指定位置:通过角标方式使用。
        //数字组的角标从0开始,到数组的长度-1结束
        names[0] = "王明";
        names[1] = "王鹤";
        names[2] = "王明明";
        names[3] = "王钧";
        names[4] = "明天";
        //3.如何获取数组的长度。
        //属性:length
        System.out.println(names.length);//5
        System.out.println(ids.length);
        //4.如何遍历数组
        //System.out.println(names[0]);
        //System.out.println(names[1]);
        //System.out.println(names[2]);
        //System.out.println(names[3]);
        //System.out.println(names[4]);
        for(int i = 0; i < names.length; i++) {
            System.out.println(names[i]);
        }
    }
}


⑤:数组元素的默认初始化:

       >数组元素是整形:0

       >数组元素是浮点型:0.0

       >数组元素是char型:0

       >数组元素是boolean型:false

       >数组元素是引用数据类型时:null


⑥数组的内存解析:



42552c95da046ccc857eb2d2a550b0ef_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAd3lrMTEyMjMz,size_20,color_FFFFFF,t_70,g_se,x_16.png


11807bf7bd7d3e87782e4b3431e9ed7c_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAd3lrMTEyMjMz,size_20,color_FFFFFF,t_70,g_se,x_16.png



三.多维数组的使用


①二维数组的初始化

②如何调用数组的指定位置元素

③如何获取数组长度

④如何遍历数组

⑤数组元素的默认初始化  

⑥数组的内存解析


①二维数组的初始化


46269126d6b69c86aaec3fb47c26b34b_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAd3lrMTEyMjMz,size_20,color_FFFFFF,t_70,g_se,x_16.png


460346ee5a73f85731854ef5ac996a4c_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAd3lrMTEyMjMz,size_20,color_FFFFFF,t_70,g_se,x_16.png


代码实例:②~~④


public class ArrayTest2 {
    public static void main(String[] args) {
    //1.二维数组的声明和初始化
        int[] arr = new int[] {1,2,3};//一维数组
        //静态初始化
        int[][] arr1 = new int[][] {{1,2,3},{4,5},{6,7,8}};
        //动态初始化
        String[][] arr2 = new String[3][2];
        String[][] arr3 = new String[3][];
        //也是正确的写法
        int[] arr4[] = new int [][] {{1,2,3},{4,5,9,10},{6,7,8}};
        //2.如何调用二维数组的指定位置元素
        System.out.println(arr1[0][1]);//2
        System.out.println(arr2[1][1]);//null
        arr3[1] = new String[4];
        System.out.println(arr3[1][0]);
        //3.获取数组的长度
        System.out.println(arr4.length);//3
        System.out.println(arr4[0].length);//3
        System.out.println(arr4[1].length);//4
        //4.如何遍历二维数组
        for(int i = 0; i < arr4.length; i++) {
            for(int j = 0;j < arr4[i].length; j++) {
                System.out.print(arr4[i][j] + "  ");
            }
            System.out.println();
        }
    }
}


 ⑤数组元素的默认初始化

 针对于初始化方式一:比如int [][]arr = new int[4][2];

 外层元素初始化值为:地址值

 内层元素初始化值为:与一维数组初始化情况相同

 针对于初始化方式二:比如int [][]arr = new int[4][];

 外层元素初始化值为:null

 内层元素初始化值为:不能调用,否则报错


⑥数组的内存解析


5a9a57efb2057e40f54f1fedd1e6d165_watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAd3lrMTEyMjMz,size_20,color_FFFFFF,t_70,g_se,x_16.png



四.数组中涉及的常见算法


1. 数组元素的赋值(杨辉三角、回形数等)


2. 求数值型数组中元素的最大值、最小值、平均数、总和等


3. 数组的复制、反转、查找(线性查找、二分法查找)


4. 数组元素的排序算法


1. 数组元素的赋值(杨辉三角、回形数等)    


   以杨辉三角为例


/*
 * 使用二维数组打印一个 10 行杨辉三角。
    【提示】
    1. 第一行有 1 个元素, 第 n 行有 n 个元素
    2. 每一行的第一个元素和最后一个元素都是 1
    3. 从第三行开始, 对于非第一个元素和最后一个元素的元素。即:
    yanghui[i][j] = yanghui[i-1][j-1] + yanghui[i-1][j];
 */
public class YangHuiTest {
    public static void main(String[] args) {
        //1.声明并初始化二维数组
        int[][] yangHui = new int[10][];
        //2.给数组的元素赋值
        for(int i = 0;i < yangHui.length;i++) {
            yangHui[i] = new int[i + 1];
            //2.1给首末元素赋值
            yangHui[i][0] = yangHui[i][i] = 1;
            //2.2给每行的非首末元素赋值
            //if(i > 1) {
                for(int j = 1;j < yangHui[i].length - 1;j++) {
                    yangHui[i][j] = yangHui[i-1][j-1] + yangHui[i-1][j];
                }
            //}
        }
        //3.遍历二维数组
        for(int i = 0;i < yangHui.length;i++) {
            for(int j = 0;j < yangHui[i].length;j++) {
                System.out.print(yangHui[i][j] + "  ");
            }
            System.out.println();
        }
    }
}


2. 求数值型数组中元素的最大值、最小值、平均数、总和等


/*
 * 算法的考察:求数值型数组中元素的最大值、最小值、平均数、总和等
 * 
 * 定义一个int型的一维数组,包含10个元素,分别赋一些随机整数,
    然后求出所有元素的最大值,最小值,和值,平均值,并输出出来。
    要求:所有随机数都是两位数。
    提示;
    (int)(Math.random() * 90 + 10)
 */
public class ArrayTest1 {
    public static void main(String[] args) {
        int[] arr = new int [10];
        for(int i = 0;i < arr.length;i++) {
            arr[i] = (int)(Math.random() * 90 + 10);
        }
        //遍历
        for(int i = 0;i < arr.length;i++) {
            System.out.print(arr[i] + "\t");
        }
        System.out.println();
        //求数组元素的最大值
        int maxValue = arr[0];
        for(int i = 0;i < arr.length;i++) {
            if(maxValue < arr[i]) {
                maxValue = arr[i];
            }
        }    
        System.out.println("最大值为" + maxValue);
        //求数组元素的最小值
        int minValue = arr[0];
        for(int i = 0;i < arr.length;i++) {
            if(minValue > arr[i]) {
                minValue = arr[i];
            }
        }    
        System.out.println("最小值为" + minValue);
        //求数组元素的总和
        int sum = 0;
        for(int i = 0;i < arr.length;i++) {
            sum += arr[i];
        }
        System.out.println("总和为" + sum);
        //求数组元素的平均数
        int avgValue = sum/arr.length;
        System.out.println("平均数为" + avgValue);
    }
}


3. 数组的复制、反转、查找(线性查找、二分法查找)


/*
 * 算法的考查:数组的复制、反转、查找(线性查找、二分法查找)
 * 
 * 
 */
public class ArrayTest2 {
    public static void main(String[] args) {
        String[] arr = new String[] {"JJ","DD","MM","BB","GG","AA"};
        //数组的复制
        String[] arr1 = new String[arr.length];
        for(int i = 0;i < arr1.length;i++) {
            arr1[i] = arr[i];
        }
            //数组的反转
            //方法一:
//            for(int i = 0;i < arr.length / 2;i++) {
//                String temp = arr[i];
//                arr[i] = arr[arr.length-i-1];
//                arr[arr.length-i-1] = temp;
//            }
            //方法二:
//            for(int i = 0,j = arr.length - 1;i < j;i++,j--) {
//                String temp = arr[i];
//                arr[i] = arr[j];
//                arr[j] = temp;
//            }
            //遍历
            for(int i = 0;i <arr.length;i++) {
                System.out.print(arr[i] + "\t");
            }
            System.out.println();
            //查找(或搜索)
            //线性查找
            String dest = "BB";
            boolean isFlag = true;
            for(int i = 0;i < arr.length;i++) {
                if(dest.equals(arr[i])) {
                    System.out.println("找到了指定的元素位置为" + i);
                    isFlag = false;
                    break;
                }
            }    
            if(isFlag) {
                System.out.println("很遗憾,没有找到哦~~");
                }
            //二分查找:
            //前提:索要查找的数组必须有序
            int[] arr2 = new int[] {-98,-34,2,34,54,66,79,105,210,333};
            int dest1 = -34;
            int head = 0;//初始的首索引
            int end = arr2.length - 1;//初始的末索引
            while(head <= end) {
                int middle = (head + end)/2;
                if(dest1 == arr2[middle]) {
                    System.out.println("找到了指定元素,位置为" + middle);
                    isFlag = false;
                    break;
                }else if(arr2[middle] > dest1) {
                    end = middle-1;
                }else {//arr2[middle] < dest1
                    head = middle +1;
                }
                if(isFlag) {
                    System.out.println("很遗憾,没有找到啦~~");
                }
            }
        }
    }


4. 数组元素的排序算法


选择排序:直接选择排序,堆排序


交换排序:冒泡排序,快速排序


插入排序:直接插入排序,折半插入排序,Shell排序


归并排序


桶式排序


基数排序


冒泡排序的演示:


/*
 *数组的冒泡排序的实现
 * 
 * 
 */
public class BubbleSortTest {
    public static void main(String[] args) {
        int[] arr = new int[] {43,32,76,-98,0,64,33,-21,32,99};
        //冒泡排序
        for(int i = 0;i < arr.length-1;i++) {
            for(int j = 0;j < arr.length -1 -i;j++) {
                if(arr[j] > arr[j+1]) {
                    int temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j + 1] = temp;
                }
            }
        }
        for(int i = 0;i <arr.length;i++) {
            System.out.print(arr[i] + "\t");
        }
    }
}


五.Arrays工具类的使用


import java.util.Arrays;
/*
 * java.util.Arrays:操作数组的工具类,里面定义了很多操作数组的方法
 *
 */
public class ArraysTest {
    public static void main(String[] args) {
        //1.boolean equals(int[] a,int[] b)  判断两个数组是否相等。
        int[] arr1 = new int[] {1,2,3,4};
        int[] arr2 = new int[] {1,3,2,4};
        boolean isEquals = Arrays.equals(arr1,arr2);
        System.out.println(isEquals);
        //2.String toString(int[] a)  输出数组信息。
        System.out.println(Arrays.toString(arr1));
        //3.void fill(int[] a,int val)  将指定值填充到数组之中。
        Arrays.fill(arr1, 10);
        System.out.println(Arrays.toString(arr1));
        //4.void sort(int[] a)
        Arrays.sort(arr2);
        System.out.println(Arrays.toString(arr2));
        //5.int binarySearch(int[] a,int key) 
        int[] arr3 = new int[] {-98,-34,2,34,54,66,79,105,210,333};
        int index = Arrays.binarySearch(arr3,210);
        if(index >= 0) {
            System.out.println(index);
        }else {
            System.out.println("没找到");
        }
    }
}


六.数组使用中的常见异常


/*
 * 数组的常见异常
 * 1.数组角标越界的异常:ArrayIndexOutOfBoundsExcetion
 * 
 * 
 * 2.空指针异常:NullPointerException
 * 
 */
public class ArrayExceptionTest {
    public static void main(String[] args) {
        int[] arr = new int[] {1,2,3,4,5};
//        for(int i = 0;i < arr.length;i++) {
//            System.out.println(arr[i]);
//        }
//        System.out.println(arr[-2]);
//        2.空指针异常:NullPointerException
        //情况一:
//        int[] arr1 = new int[] {1,2,3};
//        arr1 = null;
//        System.out.println(arr1[0]);
//        
        //情况二:
//        int[][] arr2 = new int [4][];
//        System.out.println(arr2[0][0]);
        //情况三:
        String[] arr3 = new String[] {"AA","BB","CC"};
        arr3[0] = null;
        System.out.println(arr3[0].toString());
    }
}


目录
相关文章
|
2月前
|
Java 开发者
Java多线程编程中的常见误区与最佳实践####
本文深入剖析了Java多线程编程中开发者常遇到的几个典型误区,如对`start()`与`run()`方法的混淆使用、忽视线程安全问题、错误处理未同步的共享变量等,并针对这些问题提出了具体的解决方案和最佳实践。通过实例代码对比,直观展示了正确与错误的实现方式,旨在帮助读者构建更加健壮、高效的多线程应用程序。 ####
|
1月前
|
Java 程序员
Java编程中的异常处理:从基础到高级
在Java的世界中,异常处理是代码健壮性的守护神。本文将带你从异常的基本概念出发,逐步深入到高级用法,探索如何优雅地处理程序中的错误和异常情况。通过实际案例,我们将一起学习如何编写更可靠、更易于维护的Java代码。准备好了吗?让我们一起踏上这段旅程,解锁Java异常处理的秘密!
|
28天前
|
存储 缓存 Java
Java 并发编程——volatile 关键字解析
本文介绍了Java线程中的`volatile`关键字及其与`synchronized`锁的区别。`volatile`保证了变量的可见性和一定的有序性,但不能保证原子性。它通过内存屏障实现,避免指令重排序,确保线程间数据一致。相比`synchronized`,`volatile`性能更优,适用于简单状态标记和某些特定场景,如单例模式中的双重检查锁定。文中还解释了Java内存模型的基本概念,包括主内存、工作内存及并发编程中的原子性、可见性和有序性。
Java 并发编程——volatile 关键字解析
|
1月前
|
算法 Java 调度
java并发编程中Monitor里的waitSet和EntryList都是做什么的
在Java并发编程中,Monitor内部包含两个重要队列:等待集(Wait Set)和入口列表(Entry List)。Wait Set用于线程的条件等待和协作,线程调用`wait()`后进入此集合,通过`notify()`或`notifyAll()`唤醒。Entry List则管理锁的竞争,未能获取锁的线程在此排队,等待锁释放后重新竞争。理解两者区别有助于设计高效的多线程程序。 - **Wait Set**:线程调用`wait()`后进入,等待条件满足被唤醒,需重新竞争锁。 - **Entry List**:多个线程竞争锁时,未获锁的线程在此排队,等待锁释放后获取锁继续执行。
66 12
|
28天前
|
存储 安全 Java
Java多线程编程秘籍:各种方案一网打尽,不要错过!
Java 中实现多线程的方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口和使用线程池。每种方式各有优缺点,适用于不同的场景。继承 Thread 类最简单,实现 Runnable 接口更灵活,Callable 接口支持返回结果,线程池则便于管理和复用线程。实际应用中可根据需求选择合适的方式。此外,还介绍了多线程相关的常见面试问题及答案,涵盖线程概念、线程安全、线程池等知识点。
156 2
|
2月前
|
设计模式 Java 开发者
Java多线程编程的陷阱与解决方案####
本文深入探讨了Java多线程编程中常见的问题及其解决策略。通过分析竞态条件、死锁、活锁等典型场景,并结合代码示例和实用技巧,帮助开发者有效避免这些陷阱,提升并发程序的稳定性和性能。 ####
|
2月前
|
缓存 Java 开发者
Java多线程编程的陷阱与最佳实践####
本文深入探讨了Java多线程编程中常见的陷阱,如竞态条件、死锁和内存一致性错误,并提供了实用的避免策略。通过分析典型错误案例,本文旨在帮助开发者更好地理解和掌握多线程环境下的编程技巧,从而提升并发程序的稳定性和性能。 ####
|
1月前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
1月前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
63 3
|
1月前
|
开发框架 安全 Java
Java 反射机制:动态编程的强大利器
Java反射机制允许程序在运行时检查类、接口、字段和方法的信息,并能操作对象。它提供了一种动态编程的方式,使得代码更加灵活,能够适应未知的或变化的需求,是开发框架和库的重要工具。
67 4