Java学习之数组及Comparable接口

目录

数组

定义

四个基本特点

创建数组

声明方式

注意事项

示例-基本类型

示例-引用类型

初始化

静态初始化

示例

动态初始化

示例

默认初始化

示例

常见操作

遍历

示例 for循环

示例 for-each循环

拷贝

示例

java.util.Arrays类

示例一 打印数组元素

示例二 对数组元素进行排序

示例三 实现二分法的查找

示例四 使用Arrays类对数组进行填充

多维数组

示例 二维数组的声明

示例 静态初始化

示例 动态初始化

存储表格数据

示例 使用javabean和一维数组保存表格信息

Comparable接口

示例

常见算法

冒泡排序算法

示例 冒泡算法

示例 优化算法

二分法查找


数组

数组也是对象

大纲知识点
数组的概念数组的定义
数组的概念数组的四个特点
数组的常见操作普通遍历
数组的常见操作for-each遍历
数组的常见操作数组的拷贝
数组的常见操作java.util.Array类用法
多维数组内存结构
多维数组存储表格
多维数组Javabean和数组存储表格
常见算法冒泡排序基础算法
常见算法冒泡排序优化算法
常见算法二分法查找(折半查找)

定义

数组是相同类型数据的有序集合。其中,每一个数据称作一个元素,每一个元素可以通过一个索引(下标--index)来访问。(下标从0开始计)

四个基本特点

  • 长度是确定的,数组一旦被创建,它的大小是不可改变的

  • 其元素类型必须是相同类型,不能出现混合类型

  • 数组类型可以是任何数据类型,包括基本类型和引用类型

  • 数组变量属于引用类型,数组也是对象,数组中的元素相当于对象的属性

创建数组

声明方式

type[] arr_name; // 方式一

typr arr_name[]; // 方式二

注意事项
  • 声明的时候并没有实例化任何对象,只有在实例化数组对象时,JVM才分配空间,这时才与长度有关

  • 构造一个数组,必须指定长度

  • 声明一个数组时数组并没有真正的被创建

示例-基本类型
package ArraryLearn;
​
public class ArrayCreate {
    public static void main(String[] args) {
        int[] s;            // 声明数组
        s = new int[10];    // 给数组分配空间
        System.out.println(s[0]);   // 0
        System.out.println(s[1]);   // 0
        s[2] = 20;
        System.out.println(s[2]);   // 20
​
        for(int i = 0;i < 10;i++){
           s[i] = 2 * i + 1;
           System.out.println(s[i]);  // 1 3 5 7 9 11 13 15 17 19
        }
    }
}
示例-引用类型
package ArraryLearn;
​
public class ArraryCreate01 {
    public static void main(String[] args) {
        Man[] mans;  // 声明数组
        mans = new Man[10];
​
        Man m1 = new Man(18,"张三");
        Man m2 = new Man(22,"李四");
​
        mans[0] = m1;
        mans[1] = m2;
​
        System.out.println(mans[0].getAge());
        System.out.println(mans[1].getName());
    }
}
​
class Man{
   private int age;
   private String name;
   public Man(int age,String name){
       this.age = age;
       this.name = name;
   }
​
    public int getAge() {
        return age;
    }
​
    public String getName() {
        return name;
    }
​
    public void setAge(int age) {
        this.age = age;
    }
​
    public void setName(String name) {
        this.name = name;
    }
}

初始化

静态初始化

除了用new关键字产生数组意外,还可以直接在定义数组时就为数组元素分配空间并赋值

示例
package ArraryLearn;
​
public class StaticCreateArray {
    public static void main(String[] args) {
        // 基本数据类型
        int[] a = {1,2,3,4,5,6};
        System.out.println(a[1]);  // 2
        System.out.println(a[0]);  // 1
​
        // 引用类型
        Man[] mans = {new Man(18,"张三"),new Man(22,"李四")};
        System.out.println(mans[1].getName());  // 李四
​
    }
}
动态初始化
示例

见示例-及基本类型、示例-引用类型

默认初始化
  • 数组是对象,他的元素相当于对象的属性

  • 每个元素也按照属性的方法被默认初始化

示例
int i[] = new int[2];         // 默认值:0,0
boolean[] b = new boolean[2]; // 默认值:false,true
String[] s = new String[2];   // 默认值:null,null

