Java总结【黑马程序员】(未完)

一.基础

1.类与对象,成员方法,构造器

方法

2.this,super,final,常量

final

 常量

作为常量时,一定要将其初始化,即赋值。 

3.封装,继承,多态

继承

 注意:

调用子类的无参构造器之前,先执行父类的无参构造器,在执行自己的。

class Z{
    public Z(){
        System.out.println("调用了父类的无参构造器");
    }
    public Z(String name){
        System.out.println("调用了父类的有参构造器");
    }
}
class F extends Z{
    public F(){
        System.out.println("调用了子类的无参构造器");
    }
    public F(String name){
        System.out.println("调用了子类的you参构造器");
    }
}
public class String1 {
    public static void main(String[] args) {
          F f = new F();
    }
}

//调用了父类的无参构造器
//调用了子类的无参构造器

调用子类的有参构造器之前,先执行父类的无参构造器,并不执行父类的有参构造器,之后在执行自己的有参。

public class String1 {
    public static void main(String[] args) {
          F f = new F("郝仁");
    }
}

//调用了父类的无参构造器
//调用了子类的you参构造器

原因:子类的构造器中,都默认第一行存在一个super(),它就会去调用父类的无参构造器。

        一旦父类写了一个有参构造器,默认的无参构造器没有了,就会报错——解决——在子类构造器中手写出super(),指定去调用父类的有参构造器。如:super("好的");

多态
1.什么是多态

 注意:对于  对象和行为 ,编译看左边,运行看右边

            对于  变量,编译和运行都看左边

2.多态的好处

1.可以实现解耦合,右边对象可以随时切换,后续的业务不用在变

2.可以使用父类类型的变量作为形参,接受一切子类对象

 但是,多态会产生一个问题——>多态下不能使用子类的独有功能

解决:

4.main方法,代码块

代码块

静态代码块指会在类加载阶段执行一次,并且只执行一次,不管你创建不创建对象;

实例代码块意味着,每次new 一个对象就会执行一次 

5.枚举,注解

枚举

 想要获取枚举类中的枚举项,只需要用类名调用就可以了

public class Test{
    public static void main(String[] args){
        //获取枚举A类的,枚举项
        A a1 = A.X;
        A a2 = A.Y;
        A a3 = A.Z;
    }
}

