java面向对象高级(根据青空的霞光总结)

# 面向对象高级(青空)

基本类型包装类

前置:

  • 虽然java是面向对象的语言,但是基本类型不是面向对象的,如果想要让基本类型也能像面向对象的形式进行表达,就可以是用包装类
  • 包装类实际上就是将我们的基本数据类型,封装成一个类(运用了封装的思想)

类型:

  • byte -> Byte
  • boolean -> Boolean
  • short -> Short
  • char -> Character
  • int -> Integer
  • long -> Long
  • float -> Float
  • double -> Double

装箱拆箱

  • 使用包装类会自动装箱与拆箱,也就是可以直接将一个基本类型的值赋值给一个包装类,编译器自动将这个基本类型进行了装箱。

  • Integer i = 11;     //与 Integer i = new Integer(11)一致  或者 Integer i = Integer.valueOf(10)    把一个基本类型转为包装类
            int a=i.intValue();            //与  int a=i.intValue()  一致;      intvalue()  :将一个包装类转化为int这种基本类型
    

imagecache

  • 要判断两个数字是否相等,

    • 如果是基本类型,就可以直接使用==

    • 如果是包装类的对象,直接使用==是判断是否是同一个对象

      • 但是如果使用自动装箱,这里的得到的依然是true 因为自动装箱机制(valueof)中有一个imagecacche这样一个缓存机制,他会缓存-127到127的所有数到一个数组中,进行自动装箱创建对象就会从缓存中拿到那个对象,始终只能拿到一个对象,所以==就是true,equal也是一样,如果超出了-127到127就也是false

      • Integer i=10;
        Integer a=10;
        System.out.println(i==a);     
        
      • 如果直接声明两个integer对象,再使用==判断,就是false了

      • 这时要判断对象的值是否相等就要使用equal来判断

      • Integer i = new Integer(10);
        Integer a = new Integer( 10);
         System.out.println(i.equals(a));
        

包装类的方法

  • 字符串转换成int(int转字符串 )

    • Integer i = new Integer(10);
      String str=String.valueOf(i);
       System.out.println(str);
      
      
         String str="123";
             Integer i=Integer.valueOf(str);      // Integer i=Integer.parseInt(str);
              System.out.println(i);
      
  • 对十六进制与八进制进行编码

    • 转10进制

    • Integer i=Integer.decode("0x10");
        System.out.println(i);
      
    • 十进制转其他进制:

      • System.out.println(Integer.toHexString(12));  /16进制
        
  • 对象的值是否相等

特殊包装类

void

​ void也有包装类,但是只能等于null,没啥用

BigInterger

计算一个很大的数字

  • 如果使用基本类型,当数据超出范围就会出错。

  • BigInteger i = BigInteger.valueOf(Long.MAX_VALUE);   //放入long能表示的最大数
    System.out.println(i);
    
  • 计算方式 :不能使用运算符,而是使用特定的方法进行 ,而且得到的结果以返回值得形式存在,需要另一个biginteger来接收

    • BigInteger i = BigInteger.valueOf(Long.MAX_VALUE);   //放入long能表示的最大数
      BigInteger a=i.add(BigInteger.valueOf(Long.MAX_VALUE) );      //加法
      System.out.println(i);
      
    • BigInteger i = BigInteger.valueOf(Long.MAX_VALUE);   //放入long能表示的最大数
      BigInteger a=i.multiply(BigInteger.valueOf(Long.MAX_VALUE) );   //乘法
      System.out.println(a);
      

精确计算小数

BigDecimal i= BigDecimal.valueOf(10);
BigDecimal a=i.divide(BigDecimal.valueOf(3),100,BigDecimal.ROUND_FLOOR);  //第一个参数是要除的值,第二个是小数位数(对于无限循环小数),第三个是第一百位数字的保留形式 (向下取整)
System.out.println(a);

数组

可变长度的数组

  • 因为方法是可以有不确定个数的参数,这些参数,都是使用数组来保存的

字符串

由于java中没有字符串这种基本数据类型,所以要实现字符串,就要使用类

String 类

  • String本身也是一个类,只不过它比较特殊,每个用双引号括起来的字符串,都是String类型的一个实例对象
  • 创建:
    • 可以直接双引号,如果是直接使用双引号创建的字符串,如果内容相同,为了优化效率,那么始终都是同一个对象
    • 可以new一个对象,值放到括号里,new出来的就不是一个对象了
  • 判断是否内容相同使用equal