常见操作

遍历

"通过循环遍历数组的所有元素"

数组元素下标的合法区间:[0,length-1]。可通过下标遍历数组中的元素,遍历时可读取/修改元素的值

示例 for循环
package ArraryLearn;
​
public class BianliArray {
    public static void main(String[] args) {
        int[] i = new int[5];
        for(int j = 0;j < i.length;j++){
           i[j] = 20 * j;
           System.out.println(i[j]);  // 0,20,40,60,80
        }
    }
}
示例 for-each循环

专门用于读取数组或集合中的元素,即进行数组遍历

package ArraryLearn;
​
public class BianliArray {
    public static void main(String[] args) {
​
        String[] s = {"张三","李四","王五","陈六"};
        for(String temp : s){   // temp可随意取名,临时变量
           System.out.println(temp);  // 张三,李四,王五,陈六
        }
    }
}
  • for-each增强for循环在遍历数组过程中不能修改数组中某元素的值

  • for-each仅适用于简单遍历,不涉及有关索引(下标)的操作

拷贝
  • 将某个数组的内容拷贝到另一个数组中

  • 实际上“容器的扩容”就是数组的拷贝

  • System.arraycopy(object src,int srcpos,object dest,int destpos,int length)

该方法可以将src数组里的元素值赋给dest数组的元素,其中srcpos指定从src数组第几个元素开始赋值,length参数指定将src数组的多少个元素赋给dest数组的元素

示例
package ArraryLearn;
​
public class CopyArray {
    public static void main(String[] args) {
        int[] a = {1,2,3,4,5,6,7,8,9,10};
        int[] b = new int[10];
        System.arraycopy(a,2,b,3,6);
​
        for(int i = 0;i < b.length;i++){
           System.out.print(b[i] + "\t");   // 0    0    0    3    4    5    6    7    8    0
        }
​
    }
}

java.util.Arrays类

Arrays类包含了:排序、查找、填充、打印内容等常见的数组操作

示例一 打印数组元素
package ArraryLearn;
import java.util.Arrays;
​
public class Test {
    public static void main(String[] args) {
        int[] a = {1,2,3,4,5,6,7,8,9,10};
        System.out.println(a);          // [I@4554617c
        System.out.println(Arrays.toString(a)); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    }
}

注:此处的Arrays.toString()方法是Arrays类的静态方法,不是前面Object的toString()方法

示例二 对数组元素进行排序
package ArraryLearn;
import java.util.Arrays;
​
public class Test {
    public static void main(String[] args) {
        
        int[] b = {5,9,3,7,6,3,2,4,10,56};
        Arrays.sort(b);   // 排序
        System.out.println(Arrays.toString(b)); // [2, 3, 3, 4, 5, 6, 7, 9, 10, 56]
    }
}
示例三 实现二分法的查找
package ArraryLearn;
import java.util.Arrays;
​
public class Test {
    public static void main(String[] args) {
​
        int[] c = {56,33,12,17,16,52,25,423,2659};
        Arrays.sort(c);  // 排序 二分法查找必须先对数组进行排序
        // 返回排序后新的索引位置,未找到返回负数
        System.out.println(Arrays.toString(c)); // [12, 16, 17, 25, 33, 52, 56, 423, 2659]
        System.out.println("该元素的索引:" + Arrays.binarySearch(c,17)); // 该元素的索引:2
    }
}
示例四 使用Arrays类对数组进行填充
package ArraryLearn;
import java.util.Arrays;
​
public class Test {
    public static void main(String[] args) {
        
        int[] d = {1,2,3,4,5,6,78,12,66,17,65};
        System.out.println(Arrays.toString(d)); // [1, 2, 3, 4, 5, 6, 78, 12, 66, 17, 65]
        Arrays.fill(d,3,6,100); // 将数组d中3-6索引的元素替换为100
        System.out.println(Arrays.toString(d)); // [1, 2, 3, 100, 100, 100, 78, 12, 66, 17, 65]
    }
}

多维数组

可以看成以数组为元素的数组。可有二维、三维、甚至更多。

