黑马程序员_内部类、数组的排序

 

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------

        今天学习的内容包括内部类,以及数组的排序和数组中元素的查找。

1:内部类:
        定义:把一个类定义到另一个类的内部,这样的类叫做内部类,也叫嵌套类或者内置类。
        也就是说定义在另一个类内部的类叫内部类。

        内部类的特点:
        内部类可以直接访问外部类的成员,包括私有。
        外部类要想访问内部类的成员,必须创建对象。
        内部类本身也是封装的一种体现。

        内部类的应用场景:
        一个类和另一个类有嵌套关系时,可以使用内部类

        内部类可以定义的位置:    

        成员位置:把内部类定义在成员位置,这个内部类叫做成员内部类
        局部位置:把内部类定义在局部位置,这个内部类叫做局部内部类
        在其他的类中访问成员内部类的方式:

        外部类名.内部类名 变量名 = 外部类对象.内部类对象

        成员内部类的常见修饰符:
        private:防止外界直接调用,保证代码的安全性
        static:为了访问数据的方便

例如下面的代码就是访问private修饰的成员内部类:

package cn.itcast;
public class Body {
 private class Heart {            //通过private修饰成员内部类

  public void operator() {
   System.out.println("打开心脏");
   System.out.println("进行手术");
   System.out.println("关闭心脏");
  }
 }
 
 public void operatorHeart(Person p) {
  if(p.getProfession() == "Doctor") {       //对输入的参数进行检查,以保证代码的安全性

   Heart h = new Heart();
   h.operator();
  }
  
 }
} 
package cn.itcast;
public class Person {
 public String profession;        
 public Person() {
  super();
 }
 public Person(String profession) {
  super();
  this.profession = profession;
 }
 public String getProfession() {
  return profession;
 }
 public void setProfession(String profession) {
  this.profession = profession;
 }
}
package cn.itcast;
public class Test {
 public static void main(String[] args) {
  Person p = new Person("Doctor");
  Body b = new Body();
  b.operatorHeart(p);
 }
}

 

        对于静态内部类中非静态方法的访问方式:
        外部类名.内部类名 变量名 = new 外部类名.内部类名();
        变量名.方法名
        对于静态内部类的静态方法
        外部类名.内部类名.方法名

        局部内部类:

        类定义在外部类的方法中

        如果局部内部类访问局部变量,那么局部变量必须用final修饰,为什么?
        因为局部内部类的对象使用完毕,不会立即被回收,会在不确定的时间被垃圾回收器回收,所以在局部内部类访问局部变量,那么局部变量必须用final修饰。

        匿名内部类:匿名内部类属于局部内部类,本质上来说是一个对象。

        匿名内部类的前提:

        匿名内部类可以继承一个外部类或者实现一个接口。
        匿名内部类的格式:
        new 外部类名或者接口名() {

            重写类或者接口中的方法,也可以自己定义方法
          };

         匿名内部类可以理解为继承类或者实现接口的子类匿名对象。

        例如:

 interface Inner{
  public abstract void show();
 }
 class Outer {
  public void method() {
   Inner i = new Inner() {
    public void show() {                //匿名内部类是一个对象,所以可以将其赋值给一个变量

     System.out.println("show");
    }
   };
   i.show();        //通过接口的子类对象调用方法

  }
 }
 class Test {
  Outer o = new Outer();
  o.method();
 }

 2:数组的两种排序方法

        数组的主要排序方法有两种,一种是选择排序,一种是冒泡排序,两种排序方法的效果相同,但是具体的实现原理不同。

        A:选择排序法:

        原理:选择排序是拿数组中第一个位置的元素和后面的元素比较,如果后面比到的元素比第一个位置的元素小,那么就把小的元素放到第一个位置上,然后继续拿第一个位置的元素和后面剩余的元素比较,一直到最后一个元素,然后再拿第二个位置的元素和后面的元素比,一直到最后一个元素。第一次比完之后,最小的元素出现在第一个位置,也就是0索引处。

具体代码的实现过程:

package cn.itcast;
/*
 * 选择排序:
 * */
public class SelectSort {
 public static void main(String[] args) {
  int[] arr = { 45, 26, 37, 88, 25, 67, 40 };
  printArray(arr);        
  selectSort(arr);        //调用数组的排序方法

  printArray(arr);
 }
 private static void selectSort(int[] arr) {
  for (int x = 0; x < arr.length - 1; x++) {    
   for (int y = x + 1; y < arr.length; y++) {       //每次比较的时候,都不用和自身比,所以+1

    if (arr[y] < arr[x]) {                        //对两个元素比较

     int temp = arr[y];                            //对于满足条件的元素调换位置

     arr[y] = arr[x];
     arr[x] = temp;
    }
   }
  }
 }
 //定义一个输出数组的方法