一些方法

  • str.length 返回字符串长度

  • str.substring(开始下标,结束下标) 分割字符串,并返回一个新的子串对象 与Python的切片一样

  • str.split(“分割的标志”) 通过给定的标志字符来分割字符串,如 a.b.c.d 若按照点来切割,就得到【a b c d】 这样一个数组

  • 字符数组和字符串之间是可以快速进行相互转换的

    • char[]  a={'1','2','3'};
      String i= new String(a);
      System.out.println(i);
      
    • String i="123";
      char[] a=i.toCharArray();
      System.out.println(a);
      

StringBuilder

使用StringBuilder来连接字符串

我们可以通过+来连接字符串,在编译时,会自动将这两个字符串连接后赋值给一个String对象,如果+很多,就要一个一个加,中间就会产生多个中间String对象,就比较浪费资源,直接使用StringBuilder来连接就好很多

使用

String i="123";
String str="ni";
String str1="干";
String str2="嘛";
StringBuilder sb=new StringBuilder();
sb.append(i).append(str).append(str1).append(str2);
System.out.println(sb.toString());

正则表达式

想要判断用户输入的内容是否满足某种格式(如邮箱格式),如果满足返回true,不满足返回false

比较的函数

  • java的字符串中提供了matches这个方法,用正则来匹配

内部类

成员内部类

内部类:就是在类的内部再定义一个类

使用

  • public class cls {
        public class Test{
            public String name;
            public  void getMessage(){
                System.out.println("这是一个内部类");
            }
        }
    }
    
  • public class main {
        public static void main(String[] args) {
            cls cls = new cls();
            cls.Test test=cls.new Test();
            test.getMessage();
        }
    }
    
  • 内部类可以访问外部类的属性与方法,但外部类不能访问内部类

  • 对于同名变量的调用

    • public class cls {
          public String name;
          public class Test{
              public String name;
              public  void getMessage(String name){
                  System.out.println(name);
                  System.out.println("第二个name  "+this.name);
                  System.out.println("第三个name   "+cls.this.name);
                  System.out.println("这是一个内部类");
              }
          }
      }
      
    • public class main {
          public static void main(String[] args) {
              cls cls = new cls();
              cls.Test test=cls.new Test();
              test.getMessage("第一个name   ");
      
          }
      }
      
    • 对于super的使用也是一样的

静态内部类

就是在成员内部前加上static关键词使其变成静态

使用

  • public class Cls {
        public String name;
        public static class inner{
            public void getmessage(){
                System.out.println("这是一个静态内部类");
            }
        }
    }
    
  • public class main {
        public static void main(String[] args) {
            Cls.inner inner=new Cls.inner();  //不需要依托与对象了
            inner.getmessage();
        }
    }
    
  • 因为内部类是静态的所以无法访问外部,除非外部也是一个静态的属性或者方法

局部内部类

声明在类中的方法中的类

public class Cls {
    public String name;
    public static  String x="这是x";
    public void getmessage(){
        class inner{   //不允许使用修饰符
        }
        inner inner = new inner();
        
    }
}

匿名内部类

作用

抽象类和接口的方法的实现:1.子类继承,子类实现,2.使用匿名内部类

使用

public class Main {
    public static void main(String[] args) {
        Student student=new Student() {  //new 的时候加上花括号,把抽象方法实现一下,并创建创建出实例对象
            @Override
            public void getmessage() {
                System.out.println("这是一个匿名内部类");
            }
        };
    student.getmessage();      //这里的student就是已经实现了抽象方法的一个实例对象,但是这个类甚至没有名字,就直接有了一个实例对象
    }
}
public interface Student {
    public void getmessage();
}
  • 抽象类也可以。
  • 普通类也可以创建匿名内部类,但是意义不大。

lambda表达式

作用:

  • 可以认为其实就是匿名内部类的简写(底层其实不是简简单单的替换)

条件

  • 必须是只有一个必须要实现的匿名方法的接口。它不支持抽象类,因为抽象类不是只有方法,它还有属性
  • 假如接口中有两个抽象方法,其中一个使用了default 有默认实现,也行

格式

  • 标准格式为:([参数类型 参数名称,]...) ‐> { 代码语句,包括返回值 }

  • 无参数或参数为多个时括号必须写,只有一个参数可以省略括号,类型也可以省略

  • 代码语句只有一句,花括号可以省略,

  • 代码语句只有返回值语句,return和花括号都可以省

  • 那么就会出现这样的语句

    • public class Main {
          public static void main(String[] args) {
              Student student= a-> a;     参数先省去括号和类型,只有返回值语句,省略return和花括号
              System.out.println(student.getmessage(33));
          }
      }
      
      public interface Student {
          public int  getmessage(int a);
      }
      

使用

  • 使用前