示例 二维数组的声明
package ArraryLearn;
​
public class TestMultipleArray {
    public static void main(String[] args) {
        int [][] a = new int[3][];
        // int [][] a1 = new int[][3]; 非法形式,应从低维到高维
        a[0] = new int[2];   // a指向的数组的第一位又指向一个数组的第一位和第二位
        a[1] = new int[3];   // a指向的数组的第一位又指向一个数组的第一、二、三位
        a[2] = new int[5];   // a指向的数组的第一位又指向一个数组的第一、二、三、四、五位
​
        a[0][1] = 20;
        System.out.println(a[0][1]);  // 20
​
        a[1][2] = 30;
//      System.out.println(a[1][3]); // 因为最长指向3,即是a[2],所以会报错ArrayIndexOutOfBoundsException
        System.out.println(a[1][2]); // 30
​
        System.out.println(a[2][4]); // 0,因为没有赋值,默认为0
        a[2][3] = 70;
        System.out.println(a[2][3]); // 70
    }
}
示例 静态初始化
package ArraryLearn;
​
public class TestM01 {
    public static void main(String[] args) {
        int[][] b = {
               {1,33,77},  // b0
               {17,56,42}, // b1
               {18,19,50,23,66}  // b2
        };
        System.out.println(b[1][2]);  // 42
    }
}
示例 动态初始化
package ArraryLearn;
​
public class TestM02 {
    public static void main(String[] args) {
        int[][] c = new int[4][];
//      c[0] = {1,2,3,4};     // 错误,未声明类型就初始化
        c[0] = new int[]{56,33,17,18,22};
        c[1] = new int[]{88,66,99,77,44,33,55};
        c[2] = new int[]{12,23,34,45,56,67,78,89};
        c[3] = new int[]{123,456,789};
​
        System.out.println(c[0][4]);   // 22
        System.out.println(c[1][6]);   // 55
        System.out.println(c[2][5]);   // 67
        System.out.println(c[3][2]);   // 789
        
        System.out.println(Arrays.toString(c[0])); // [56, 33, 17, 18, 22]
    }
}

存储表格数据

package ArraryLearn;
​
import java.util.Arrays;
​
public class PrintArrayClass {
    public static void main(String[] args) {
      Object[] a = {"2021-04-06","张三",100," 真厉害!"};
      Object[] b = {"2021-04-06","李四",85," 还不错哦!"};
      Object[] c = {"2021-04-06","王五",59," 怎么回事小老弟?"};
​
      Object[][] temps = new Object[3][];
      temps[0] = a;
      temps[1] = b;
      temps[2] = c;
​
      System.out.println(Arrays.toString(temps[0]));
      System.out.println(Arrays.toString(temps[1]));
      System.out.println(Arrays.toString(temps[2]));
​
      // for循环实现
      for(int i = 0;i < temps.length;i++){
        for(int j = 0;j < temps[i].length;j++){
            System.out.print(temps[i][j] + "\t");
        }
        System.out.println();
      }
    }
}
示例 使用javabean和一维数组保存表格信息

javabean 是一种特殊的Java类,用于封装数据和方法,使它们能够更容易地在应用程序中使用。

package ArraryLearn;
​
public class TestJavabean {
    public static void main(String[] args) {
        person[] p = {
               new person(18,"张三",1,"哈哈","04-06"),
               new person(19,"李四",2,"嘿嘿","04-06"),
               new person(20,"王五",3,"吼吼","04-06")
        };
​
        // 遍历数组
        for(person p1:p){
           System.out.println(p1); // 打印的是地址
           //ArraryLearn.person@4554617c
           //ArraryLearn.person@74a14482
           //ArraryLearn.person@1540e19d
        }
    }
}
​
class person{
    private int age;
    private String name;
    private int id;
    private String job;
    private String hiredate;
​
    public person(int age, String name, int id, String job, String hiredate) {
        this.age = age;
        this.name = name;
        this.id = id;
        this.job = job;
        this.hiredate = hiredate;
    }
​
    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;
    }
​
    public int getId() {
        return id;
    }
​
    public void setId(int id) {
        this.id = id;
    }
​
    public String getJob() {
        return job;
    }
​
    public void setJob(String job) {
        this.job = job;
    }
​
    public String getHiredate() {
        return hiredate;
    }
​
    public void setHiredate(String hiredate) {
        this.hiredate = hiredate;
    }