6.String    (不可变 字符串)


	java.lang包下的类,作用是字符串类型,可以用来处理字符串数据

	String如何创建对象,封装字符串数据呢?
		方式一:直接使用“ ....” 的方式得到字符串对象(推荐的方式。)
			String name = "黑马";
		方式二:通过构造器初始化字符串对象。
			

	String提供了哪些方法,对字符串进行处理?
		public class StringDemo2 {
            public static void main(String[] args) {
            // 目标:快速熟悉String提供的处理字符串的常用方法。
            String name = "ab黑马666";

            // 1、获取字符串的长度(字符个数)
            System.out.println(name.length()); // 7

            // 2、提取字符串中某个索引位置处的字符
            System.out.println(name.charAt(0));
            System.out.println(name.charAt(1));
            System.out.println(name.charAt(2));

            // 字符串的遍历。
            String name2 = "我爱你中国abc";
            //              0 1 23 4567
            for (int i = 0; i < name2.length(); i++) {
                // i = 0 1 2 3  4 5 6 7
                char ch = name2.charAt(i);
                System.out.println(ch);
            }
    
             // 3、把字符串转换成字符数组,再进行遍历
            System.out.println("----------------------------------------");
            char[] chars = name2.toCharArray();
            // chars = [我,爱,你,中,国,a, b, c]
            for (int i = 0; i < chars.length; i++) {
                char ch = chars[i];
                System.out.println(ch);
            }

            // 4、判断字符串内容,内容一样就返回true
            String s1 = "黑马";
            String s2 = new String("黑马");
            System.out.println(s1 == s2); // 比较地址
            System.out.println(s1.equals(s2)); // 比较内容

            // 5、忽略大小写比较字符串内容
            String s3 = "ab2Fg";
            String s4 = "AB2FG";
            System.out.println(s3.equals(s4)); // false .精准比较内容
            System.out.println(s3.equalsIgnoreCase(s4)); // true .忽略大小写比较字符串内容

            // 6、截取字符串内容 (包前不包后的)
            String s5 = "Java是最牛逼的编程语言之一";
            String result = s5.substring(0,9);
            System.out.println(result);

            // 7、从当前索引位置一直截取到字符串的末尾
            String result2 = s5.substring(5);
            System.out.println(result2);

            // 8、把字符串中的某个内容替换成新内容,并返回新的字符串对象给我们
            String s6 = "这个游戏简直是个垃圾,垃圾游戏!!,好垃圾!!,我打的都很垃圾~~~";
            String result3 = s6.replaceAll("垃圾", "**");
            System.out.println(result3);

            // 9、判断字符串中是否包含某个关键字
            String s7 = "黑马Java磊哥";
            System.out.println(s7.contains("Java")); // true
            System.out.println(s7.contains("java")); // false
            System.out.println(s7.contains("黑马Java2")); // false

            // 10、判断字符串是否以某个字符串开头。
            // startsWith 判断是否以什么内容开头
            System.out.println(s7.startsWith("黑马Java")); // true
            System.out.println(s7.startsWith("马Java")); // false

            // endsWith 判断是否以什么内容结尾
            System.out.println(s7.endsWith("磊哥")); // true
            System.out.println(s7.endsWith("ava磊哥"));// true
            System.out.println(s7.endsWith("磊哥2"));// false


            // 11、把字符串按照某个指定内容分割成多个字符串,
            // 放到一个字符串数组中返回给我们。
            String s8 = "高叶,杨超越,古力娜扎";
            String[] names = s8.split(",");
            for (int i = 0; i < names.length; i++) {
                System.out.println(names[i]);
            }
        }
}
	

String的注意事项1:
       1. String的对象是不可变字符串对象
  static      2.“...”给出的字符串对象,放在常量池,且相同内容的字符串对象在常量池中只有一份。
       3.new 出来的字符串对象,是直接放在堆内存中,每new一次都会产生一个新的字符串对象

 String的注意事项2:
        对于8种基本数据类型的变量,建议使用 == 进行相等判断
        对于两个字符串对象的比较,建议使用equals进行比较,只关心内容一样,就返回true. 

7.static关键字

static是静态的意思,可以修饰成员变量,可以修饰成员方法


    static修饰成员变量
        1. 静态成员变量
            有static修饰,属于类,与类一起加载,内存中只有一份,可以被共享访问。
            什么时候用呢? 如果信息要被共享,只需要一份就用,比如:系统在线人数。
            访问规则:
                建议用类名访问:类名.静态成员变量
                注意:同一个类中,访问静态成员可以省略类名不写。
                还可以这样访问:对象名.静态成员变量(不推荐)
        2.实例成员变量
            无static修饰,属于对象,每个对象中都存在一份实例成员变量。比如:name age
            什么时候用呢?比如:name age,每个对象中都有这些信息,而且信息还不同时,定义成实例成员变量。
            访问规则:
                只能用:对象名.实例成员变量
    static修饰成员方法
        1.静态成员方法
            有static修饰,属于类,与类一起加载,可以被共享访问
            什么时候用呢?如果是做一个通用功能。
            访问规则:
                建议用类名访问:类名.静态方法
                注意:同一个类中,访问静态成员可以省略类名不写。
                也可以这样访问:对象名.静态成员方法(不推荐)
       2. 实例成员方法
            无static修饰,属于对象,必须用对象触发访问。
            什么时候用呢?如果这个方法属于对象,而且要直接访问对象的实例成员,则申明成实例方法。
            访问规则:
            只能用:对象名.实例成员方法。

8.方法重载,方法重写

 方法重写

 方法重写的常见应用:

               子类重写Object类的toString()方法,以便返回对象的内容。

9.抽象类