public class Main {
  public static void main(String[] args) {
    Student student=new Student() {
      @Override
      public void getmessage() {
        System.out.println("这是一个匿名内部类");
      }
    };
    student.getmessage();
  }
}
  • 使用后

  • public class Main {
        public static void main(String[] args) {
            Student student= () -> System.out.println("这是一个匿名内部类");  
        student.getmessage();
        }
    }
    
  • 如果某个方法的参数是一个接口的实现,那么就可以使用这个

    • public class Main {
          public static void main(String[] args) {
              Student student= a-> a;
              System.out.println(student.getmessage(33));
              get(student);
          }
          public static void get(Student student){
              System.out.println("啊,确实挺不错的");
          }
      }
      

方法引用

概念

  • 直接将已经实现了的现成方法(自己实现的,或者jdk已经实现好的)拿过来当做抽象方法的实现。
  • 当然方法的名称,参数,返回值等等都需要一致

使用

  • 比如有一个接口中只有一个相加的方法

    • public interface Student {
         public int sum(int a,int b);
      }
      
  • 使用匿名内部类 和lambda都可以实现

    • public class Main {
          public static void main(String[] args) {
      
              Student student=(int a,int b)->a+b;
              System.out.println(student.sum(1,3));
          }
      }
      
  • 但是还可以更简单,因为sum这个方法,在integer中已经有过定义了,我们就可以直接把他引用过来

    • public class Main {
          public static void main(String[] args) {
      
              Student student=Integer::sum;
              System.out.println(student.sum(1,3));
          }
      }
      
  • 再比如有这样一个接口,并没有一个现成的类实现了该方法

    • public interface Student {
      
         public  void getmessage();
      }
      
  • 我们就可以自己实现出来,把自己的方法引用上,我觉得一般是用的时候恰好,在之前我们已经实现过了这个方法,我们直接引用了该方法

    • public class Main {
          public static void main(String[] args) {
              Main main = new Main();
              Student student=main::getmessage;
              student.getmessage();
          }
          public void getmessage(){
              System.out.println("这是一个被方法引用的方法");
          }
      }
      

异常处理

分类

  • 运行时异常
    • 继承自runtimeexception
  • 编译时异常
    • 继承自exception
  • 错误 error
    • 直接导致jvm运行不了了
  • RuntimeException继承自Exception,Exception继承自Throwable

抛出异常

  • 当别人给出了错误的参数,使程序无法运行,就可以手动抛出运行时时异常,使程序终止

    • public class Except {
          public static void main(String[] args) {
              div(1,0);
      
          }
          public static int  div(int a ,int b){
              if(b==0){
                  throw new ArithmeticException("除数不能为零");
              }
              return a/b;
          }
      }
      
    • 程序终止并打印出栈信息

      • Exception in thread "main" java.lang.ArithmeticException: 除数不能为零
        at com.ximenheiniu.blog.except.Except.div(Except.java:10)
        at com.ximenheiniu.blog.except.Except.main(Except.java:5)
    • 如果我们在方法中抛出了一个非运行时异常,那么我们就要告知函数的调用方,我们抛出了一个异常,调用方要进行处理

      • public class Except {
            public static void main(String[] args) throws Exception{
                div(1,0);
        
            }
            public static int  div(int a ,int b) throws Exception{
                throw new Exception("出错啦");
        
            }
        }
        
    • 如果不同分支会造成不同异常,就都要抛出

    • 运行时异常也可以抛出,但是不做要求

异常的处理

为啥要处理

  • 程序在遇到异常后会终止程序,但是我们希望程序遇到异常后可以跳过异常运行完。

处理方式

  • 我们可以将可能会出错的代码写到try语句中,catch语句写发生异常后运行的代码

  • 注意:catch中捕获的类型只能是Throwable的子类,,也就是说要么是抛出的异常,要么是错误,不能是其他的任何类型。

  • 如果某个方法明确指出会抛出异常,而且是非运行时异常,我们一定要处理,否则无法编译

  • 当然我们也可以不在这一级处理该异常,而是将异常抛出,让上一级去处理

  • 如果我们要捕获的异常,是某个异常的父类,那么当发生这个异常时,同样可以捕获,有点像是用异常的父类来泛指了一下子类异常

  • catch可以有多个,当代码可能发生多种异常,不确定是哪一个,就可以多个catch,但是注意子类在前,父类在后,否则子类永远不会被捕获,最后要有一个exception兜底

    • 也可以一个catch,异常用括号括起来,中间用 | 隔开。

      • try{
                   
               }catch (ArithmeticException){
                   
               }catch (Exception){
                   
               }
        
      • try{
        
        }catch (NullPointerException | IndexOutOfBoundsException e){
        
        
        };
        
  • 当我们希望,程序运行时,无论是否出现异常,都会在最后执行任务,可以交给finally语句块来处理