​
    // 重写打印出信息
    @Override
    public String toString() {
        return "person{" +
               "age=" + age +
               ", name='" + name + '\'' +
               ", id=" + id +
               ", job='" + job + '\'' +
               ", hiredate='" + hiredate + '\'' +
               '}';
    }
}

Comparable接口

----定义比较策略

Comparable接口只有一个方法:

public int CompareTo(Object obj)

obj为要比较的对象

方法中,将当前对象和obj这个对象进行比较,如果大于返回1,等于返回0,小于返回-1(此处的1可以是正整数,-1也可以是负整数)。compareTo方法的代码也比较固定

示例

import java.util.Arrays;
​
public class Test {
    public static void main(String[] args) {
        Man[] mans = {
               new Man(18,"张三"),
               new Man(29,"李四"),
               new Man(20,"王五")
        };
        Arrays.sort(mans);
        System.out.println(Arrays.toString(mans));
    }
}
class Man implements Comparable{
    int age;
    int id;
    String name;
​
    public Man(int age, String name) {
        this.age = age;
        this.name = name;
    }
​
    @Override
    public String toString(){
        return this.name;
    }
​
    public int compareTo(Object o){
        Man man = (Man) o;
        if(this.age < man.age){
           return -1;
        }
        if(this.age > man.age){
           return 1;
        }
        return 0;
    }
}

常见算法

算法可视化:visualising data structures and algorithms through animation - VisuAlgo

冒泡排序算法

重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来,这样越大的元素会经由交换慢慢"浮"到数列的顶端。

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个

  • 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会 是最大的数

  • 针对所有的元素重复以上的步骤,除了最后一个

  • 持续每次对越来越少的元素重复上面的步骤,知道没有任何一对数字需要比较

eg:

初始: 3 1 6 8 9 0 7 4 5 2

第一趟:1 3 6 8 0 7 4 5 2 9

第二趟:1 3 6 0 7 4 5 2 8 9

第三趟:1 3 0 6 4 5 2 7 8 9

第四趟:1 0 3 4 5 2 6 7 8 9

第五趟:0 1 3 4 2 5 6 7 8 9

第六趟:0 1 3 2 4 5 6 7 8 9

第七趟:0 1 2 3 4 5 6 7 8 9

第八趟:0 1 2 3 4 5 6 7 8 9

第九趟:0 1 2 3 4 5 6 7 8 9

第十趟:0 1 2 3 4 5 6 7 8 9

示例 冒泡算法
import java.awt.image.AreaAveragingScaleFilter;
import java.util.Arrays;
​
public class TestBubblesort {
    public static void main(String[] args) {
        int[] values = {3,1,6,8,9,0,7,4,5,2};
        System.out.println("初始顺序:" + Arrays.toString(values));
        bubbleSort(values);
​
    }
​
    public static void bubbleSort(int[] values){
        int temp;
        for(int i = 0;i < values.length;i++){
           for(int j = 0;j < values.length - 1 - i;j++){
               if(values[j] > values[j + 1]){
                  temp = values[j];
                  values[j] = values[j + 1];
                  values[j + 1] = temp;
               }
           }
           System.out.println((i + 1) + "趟排序:" + Arrays.toString(values));
           // 打印结果
//         初始顺序:[3, 1, 6, 8, 9, 0, 7, 4, 5, 2]
//         1趟排序:[1, 3, 6, 8, 0, 7, 4, 5, 2, 9]
//         2趟排序:[1, 3, 6, 0, 7, 4, 5, 2, 8, 9]
//         3趟排序:[1, 3, 0, 6, 4, 5, 2, 7, 8, 9]
//         4趟排序:[1, 0, 3, 4, 5, 2, 6, 7, 8, 9]
//         5趟排序:[0, 1, 3, 4, 2, 5, 6, 7, 8, 9]
//         6趟排序:[0, 1, 3, 2, 4, 5, 6, 7, 8, 9]
//         7趟排序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//         8趟排序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//         9趟排序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//         10趟排序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        }
    }
}
示例 优化算法
  • 把整个数列分为两部分:前面是无序数列,后面是有序数列

