Java的基本使用之核心类

1、StringBuilder类

在 Java 中,我们可以使用 + 来拼接字符串,类似于下面的代码:

String s = "";
for (int i = 0; i < 1000; i++) {
    s = s + "," + i;
}

但是在每次循环中都会创建新的字符串对象(因为字符串是不可变的),然后扔掉旧的字符串。这样,绝大部分字符串都是临时对象,不但浪费内存,还会影响GC效率。

为了能高效拼接字符串,Java标准库提供了StringBuilder,它是一个可变对象,可以预分配缓冲区,这样,往StringBuilder中新增字符时,不会创建新的临时对象:

StringBuilder sb = new StringBuilder(1024);
for (int i = 0; i < 1000; i++) {
    //StringBuilder可以进行链式操作
    sb.append(',').append(i);
}
String s = sb.toString();

对于一般的字符串操作,我们可以不必将其改写为 StringBuilder,在对字符串进行频繁的插入、删除等操作时可以将其改写成 StringBuilder。

 

2、JavaBean

JavaBean 是一种符合命名规范的 class,也就是说,只要符合这些命名规范的类,都可以称之为 JavaBean。

JavaBean 的命名规范:

  1. JavaBean 类必须是一个公共类,即访问修饰符为 public
  2. JavaBean 类必须有一个空的构造函数,类中必须有一个无参的public构造方法
  3. JavaBean类不应有公共实例变量,类变量都应该是 private
  4. 属性(注意,不是成员变量,属性指的是getter或者setter方法名后面的属性名,比如getName,属性即为name)应该由一组读写方法(getXxx 和 setXxx)来访问,一个 JavaBean 对象的属性可以是可读写、或只读、或只写。可以用IDE (Eclipse、IntelliJ IDEA) 来为属性自动生成 getter / setter 方法。(如果操作的字段为boolean类型,此时的读方法不应该命名为 getter 方法,而是 is 方法,例如把 getName 变成 isName)

比如:

public class Person {
    private String age;
    private boolean man;  

    public String getAge() { return this.age; }
    public void setAge(String age) { this.age= age; }

    public boolean isMan(){};    // 读方法
    public void setMan(boolean value){}  // 写方法

    //属性只需要定义getter和setter方法,不是一定需要有对应的字段即成员变量。比如这个类中就没有下面对应的child字段
    public boolean isChild() {
        return age <= 6;
    }
}

我们通常把一组对应的读方法(getter)和写方法(setter)称为属性,例如,name属性:

  • 对应的读方法是String getName()
  • 对应的写方法是setName(String)

只有getter的属性称为只读属性,只有setter的属性称为只写属性,很明显,只读属性很常见,只写属性不常见。

 

3、枚举类(enum)

3.1、枚举类介绍

枚举类说明:

  • 枚举类的对象是确定的,只有有限个。例如,如果把季节定义成类,那么这个类只有四个对象:春夏秋冬。此时就能把季节定义为一个枚举类,这个枚举类的对象是确定的并且只有有限个。
  • 当需要定义一组常量时,强烈建议使用枚举类。
  • 如果枚举类只有一个对象,则可以作为一种单例模式的实现方式。

枚举类的举例:

  • 季节:春,夏,秋,冬
  • 线程的状态:创建、就绪、运行、阻塞、死亡

枚举类中的每个枚举都是单例模式,枚举类中的实例对象是有限且固定的。

 

3.2、定义枚举类

在JDK 5.0之前,需要我们自定义枚举类。

//自定义枚举类
class Season{
    //1.声明Season对象的属性:private final修饰
    private final String seasonName;
    private final String seasonDesc;
 
    //2.私有化类的构造器,并给对象属性赋值
    private Season(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }
 
    //3.提供当前枚举类的多个对象:public static final修饰
    public static final Season SPRING = new Season("春天","春天来了");
    public static final Season SUMMER = new Season("夏天","夏天来了");
    public static final Season AUTUMN = new Season("秋天","秋天来了");
    public static final Season WINTER = new Season("冬天","冰天来了");
}

 

从JDK5.0 开始可以使用enum关键字来定义枚举类,简化书写过程。

package test;

//使用enum关键字枚举类
public enum Season {
    //1.提供当前枚举类的对象,多个对象之间用","隔开,末尾对象";"结束
    SPRING("春天","春天来了"),
    SUMMER("夏天","夏天来了"),
    AUTUMN("秋天","秋天来了"),
    WINTER("冬天","冰天来了");

    //2.声明Season对象的属性:private final修饰
    private final String seasonName;
    private final String seasonDesc;