常用工具类

数学工具类

这个类是java.util包下类

  • 乘方
    • Math.pow(5,7) 5的7次方
  • 绝对值
    • Math.abs(-1)
  • Math.max 最大值
  • 算数平方根
    • Math.sqrt()
  • Math.PI
  • Math.E
  • Math.sin
  • Math.log
  • Math.ceil 向上取整
  • Math.floor 向下取整
  • Random rand=new Random(); random.nextint(100); 生成随机数

数组工具类

这个类也是java.util包下类

  • 打印:arrays.tostring()

  • 排序:arrays.sort(arr)

  • 填充 : arrays.fill(arr,填充物)

  • 复制:

    • import java.util.Arrays;
      
      public class Except {
          public static void main(String[] args) throws Exception{
              int[] a={1,23,4,65,213,564,6};
              int [] x=Arrays.copyOf(a,12); //复制a数组生成一个新的数组,并给出数组的长度
              System.out.println(Arrays.toString(a));
              System.out.println(x.length);
          }
      
      }
      
      
    • public class Except {
          public static void main(String[] args) throws Exception{
            int[] a={1,23,4,65,213,564,6};
              int [] x=new int[10];
              System.arraycopy(a,1,x,2,5);   //(源数组,源数组复制起始位置,目标数组,,目标数组放置起始位置,复制长度)   利用数组进行搬运
              System.out.println(Arrays.toString(x))
          }
      
      }
      
    • import java.util.Arrays;
      
      public class Except {
          public static void main(String[] args) throws Exception{
              int[] a={1,23,4,65,213,564,6};
             int []x=Arrays.copyOfRange(a,0,1);  //选择范围进行复制
              System.out.println(Arrays.toString(x));
          }
      
      }
      
  • 查找

    • 对于有序数组可以使用二分查找

      • public class Except {
            public static void main(String[] args) throws Exception{
                int[] a={1,23,4,65,213,564,6};
                Arrays.sort(a);
                System.out.println(Arrays.binarySearch(a,1));
            }
        
        }
        
  • 判断相等

    • public class Except {
          public static void main(String[] args) throws Exception{
              int[][] a = new int[][]{{2, 8, 4, 1}, {9, 2, 0, 3}};
              int[][] b = new int[][]{{2, 8, 4, 1}, {9, 2, 0, 3}};
              System.out.println(Arrays.equals(a, b));   //equals仅适用于一维数组
              System.out.println(Arrays.deepEquals(a, b));   //对于多维数组,需要使用deepEquals来进行深层次判断
          }
          }
      

练习

冒泡排序

  • 有一个int数组,但是数组内的数据是打乱的,现在我们需要将数组中的数据按从小到大的顺序进行排列:

  • import java.util.Arrays;
    
    public class MaoPao {
        public static void main(String[] args) {
            int[] arr = new int[]{3, 5, 7, 2, 9, 0, 6, 1, 8, 4};
            int [] a=sort(arr);
            System.out.println(Arrays.toString(a));
        }
    
        public static int[] sort(int[] arr ){
            int tmp=arr[0];
            for (int j = 0; j < arr.length-1; j++) {
                for (int i = 0; i <arr.length-1-j; i++) {
                    if(arr[i]<arr[i+1]){
                        tmp=arr[i];
                        arr[i]=arr[i+1];
                        arr[i+1]=tmp;
                    }
                }
            }
    
            return arr;
        }
    
    }
    

二分查找

public class Binarysearch {
    public static void main(String[] args) {
        int[] arr = {1, 3, 4, 6, 7, 8, 10, 11, 13, 15};
        int target = 1;
        int result = binarysearch(arr, target);
        System.out.println(result);
    }

    public static int binarysearch(int[] arr, int target) {
        int left = 0;
        int right = arr.length - 1;

        while (left <= right) {
            int mid = (left + right) / 2;
            if (arr[mid] > target) {
                //mid以及mid以后的就不用找了
                right = mid - 1;
            } else if (arr[mid] < target) {
                left = mid + 1;
            } else {
                return mid;
            }
        }
        return -1;
    }
}

斐波那契(青蛙跳台阶)

//斐波那契
public class Frog {
    public static void main(String[] args) {
        int result=jump(2);
        System.out.println(result);
    }
    public static int jump(int n){
        int [] arr=new int[n+1];
        //考虑到如果n是0,就也是一种
        arr[0]=1;
        arr[1]=1;
        for (int i = 2; i <=n ; i++) {
            arr[i]=arr[i-1]+arr[i-2];
        }
        return arr[n];
    }
}
posted @ 2023-09-03 14:03  西门黑牛  阅读(20)  评论(0编辑  收藏  举报