  • 判断每一趟是否发生了数组元素的交换,如果没发生,则说明此时数组已经有序,无需再进行比较,可终止

import javax.swing.plaf.synth.SynthOptionPaneUI;
import java.util.Arrays;
​
public class GoodBubbleSort {
    public static void main(String[] args) {
        int[] a = {3,1,6,8,9,0,7,4,5,2};
        System.out.println("原始序列:" + Arrays.toString(a));
        bubbleSort2(a);
​
    }
​
    public static void bubbleSort2(int[] a){
        int temp;
​
        for(int i = 0;i < a.length - 1;i++){
           boolean flag = true; // 标记数组是否有序了
​
           for(int j = 0;j < a.length - 1 - i;j++){
               if(a[j] > a[j + 1]){
                  temp = a[j];
                  a[j] = a[j + 1];
                  a[j + 1] = temp;
​
                  flag = false; // 发生了交换,表明是无序状态,需要继续比较
               }
           }
           // 根据标记量的值判断是否有序,有序退出循环,无序反之
           if(flag){
               break;
           }
           System.out.println("第" + (i + 1) + "趟排序:" + Arrays.toString(a));
           // 输出结果
//         原始序列:[3, 1, 6, 8, 9, 0, 7, 4, 5, 2]
//         第1趟排序:[1, 3, 6, 8, 0, 7, 4, 5, 2, 9]
//         第2趟排序:[1, 3, 6, 0, 7, 4, 5, 2, 8, 9]
//         第3趟排序:[1, 3, 0, 6, 4, 5, 2, 7, 8, 9]
//         第4趟排序:[1, 0, 3, 4, 5, 2, 6, 7, 8, 9]
//         第5趟排序:[0, 1, 3, 4, 2, 5, 6, 7, 8, 9]
//         第6趟排序:[0, 1, 3, 2, 4, 5, 6, 7, 8, 9]
//         第7趟排序:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        }
    }
}

二分法查找

binary Search --- 折半检索

查找之前需要排序

import java.util.Arrays;
​
public class TestBinarySearch {
    public static void main(String[] args) {
        int[] arr = {30, 20, 10, 40, 50, 60, 70, 80, 55, 90};
        int searchNumber = 50;   // 所要找的数
        Arrays.sort(arr);
​
        System.out.println(Arrays.toString(arr));
        System.out.println(searchNumber + "元素的索引:" + binarySearch(arr,searchNumber));
        
        // [10, 20, 30, 40, 50, 55, 60, 70, 80, 90]
        // 50元素的索引:4
    }
​
    public static int binarySearch(int[] array, int value) {
        // low 与 high 区间
        int low = 0;
        int high = array.length - 1;
​
        while (low <= high) {
           int middle = (low + high) / 2;
           if (value == array[middle]) {
               return middle;  // 返回查询到的索引位置
           }
           if(value > array[middle]){
               low = middle + 1;
           }
           if(value < array[middle]){
               high = middle - 1;
           }
        }
        return -1;   // 循环完,说明未找到,返回-1
    }
}
  • 19
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的Comparable接口定义了一个compareTo方法,用于比较类的对象之间的大小关系。实现Comparable接口的类可以使用Arrays.sort()和Collections.sort()进行排序。 实现Comparable接口的类需要重写compareTo方法,该方法返回一个整数值,表示当前对象与另一个对象的大小关系。如果当前对象小于另一个对象,则返回负整数;如果当前对象等于另一个对象,则返回0;如果当前对象大于另一个对象,则返回正整数。 以下是一个示例实现Comparable接口的类: ``` public class Person implements Comparable<Person> { private String name; private int age; public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Person o) { return this.age - o.getAge(); } } ``` 在上面的示例中,Person类实现了Comparable接口,并重写了compareTo方法。该方法比较两个Person对象的年龄大小关系。 如果要对Person对象进行排序,可以使用Arrays.sort()或Collections.sort()方法。例如: ``` Person[] persons = new Person[] { new Person("Tom", 25), new Person("Jack", 18), new Person("Mary", 30) }; Arrays.sort(persons); for (Person person : persons) { System.out.println(person.getName() + " " + person.getAge()); } ``` 该示例中,使用Arrays.sort()对Person对象数组进行排序,按照年龄从小到大排序。最后输出排序后的结果。 需要注意的是,实现Comparable接口的类必须能够比较大小,否则可能会抛出ClassCastException异常。因此,在重写compareTo方法时,应该考虑到类的属性是否可以比较大小。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值