- 被abstract修饰的类,就是抽象类
- 被abstract修饰的方法,就是抽象方法(不允许有方法体

//abstract修饰类,这个类就是抽象类
public abstract class A{
    //abstract修饰方法,这个方法就是抽象方法
    public abstract void test();
}

 类该有的成员(成员变量、成员方法、构造器),抽象类都可以有

抽象类是不能创建对象的,如果抽象类的对象就会报错

抽象类虽然不能创建对象,但是它可以作为父类让子类继承。而且子类继承父类必须重写父类的所有抽象方法。

子类继承父类如果不想重写父类的抽象方法,要想不出错,这个子类也必须是抽象类,这个时候就可以不重写父类的抽象方法

抽象类的好处

父类知道子类都要做某个行为,子类做的情况都不一样,就可以将其弄为抽象方法,让子类去重写实现。(更似于多态)

10.接口

Java提供了一个关键字interface,用这个关键字来定义接口这种特殊结构。格式如下

public interface 接口名{
    //成员变量(视为   常量)
    //成员方法(视为   抽象方法)
}
public interface A{
    //这里public static final可以加,可以不加。
    public static final String SCHOOL_NAME = "黑马";
    
    //这里的public abstract可以加,可以不加。
    public abstract void test();
}

因为成员方法视为抽象方法,所以接口不能创建对象 。

注意:

  • 接口是用来 被类 实现(implements)的,我们称之为实现类。

  • 一个类是可以实现多个接口的(接口可以理解成干爹),类实现接口必须重写所有接口的全部抽象方法,否则这个类也必须是抽象类

 好处
  • 弥补了类单继承的不足,一个类同时可以实现多个接口。

  • 让程序可以面向接口编程,这样程序员可以灵活方便的切换各种业务实现。

综合案例:班级学生信息管理模块的开发

学生的信息有:名字,年龄,分数

开发功能:打印全班学生的信息;全班学生的平均成绩

学生类:

package com.zkl.interface1;

public class Student {
    private String name;
    private double score;
    private int age;

    public Student() {
    }

    public Student(String name, double score, int age) {
        this.name = name;
        this.score = score;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

班级管理类:

package com.zkl.interface1;

import java.util.ArrayList;

public class ClassManager {//班级管理类
    private ArrayList<Student> students =  new ArrayList<Student>();//集合容器
    private Operator operator = new Operatorimpl1();

    public ClassManager(){
        students.add(new Student("热巴",90,20));
        students.add(new Student("丽影",100,18));
        students.add(new Student("杨幂",93,25));
        students.add(new Student("宋祖儿",94,18));
    }
    //打印所有信息
    public void PrintAllInfo(){
        operator.printAllInfo(students);
    }

    //打印全班学生的平均分
    public  void  PrintScore(){
        operator.printScore(students);
    }
}

 接口:表示学生信息管理系统的两个功能。

package com.zkl.interface1;

import java.util.ArrayList;

public interface Operator {
    void printAllInfo(ArrayList<Student> students);
    void printScore(ArrayList<Student> students);
}

接口实现类:

package com.zkl.interface1;

import java.util.ArrayList;

public class Operatorimpl1 implements Operator{

    @Override
    public void printAllInfo(ArrayList<Student> students) {
        System.out.println("--------------全班学生信息---------------");
        for (int i = 0; i < students.size(); i++) {
            Student s = students.get(i);
            System.out.println("学生姓名:"+ s.getName()+"分数: " + s.getScore()+ "年龄"+s.getAge());
        }
        System.out.println("----------------------------------");
    }

    @Override
    public void printScore(ArrayList<Student> students) {
        double AllScore = 0.0;
        for (int i = 0; i < students.size(); i++) {
            Student s = students.get(i);
            AllScore += s.getScore();
        }
        double AverageScore = AllScore / students.size();
        System.out.println("平均分=" +AverageScore);
    }
}

测试类:

package com.zkl.interface1;

public class Test {
    public static void main(String[] args) {
        // 目标:完成班级学生信息管理的案例。
        ClassManager clazz = new ClassManager();
        clazz.PrintAllInfo();
        clazz.PrintScore();
    }
}

11.内部类

内部类是类中的五大成分之一(成员变量、方法、构造器、内部类、代码块),如果一个类定义在另一个类的内部,这个类就是内部类。

当一个类的内部,包含一个完整的事物,且这个事物没有必要单独设计时,就可以把这个事物设计成内部类。

比如:汽车、的内部有发动机,发动机是包含在汽车内部的一个完整事物,可以把发动机设计成内部类。

public class Car{
    //内部类
    public class Engine{
        
    }
}

内部类有四种形式,分别是成员内部类、静态内部类、局部内部类、匿名内部类

1.成员内部类

成员内部类就是类中的一个普通成员,类似于成员变量、成员方法。

public class Outer {
    private int age = 99;
    public static String a="黑马";

    // 成员内部类
    public class Inner{
        private String name;
        private  int age = 88;

        //在内部类中既可以访问自己类的成员,也可以访问外部类的成员
        public void test(){
            System.out.println(age); //88
            System.out.println(a);   //黑马

            int age = 77;
            System.out.println(age); //77
            System.out.println(this.age); //88
            System.out.println(Outer.this.age); //99
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAge() {
            return age;
        }

        public void setAge(int age) {
            this.age = age;
        }
    }
}

 成员内部类如何创建对象

//外部类.内部类 变量名 = new 外部类().new 内部类();
Outer.Inner in = new Outer().new Inner();
//调用内部类的方法
in.test();

总结一下内部类访问成员的特点

  • 既可以访问内部类成员、也可以访问外部类成员

  • 如果内部类成员和外部类成员同名,可以使用类名.this.成员区分

2.匿名内部类

所谓匿名,指的是不需要为这个类声明名字

new 父类/接口(参数值){
    @Override
    重写父类/接口的方法;
}

匿名内部类本质上是一个没有名字的子类对象、或者接口的实现类对象  

(并没有创建子类对象,但是new后面跟的是其父类,事实上编译后系统会自动为匿名内部类生产字节码 ,类名会继承父类)

作用:简化了创建子类对象、实现类对象的书写格式。

应用场景:只有在调用方法时,当方法的形参是一个接口或者抽象类,为了简化代码书写,而直接传递匿名内部类对象给方法。

3.局部内部类

局部内部类是定义在方法中的类,和局部变量一样,只能在方法中有效。所以局部内部类的局限性很强,一般在开发中是不会使用的。

public class Outer{
    public void test(){
        //局部内部类
        class Inner{
            public void show(){
                System.out.println("Inner...show");
            }
        }
        
        //局部内部类只能在方法中创建对象,并使用
        Inner in = new Inner();
        in.show();
    }
}
4.静态内部类

就是在成员内部类的前面加了一个static关键字。

静态内部类属于外部类自己持有,静态内部类创建对象时,需要使用外部类的类名调用。

public class Outer {
    private int age = 99;
    public static String schoolName="黑马";

    // 静态内部类
    public static class Inner{
        //静态内部类访问外部类的静态变量,是可以的;
        //静态内部类访问外部类的实例变量,是不行的
        public void test(){
            System.out.println(schoolName); //99
            //System.out.println(age);   //报错
        }
    }
}
//格式:外部类.内部类 变量名 = new 外部类.内部类();
Outer.Inner in = new Outer.Inner();
in.test();

二.异常

三.常用API

1.1 Object类

Object类是Java中所有类的祖宗类,因此,Java中所有类的对象都可以直接使用Object类中提供的一些方法。

  • 4.1.1 toString()方法

public String toString()
    调用toString()方法可以返回对象的字符串表示形式。
    默认的格式是:“包名.类名@哈希值16进制”

假设有一个学生类如下

public class Student{
    private String name;
    private int age;
    
    public Student(String name, int age){
        this.name=name;
        this.age=age;
    }
}

再定义一个测试类

public class Test{
    public static void main(String[] args){
        Student s1 = new Student("赵敏",23);
        System.out.println(s1.toString()); 
    }
}

如果,在Student类重写toString()方法,那么我们可以返回对象的属性值,代码如下

public class Student{
    private String name;
    private int age;
    
    public Student(String name, int age){
        this.name=name;
        this.age=age;
    }
    
    @Override
    public String toString(){
        return "Student{name=‘"+name+"’, age="+age+"}";
    }
}

4.1.2 equals(Object o)方法


public boolean equals(Object o)
    判断此对象与参数对象是否"相等"

测试类,测试一下

public class Test{
    public static void main(String[] args){
        Student s1 = new Student("赵薇",23);
        Student s2 = new Student("赵薇",23);
        
        //equals本身也是比较对象的地址,和"=="没有区别
        System.out.println(s1.equals(s2)); //false
         //"=="比较对象的地址
        System.out.println(s1==s2); //false
    }
}

但是如果我们在Student类中,把equals方法重写了,就按照对象的属性值进行比较

public class Student{
    private String name;
    private int age;
    
    public Student(String name, int age){
        this.name=name;
        this.age=age;
    }
    
    @Override
    public String toString(){
        return "Student{name=‘"+name+"’, age="+age+"}";
    }
    
    //重写equals方法,按照对象的属性值进行比较
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
​
        Student student = (Student) o;
​
        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }
}

总结:

public String toString()
    返回对象的字符串表示形式。默认的格式是:“包名.类名@哈希值16进制”
    【子类重写后,返回对象的属性值】
    
public boolean equals(Object o)
    判断此对象与参数对象是否"相等"。默认比较对象的地址值,和"=="没有区别
    【子类重写后,比较对象的属性值】

4.1.3 clone() 方法

clone()方法,克隆。意思就是某一个对象调用这个方法,这个方法会复制一个一模一样的新对象,并返回。

public Object clone()
    克隆当前对象,返回一个新对象

想要调用clone()方法,必须让被克隆的类实现Cloneable接口。如我们准备克隆User类的对象,代码如下

public class User implements Cloneable{
    private String id; //编号
    private String username; //用户名
    private String password; //密码
    private double[] scores; //分数
​
    public User() {
    }
​
    public User(String id, String username, String password, double[] scores) {
        this.id = id;
        this.username = username;
        this.password = password;
        this.scores = scores;
    }
​
    //...get和set...方法自己加上
​
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

接着,我们写一个测试类,克隆User类的对象。并观察打印的结果

public class Test {
    public static void main(String[] args) throws CloneNotSupportedException {
        User u1 = new User(1,"zhangsan","wo666",new double[]{99.0,99.5});
        //调用方法克隆得到一个新对象
        User u2 = (User) u1.clone();
        System.out.println(u2.getId());
        System.out.println(u2.getUsername());
        System.out.println(u2.getPassword());
        System.out.println(u2.getScores()); 
    }
}

我们发现,克隆得到的对象u2它的属性值和原来u1对象的属性值是一样的。

上面演示的克隆方式,是一种浅克隆的方法,浅克隆的意思:拷贝出来的对象封装的数据与原对象封装的数据一模一样(引用类型拷贝的是地址值)

1.2 Objects类

Objects是一个工具类,提供了一些方法可以对任意对象进行操作。

下面写代码演示一下这几个方法

public class Test{
    public static void main(String[] args){
        String s1 = null;
        String s2 = "itheima";
        
        //这里会出现NullPointerException异常,调用者不能为null
        System.out.println(s1.equals(s2));
        //此时不会有NullPointerException异常,底层会自动先判断空
        System.out.println(Objects.equals(s1,s2));
        
        //判断对象是否为null,等价于==
        System.out.println(Objects.isNull(s1)); //true
        System.out.println(s1==null); //true
        
        //判断对象是否不为null,等价于!=
        System.out.println(Objects.nonNull(s2)); //true
        System.out.println(s2!=null); //true
    }
}

1.3 基本类型包装类

同学们,接下来我们学习一下包装类。为什么要学习包装类呢?因为在Java中有一句很经典的话,万物皆对象。Java中的8种基本数据类型还不是对象,所以要把它们变成对象,变成对象之后,可以提供一些方法对数据进行操作。

Java中8种基本数据类型都用一个包装类与之对一个,如下图所示

包装类,主要学习两点:

  • 创建包装类的对象方式、自动装箱和拆箱的特性;
  • 利用包装类提供的方法对字符串和基本类型数据进行相互转换

1.3.1 创建包装类对象

创建包装类对象的方法,以及包装类的一个特性叫自动装箱和自动拆箱。我们以Integer为例,其他的可以自己学,都是类似的。

//1.创建Integer对象,封装基本类型数据10
Integer a = new Integer(10);
​
//2.使用Integer类的静态方法valueOf(数据)
Integer b = Integer.valueOf(10);
​
//3.还有一种自动装箱的写法(意思就是自动将基本类型转换为引用类型)
Integer c = 10;
​
//4.有装箱肯定还有拆箱(意思就是自动将引用类型转换为基本类型)
int d = c;
​
//5.装箱和拆箱在使用集合时就有体现
ArrayList<Integer> list = new ArrayList<>();
//添加的元素是基本类型,实际上会自动装箱为Integer类型
list.add(100);
//获取元素时,会将Integer类型自动拆箱为int类型
int e = list.get(0);

1.3.2 包装类数据类型转换

在开发中,经常使用包装类对字符串和基本类型数据进行相互转换。

  • 把字符串转换为数值型数据:包装类.parseXxx(字符串)

public static int parseInt(String s)
    把字符串转换为基本数据类型
  • 将数值型数据转换为字符串:包装类.valueOf(数据);

public static String valueOf(int a)
    把基本类型数据转换为
  • 写一个测试类演示一下

//1.字符串转换为数值型数据
String ageStr = "29";
int age1 = Integer.parseInt(ageStr);
​
String scoreStr = 3.14;
double score = Double.prarseDouble(scoreStr);
​
//2.整数转换为字符串,以下几种方式都可以(挑中你喜欢的记一下)
Integer a = 23;
String s1 = Integer.toString(a);
String s2 = a.toString();
String s3 = a+"";
String s4 = String.valueOf(a);

2.1 Math类

Math是数学的意思,该类提供了很多个进行数学运算的方法,如求绝对值,求最大值,四舍五入等,话不多说,直接上代码。

public class MathTest {
    public static void main(String[] args) {
        // 目标:了解下Math类提供的常见方法。
        // 1、public static int abs(int a):取绝对值(拿到的结果一定是正数)
        //    public static double abs(double a)
        System.out.println(Math.abs(-12)); // 12
        System.out.println(Math.abs(123)); // 123
        System.out.println(Math.abs(-3.14)); // 3.14
​
        // 2、public static double ceil(double a): 向上取整
        System.out.println(Math.ceil(4.0000001)); // 5.0
        System.out.println(Math.ceil(4.0)); // 4.0
​
        // 3、public static double floor(double a): 向下取整
        System.out.println(Math.floor(4.999999)); // 4.0
        System.out.println(Math.floor(4.0)); // 4.0
​
        // 4、public static long round(double a):四舍五入
        System.out.println(Math.round(3.4999)); // 3
        System.out.println(Math.round(3.50001)); // 4
​
        // 5、public static int max(int a, int b):取较大值
        //   public static int min(int a, int b):取较小值
        System.out.println(Math.max(10, 20)); // 20
        System.out.println(Math.min(10, 20)); // 10
​
        // 6、 public static double pow(double a, double b):取次方
        System.out.println(Math.pow(2, 3)); // 2的3次方   8.0
        System.out.println(Math.pow(3, 2)); // 3的2次方   9.0
​
        // 7、public static double random(): 取随机数 [0.0 , 1.0) (包前不包后)
        System.out.println(Math.random());
    }
}

2.2 System类

接下来,学习一个System类,这是系统类,提供了一些获取获取系统数据的方法。比如获取系统时间。

/**
 * 目标:了解下System类的常见方法。
 */
public class SystemTest {
    public static void main(String[] args) {
​
        // 1、public static void exit(int status):
        //   终止当前运行的Java虚拟机。
        //   该参数用作状态代码; 按照惯例,非零状态代码表示异常终止。
        System.exit(0); // 人为的终止虚拟机。(不要使用)
​
        // 2、public static long currentTimeMillis():
        //    获取当前系统的时间
        //    返回的是long类型的时间毫秒值:指的是从1970-1-1 0:0:0开始走到此刻的总的毫秒值,1s = 1000ms
        long time = System.currentTimeMillis();
        System.out.println(time);
​
        for (int i = 0; i < 1000000; i++) {
            System.out.println("输出了:" + i);
        }
​
        long time2 = System.currentTimeMillis();
        System.out.println((time2 - time) / 1000.0 + "s");
    }
}

2.2 Arrays类

2.1.1 Arrays基本使用

我们先认识一下Arrays是干什么用的,Arrays是操作数组的工具类,它可以很方便的对数组中的元素进行遍历、拷贝、排序等操作。

下面我们用代码来演示一下:遍历、拷贝、排序等操作。需要用到的方法如下

/**
 * 目标:掌握Arrays类的常用方法。
 */
public class ArraysTest1 {
    public static void main(String[] args) {
        // 1、public static String toString(类型[] arr): 返回数组的内容
        int[] arr = {10, 20, 30, 40, 50, 60};
        System.out.println(Arrays.toString(arr));
​
        // 2、public static 类型[] copyOfRange(类型[] arr, 起始索引, 结束索引) :拷贝数组(指定范围,包前不包后)
        int[] arr2 = Arrays.copyOfRange(arr, 1, 4);
        System.out.println(Arrays.toString(arr2));
​
        // 3、public static copyOf(类型[] arr, int newLength):拷贝数组,可以指定新数组的长度。
        int[] arr3 = Arrays.copyOf(arr, 10);
        System.out.println(Arrays.toString(arr3));
​
        // 4、public static setAll(double[] array, IntToDoubleFunction generator):把数组中的原数据改为新数据又存进去。
        double[] prices = {99.8, 128, 100};
        //                  0     1    2
        // 把所有的价格都打八折,然后又存进去。
        Arrays.setAll(prices, new IntToDoubleFunction() {
            @Override
            public double applyAsDouble(int value) {
                // value = 0  1  2
                return prices[value] * 0.8;
            }
        });
        System.out.println(Arrays.toString(prices));
​
        // 5、public static void sort(类型[] arr):对数组进行排序(默认是升序排序)
        Arrays.sort(prices);
        System.out.println(Arrays.toString(prices));
    }
}

2.1.2 Arrays操作对象数组

刚才我们使用Arrays操作数组时,数组中存储存储的元素是int类型、double类型,是可以直接排序的,而且默认是升序排列。

如果数组中存储的元素类型是自定义的对象,如何排序呢?接下来,我们就学习一下Arrays如何对对象数组进行排序。

首先我们要准备一个Student类,代码如下:

public class Student implements Comparable<Student>{
    private String name;
    private double height;
    private int age;
    
    public Student(String name, double height, int age) {
        this.name = name;
        this.height = height;
        this.age = age;
    }
​
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", age=" + age +
                '}';
    }
}
​

然后再写一个测试类,往数组中存储4个学生对象,代码如下。此时,运行代码你会发现是会报错的。

public class ArraysTest2 {
    public static void main(String[] args) {
        // 目标:掌握如何对数组中的对象进行排序。
        Student[] students = new Student[4];
        students[0] = new Student("蜘蛛精", 169.5, 23);
        students[1] = new Student("紫霞", 163.8, 26);
        students[2] = new Student("紫霞", 163.8, 26);
        students[3] = new Student("至尊宝", 167.5, 24);
​
        // 1、public static void sort(类型[] arr):对数组进行排序。
        Arrays.sort(students);
        System.out.println(Arrays.toString(students));
    }
}

上面的代码为什么会报错呢?因为Arrays根本就不知道按照什么规则进行排序。为了让Arrays知道按照什么规则排序,我们有如下的两种办法。

  • 排序方式1:让Student类实现Comparable接口,同时重写compareTo方法。Arrays的sort方法底层会根据compareTo方法的返回值是正数、负数、还是0来确定谁大、谁小、谁相等。代码如下:

public class Student implements Comparable<Student>{
    private String name;
    private double height;
    private int age;
    
    //...get、set、空参数构造方法、有参数构造方法...自己补全
​
    // 指定比较规则
    // this  o
    @Override
    public int compareTo(Student o) {
        // 约定1:认为左边对象 大于 右边对象 请您返回正整数
        // 约定2:认为左边对象 小于 右边对象 请您返回负整数
        // 约定3:认为左边对象 等于 右边对象 请您一定返回0
        /* if(this.age > o.age){
            return 1;
        }else if(this.age < o.age){
            return -1;
        }
        return 0;*/
​
        //上面的if语句,也可以简化为下面的一行代码
        return this.age - o.age; // 按照年龄升序排列
        // return o.age - this.age; // 按照年龄降序排列
    }
    
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", age=" + age +
                '}';
    }
}
  • 排序方式2:在调用Arrays.sort(数组,Comparator比较器);时,除了传递数组之外,传递一个Comparator比较器对象。Arrays的sort方法底层会根据Comparator比较器对象的compare方法方法的返回值是正数、负数、还是0来确定谁大、谁小、谁相等。代码如下

public class ArraysTest2 {
    public static void main(String[] args) {
        // 目标:掌握如何对数组中的对象进行排序。
        Student[] students = new Student[4];
        students[0] = new Student("蜘蛛精", 169.5, 23);
        students[1] = new Student("紫霞", 163.8, 26);
        students[2] = new Student("紫霞", 163.8, 26);
        students[3] = new Student("至尊宝", 167.5, 24);
​
        // 2、public static <T> void sort(T[] arr, Comparator<? super T> c)
        // 参数一:需要排序的数组
        // 参数二:Comparator比较器对象(用来制定对象的比较规则)
        Arrays.sort(students, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                // 制定比较规则了:左边对象 o1   右边对象 o2
                // 约定1:认为左边对象 大于 右边对象 请您返回正整数
                // 约定2:认为左边对象 小于 右边对象 请您返回负整数
                // 约定3:认为左边对象 等于 右边对象 请您一定返回0
//                if(o1.getHeight() > o2.getHeight()){
//                    return 1;
//                }else if(o1.getHeight() < o2.getHeight()){
//                    return -1;
//                }
//                return 0; // 升序
                 return Double.compare(o1.getHeight(), o2.getHeight()); // 升序
                // return Double.compare(o2.getHeight(), o1.getHeight()); // 降序
            }
        });
        System.out.println(Arrays.toString(students));
    }
}

                       

四.集合

1.特点:  它是一种容器,用来存储数据;

                与数组不同,集合大小是可变的

2.学习要点:创建容器对象的方法,

                     增删改查的 方法

                     容器的其他特点

1.ArrayList

        创建ArrayLlst集合的对象:

ArrayList list = new ArrayList();

         增删改查的方法:

总结 

五.泛型

六.IO流

  1. 文件的概念,常用操作
  2. 原理,分类
  3. 节点流和处理流
  4. 输入流
  5. 输出流

七.线程

  1. 并发,并行,生命周期
  2. 线程的两种创建方式
  3. 线程同步
  4. 线程通信
  5. 线程池

八.网络通信

  1. 网络基础

  2. InetAddress

  3. Socket

  4. TCP编程

  5. UDP编程

九.反射

十.Mysql基础

特殊文本文件

1.xml文件
2.properties文件
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值