    //3.私化类的构造器,并给对象属性赋值
    private Season(String seasonName,String seasonDesc){
        this.seasonName = seasonName;
        this.seasonDesc = seasonDesc;
    }

    //4.其他需求:根据需要定义
    public String getSeasonName() {
        return seasonName;
    }
    public String getSeasonDesc() {
        return seasonDesc;
    }

    //其他诉求1:提供toString()
    @Override
    public String toString() {
        return "Season{" +
                "seasonName='" + seasonName + '\'' +
                ", seasonDesc='" + seasonDesc + '\'' +
                '}';
    }
}

 

使用枚举类时,通过 枚举类名.常量名 来使用,此时得到的是枚举类的实例对象,可以通过访问该类的成员方法来获取相应的数据。

package test;

public class Test02 {
    public static void main(String[] args) {
        Season spring = Season.SPRING;
        System.out.println(spring); //Season{seasonName='春天', seasonDesc='春暖花开'}

        String seasonStr = Season.SUMMER.getSeasonName();
        String seasonDesc = Season.SUMMER.getSeasonDesc();

        System.out.println(seasonStr + "  " + seasonDesc);  // 夏天  夏天来了
    }
}

 

3.3、枚举类的特点

通过enum定义的枚举类,和其他的class没有任何区别,enum定义的类型就是class
  • 使用enum关键字定义的枚举类默认继承了java.lang.Enum类,由于Java的单继承性,不能再继承其他类。
  • 必须要在第一行声明枚举类的对象,否则会报错。
  • 从JDK5.0 开始Java的 switch语句可以把使用enum定义的枚举类的对象作为表达式,并且case只能直接使用枚举类对象名,不能加类名限定。如下:
package test;

public class Test02 {
    public static void main(String[] args) {
        Season sea = Season.SPRING;
        switch (sea){
            case Season.SPRING://这里编译会报错,应该直接使用 SPRING
                System.out.println(111);
                break;
            case SUMMER:
                System.out.println(222);
                break;
            case AUTUMN:
                break;
            case WINTER:
                break;
        }
    }
}

 使用enum定义的枚举类是一种引用类型,引用类型比较,要始终使用equals()方法,但enum类型可以例外。这是因为enum类型的每个常量在JVM中只有一个唯一实例,所以可以直接用==比较

 

3.4、枚举类的主要方法

  • values()方法:将枚举类的所有对象以数组形式返回,利用此方法可以方便地遍历枚举类的值。
  • valueOf(String name)方法:返回枚举类中对象名为name的对象。若没有,则抛出IllegalArgumentException的异常。
  • toString()方法:返回枚举类对象的名称
package test;

public class Test02 {
    public static void main(String[] args) {
        Season summer = Season.SUMMER;
        //toString():返回枚举类对象的名称
        System.out.println(summer.toString());

        //values():返回所的枚举类对象构成的数组
        Season[] values = Season.values();
        for(int i = 0;i < values.length;i++){
            System.out.println(values[i]);
        }

        //valueOf(String objName):返回枚举类中对象名是objName的对象。
        Season winter = Season.valueOf("WINTER");
        //如果没objName的枚举类对象,则抛异常:IllegalArgumentException
        Season winter1 = Season.valueOf("WINTER1");
        System.out.println(winter1);
    }
}

输出结果如下:

 

3.5、枚举值的其他方法

因为enum是一个class,每个枚举的值都是class实例,因此,这些实例有一些方法,如下:

name()方法 返回常量名

String s = Weekday.SUN.name(); // "SUN"

 

ordinal()返回定义的常量的顺序,从0开始计数

int n = Weekday.MON.ordinal(); // 1

但是改变枚举常量的顺序就会导致ordinal()返回值发生变化。

 

因为enum本身是class,所以我们可以定义private的构造方法,并且,给每个枚举常量添加字段:

public class Main {
    public static void main(String[] args) {
        Weekday day = Weekday.SUN;
        if (day.dayValue == 6 || day.dayValue == 0) {
            System.out.println("Work at home!");   //输出 Work at home!
        } else {
            System.out.println("Work at office!");
        }
    }
}

enum Weekday {
    MON(1), TUE(2), WED(3), THU(4), FRI(5), SAT(6), SUN(0);

    public final int dayValue;

    private Weekday(int dayValue) {
        this.dayValue = dayValue;
    }
}

这样就无需担心顺序的变化,新增枚举常量时,也需要指定一个int值。

给枚举类添加的字段也可以是非final类型,即让该字段可以在使用时被修改,但是不推荐这样做!

 

posted @ 2020-01-09 16:50  wenxuehai  阅读(461)  评论(0编辑  收藏  举报
//右下角添加目录