 public static void printArray(int[] arr) {
  System.out.print("[");
  for (int x = 0; x < arr.length; x++) {
   if (x != arr.length - 1) {                //判断当前遍历到的元素是不是最后一个元素

    System.out.print(arr[x] + ", ");
   } else {
    System.out.println(arr[x] + "]");
   }
  }
 }
}

        B:冒泡排序法:

        原理:冒泡排序的原理就是将数组中相邻的两个元素进行比较,大的向后边移,然后大的再和后面相邻的元素比,小的向前移动,大的向后移动,比到最后一个的时候,最大值就出现在最后的位置。然后再次进行比较,一直到所有元素都比较完成。

        具体的代码实现过程:

 package cn.itcast;
/*
 * 冒泡排序:
 * */
public class BubbleSort {
 public static void main(String[] args) {
  int[] arr = { 12, 43, 23, 62, 54, 89 };
  printArray(arr);
  bubbleSort(arr);
  printArray(arr);
 }
 private static void bubbleSort(int[] arr) {
  for (int x = 0; x < arr.length; x++) {

//   -1是为了避免角标越界
//   -x是为了每次比较时不用比较后面的最大值

   for (int y = 0; y < arr.length - 1 - x; y++) {
    if (arr[y] > arr[y + 1]) {
     int temp = arr[y];
     arr[y] = arr[y + 1];
     arr[y + 1] = temp;
    }
   }
  }
 }
 public static void printArray(int[] arr) {
  System.out.print("[");
  for (int x = 0; x < arr.length; x++) {
   if (x != arr.length - 1) {
    System.out.print(arr[x] + ", ");
   } else {
    System.out.println(arr[x] + "]");
   }
  }
 }
}

 3:数组元素的查找:折半查找

        折半查找的前提是数组必须有序,如果数组无序,就不能使用折半查找,必须使用普通的查找方法,也不能先排序再查找,否则会改变原有的顺序。

        折半查找的原理:折半查找就是拿要查找的元素先和数组里面中间索引处的元素比较,如果该元素大于数组里面中间索引位置的元素,那么再拿该元素和后边一半的中间元素比较,如果大于中间索引处的元素,继续和剩余的数组元素的中间索引处的元素相比较,一直到找到为止,如果数组索引的最小索引大于最大索引,那么就说明该元素不在数组中,返回-1。

        具体的代码实现过程:

package cn.itcast;
/* 
 * 需求:写折半查找的功能实现
 * */
public class ArrayDemo {
 public static void main(String[] args) {
  int[] arr = { 12, 15, 20, 26, 32, 45, 69 };
  int index = getIndex(arr, 20);
  System.out.println(index);
 }
 private static int getIndex(int[] arr, int value) {

    int min = 0;                //定义第一次查找的最小索引

  int max = arr.length - 1;   //定义第一次查找的最大索引 

  int mid = (min + max) / 2;    //定义第一次查找的中间索引

  while (arr[mid] != value) {      
  if (arr[mid] > value) {        //中间索引处元素的值小于要查找的元素的值

    max = mid - 1;                 //将中间索引-1作为下一次查找的最大索引

   } else if (arr[mid] < value) {    //中间索引处的元素大于要查找的元素的值

    min = mid + 1;                    //将中间索引+1作为下一次查找的最小索引

   }
   if (min > max) {            //最小索引大于最大索引

    return -1;                 //返回-1,说明在数组中没有找到该元素

   }
   mid = (min + max) / 2;        //将中间索引的值改为修改后的最大索引和最小索引的中间值

  }
  return mid;                     //返回符合条件的索引

 }
}

        这些就是今天的学习内容,其中比较容易弄错的就是数组的寻则排序和冒泡排序,而最难理解的是匿名内部类,要把匿名内部类作为一个对象,最后经过老师的反复讲解才弄清楚。

 

 

---------------------- <a href="http://www.itheima.com"target="blank">ASP.Net+Unity开发</a>、<a href="http://www.itheima.com"target="blank">.Net培训</a>、期待与您交流! ----------------------详细请查看:<a href="http://www.itheima.com" target="blank">www.itheima.com</a>

转载于:https://my.oschina.net/u/1390204/blog/288093

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值