Java入门系列06 -- 枚举,包装类,Math常见计算,字符串

枚举类型

  • 如果一个变量的取值只可能是固定的几个值,可以考虑使用枚举类型;
    • 枚举是由一组预定义的常量构成;
public enum  Season {
    SPRING,SUMMER,FALL,WINTER
}
import com.example.java_test.java.cls.Season;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Season season = Season.SPRING;
        Log.v("MainActivity",season.name());
        Log.v("MainActivity",String.valueOf(season.ordinal()));

        switch (season) {
            case SPRING:
                Log.v("MainActivity","春天");
                break;
            case SUMMER:
                Log.v("MainActivity","夏天");
                break;
            case FALL:
                Log.v("MainActivity","秋天");
                break;
            case WINTER:
                Log.v("MainActivity","冬天");
                break;
        }
    }
}
  • 枚举的本质是类,所有枚举类型最终都隐式继承自java.lang.Enum
  • 枚举定义完常量后,可以再定义成员变量,方法等内容(这时最后一个常量要以分号结束);
  • 枚举的构造方法权限必须是无修饰符 或者 private
    • Java会主动调用构造方法初始化每一个常量,你不能主动调用构造方法;
public enum  Season {
    SPRING,SUMMER,FALL,WINTER;

    private int age;
    private String str;

    Season() {

    }

    void test() {

    }
}
自定义构造方法的枚举
public enum  Season {
    SPING(5,15),
    SUMMER(5,15),
    FALL(5,15),
    WINTER(5,15);

    //温度
    private int min;
    private int max;
    //自定义构造方法 私有
    Season(int min,int max) {
        this.min = min;
        this.max = max;
    }

    public int getMin() {
        return min;
    }

    public int getMax() {
        return max;
    }
}
  • 自定义构造方法 私有,不准外界调用;

基本数据类型的缺陷

  • 对比引用类型,基本数据类型存在一些缺陷;
    • 无法表示不存在的值(null值);
    • 不能利用面向对象的方式去操作基本数据类型,比如直接调用基本数据类型调用方法;
    • 当方法参数是引用类型时,基本类型无法传递;
  • 解决方案:可以自己将基本数据类型包装成引用类型;
  • 案例:自定义包装int的类IntObject
public class IntObject {

    public int value;
    public IntObject(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

包装类

  • 在Java中已经内置了基本数据类型的包装类,都在java.lang包中;
    • 其中数字类型的包装类最终都继承自java.lang.Number
image.png
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
       
        Integer num2 = Integer.valueOf(100);
        Integer num3 = new Integer(100);
    }
}

自动装箱,拆箱

  • 自动装箱:Java编译器会自动调用xxx.vauleOf方法,将基本数据类型转换成包装类;
  • 自动拆箱:Java编译器会自动调用xxxValue方法,将包装类转换为基本类型;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //自动装箱 将100 自动转成 Integer
        Integer num1 = 100;
        Integer num2 = Integer.valueOf(100);
        Integer num3 = new Integer(100);

        //自动拆箱 将Integer 自动转成 int
        int num4 = num1;
    }
}

包装类的判等

  • 使用equals:判断的是引用所指向的内容是否相等;
  • 使用==:判断的是引用的值,即所指向的对象的内存地址是否相等;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Integer num1 = 100;
        Integer num2 = 100;
        Integer num3 = 888;
        Integer num4 = 888;

        //不推荐
        System.out.println(num1 == num2); //true
        System.out.println(num3 == num4); //false

        //推荐
        System.out.println(num1.equals(num2)); //true
        System.out.println(num3.equals(num4)); //true
    }
}
  • System.out.println(num3 == num4) 返回false,主要是因为 Integer内部有个缓存IntegerCache,当数字在(-127,128)之间的Integer会被IntegerCache缓存下来,所以num1 = 88会被缓存下来,num2直接从缓存中取出,num3 =888,超出范围不会缓存;

  • 基本类型数组包装类数组 之间是不能自动装箱,拆箱的;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        int[] num1 = {11,22};
        Integer[] num2 = num1; //报错
    }
}

Math

  • java.lang.Math类提供了常见的数学计算功能;
public static final double E = 2.7182818284590452354;
public static final double PI = 3.14159265358979323846;

 //绝对值
Math.abs(-100);
//最大值
Math.max(100,200);
//最小值
Math.min(100,200);
//4的2次方
Math.pow(4,2);
//向下取整
Math.floor(3.2);
//向上取整
Math.ceil(3.7);
//16的平方根
Math.sqrt(16);
//E的2次方
Math.exp(2);
//ln8
Math.log(8);
//角度转弧度
double degree = 90;
double radian = Math.toDegrees(degree);
//三角函数
Math.sin(radian);
Math.tan(radian);
//生成[0-1)之间的随机数
Math.random();
//生成各种随机数
Random r = new Random();
r.nextBoolean();
r.nextInt();
r.nextLong();
r.nextFloat();
  • 生成指定范围的随机数
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //生成[0,99]的整数
        int num1 = (int)(Math.random() * 100);
        int num2 = new Random().nextInt(100);

        //生成[10,99]的整数
        int num3 = (int)(Math.random() * 90) + 10;
        int num4 = new Random().nextInt(90) + 10;
    }
}
  • 随机生成4为大写字母
import java.util.Random;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //随机生成4维大写字母 A-Z ==> A + [0,25]
        for (int i = 0;i < 4;i++) {
            int c = 'A' + new Random().nextInt(26);
            System.out.println("MainActivity" + (char)c);
        }
    }
}

UUID

  • UUID:通用唯一标识符;
  • 其目的是让分布式系统中所有元素都能有唯一的标识符,而不需要通过中央控制端来做标识符的指定;
  • 可以利用java.lang.UUID 类的randomUUID方法生成一个128bit的随机UUID;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        System.out.println("MainActivity" + UUID.randomUUID());
    }
}

数字格式化

  • 可以使用System.out.printf或者System.out.format输出格式化的字符串;
  • 可以使用String.format创建格式化的字符串;
image.png
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        System.out.printf("my age is %d",10);
        String str = String.format("my age is %d",20);

        long n = 461012;
        System.out.format("%d%n",n); //"461012"
        System.out.format("%08d%n",n); //"00461012"
        System.out.format("%+8d%n",n); //"  +461012"
        System.out.format("%,8d%n",n); //" 461,012"
        System.out.format("%+,8d%n%n",n); //"+461,012"

        double pi = Math.PI;
        System.out.format("%f%n",pi); //"3.141593"
        System.out.format("%03f%n",pi); //"3.142"
        System.out.format("%8.3f%n",pi); //"    3.142"
        System.out.format("%08.3f%n",pi); //"0003.142"
        System.out.format("%-8.3ff%n",pi); //"3.142"
    }
}

DecimalFormat

  • 使用java.text.DecimalFormat可以更好的控制前0,后0,前缀,后缀,分组分隔符,十进制分隔符等;
import java.text.DecimalFormat;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //123,456.789
        customFormat("###,###.###",123456.789);
        //123456.79
        customFormat("###.##",123456.789);
        //00123.780
        customFormat("000000.000",123.78);
        //$12,345.67
        customFormat("$###,###.###",12345.67);
    }

    public static void customFormat(String pattern,double value) {
        DecimalFormat format = new DecimalFormat(pattern);
        System.out.println(format.format(value));
    }
}

字符串转数字

  • 使用包装类的valueOf,parseXX方法;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Integer num1 = Integer.valueOf("12");
        int num2 = Integer.parseInt("12");
        int num3 = Integer.parseInt("FF",16);

        Float f1 = Float.valueOf("12.34");
        float f2 = Float.parseFloat("12.34");
    }
}

数字转字符串

  • 使用字符串的valueOf方法,包装类的toString方法;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String str1 = String.valueOf(12.34);
        String str2 = Integer.toString(255);
        String str3 = Integer.toString(255,16);
        String str4 = Float.toString(12.34f);
    }
}

高精度计算

  • float,double存储的只是小数的近似值,并非精确值,因此不适合用来进行高精度计算;
  • 建议使用字符串初始化BigDecimal,因为float,double存储的是近似值,不是精确值;
import java.math.BigDecimal;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //不推荐
        float f = 0.7f;
        double d = 0.7f;
        System.out.println(0.7 * 0.7);

        //推荐做法
        BigDecimal d1 = new BigDecimal("0.7");
        BigDecimal d2 = new BigDecimal("0.7");
        System.out.println(d1.add(d2));  //加
        System.out.println(d1.subtract(d2)); //减
        System.out.println(d1.multiply(d2)); //乘
        System.out.println(d1.divide(d2)); //除
        System.out.println(d1.setScale(3)); //保留3位小数
    }
}

字符串

  • Java中用java.lang.String类代表字符串;
  • 底层使用char[] 存储字符数据,从Java9开始底层使用byte[] 存储字符数据;
  • 所有字符串的字面量(比如"abc"),都是String类的实例;
  • String对象一旦创建完毕,它的字符内容是不可以修改的;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String s = "555";
        s += "555";
        s = "666";
        test(s);
        System.out.println(s);
    }
    
    public static void test(String str) {
        str += "555";
    }
}
  • 内部布局如下:
image.png
  • 字符串的引用指向可以更改,但字符串本身的内容值不能更改;

字符串常量池(String Contant Pool)

  • Java中有个字符串常量池,简称SCP;
  • 从Java7开始属于堆空间的一部分,以前放在方法区;
  • 当遇到字符串字面量时,会去查看字符串常量池;
    • 如果字符串常量池中存在与字面量内容一样的字符串对象A时,就返回A;
    • 否则,创建一个新的字符串对象D,并加入到字符串常量池中,返回D;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String str1 = "yanzi";
        String str2 = "yanzi";
        System.out.println(str1 == str2); //true

        String s1 = "mj";
        String s2 = new String("mj");
        String s3 = new String(s2);
        String s4 = new String(s2);
        char[] cs = {'m','j'};
        String s5 = new String(cs);
        String s6 = new String(s5);
    }
}
  • 内部布局如下:
image.png
  • str1的字面量存入字符串常量池SCP中,
  • str2直接从SCP中取出,所以str1与str2指向的是同一个对象;
image.png
  • String s1 = "mj",直接将字面量mj存储SCP中;
  • String s2 = new String("mj"):创建一个新的字符串对象,其内容指向SCP中的mj;
  • char[] cs = {'m','j'}:创建一个char数组,存储了mj;
  • String s5 = new String(cs):会拷贝新的一份char数组;

intern方法

  • A.intern方法的作用:
    • 如果SCP中存在与A内容一样的字符串对象C时,就返回C;
    • 否则,将A加入到SCP中,返回A;
public class Main {

    public static void main(String[] args) {
        
        int a = 1,b = 2,c = 3;
        String s1 = String.format("%d%d%d", a,b,c);
        String s2 = String.format("%d%d%d", a,b,c);
        String s3 = s1.intern();
        String s4 = s2.intern();
        String s5 = "123";
        
        System.out.println(s1 == s2);//false
        System.out.println(s1 == s3);//true
        System.out.println(s1 == s4);//true
        System.out.println(s1 == s5);//true
    }
}
  • String s1 = String.format("%d%d%d", a,b,c):会创建新的字符串对象,所以s1与s2是两个字符串对象;
  • String s3 = s1.intern():会先去SCP中查找字符串abc,此时SCP中没有abc,那么会将abc放入SCP中;
  • String s4 = s2.intern():会先去SCP中查找字符串abc,此时SCP中存在abc,所以s3与s4指向的是同一个字符串对象;
  • String s5 = "123":也会先去SCP中查找字符串abc,与intern的执行逻辑等价,所以s1,s3,s4,s5都指向的是同一个字符串对象;
  • 断点调试结果如下:
image.png

字符串的常用方法

import javax.swing.AbstractCellEditor;

public class Main {

    public static void main(String[] args) {
        //去除左右空格: "123  3456"
        String str1 = " 123 3456  ".trim();
        //转为大写: "ABC"
        String str2 = "abc".toUpperCase();
        //转为小写: "abc"
        String str3 = "ABC".toLowerCase();
        //是否包含某个字符串:true
        boolean isContains = "123456".contains("23");
        //是否以某个字符串开头:true
        boolean isStart = "123456".startsWith("1");
        //是否以某个字符串结尾:true
        boolean isEnd = "123456".endsWith("6");
        //将字符串分割为数组:[1,2,3,4]
        String[] strs = "1_2_3_4".split("_");
        //字符串比较大小: < 0
        int result1 = "abc".compareTo("bbb");
        //字符串比较大小,忽略大小写: < 0
        int result2 = "abc".compareToIgnoreCase("ASS");
        
        //比较字符串内容是否相等
        String s1 = "abc";
        String s2 = new String("abc");
        s1.equals(s2);
        //比较字符串内容是否相等 忽略大小写
        "asd".equalsIgnoreCase("ASd");
        
        //字符串截取左闭右开[beginIndex,endIndex): 123
        String s3 = "yanzi123dd".substring(5,8);
        System.out.println(s3);
 
        //返回字符索引 从左到右
        int index1 = "12355".indexOf(2);
        //返回字符索引 从右到左
        int index2 = "asdfasf44trtr".lastIndexOf(4);
    }
}

StringBuilder

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,607评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,047评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,496评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,405评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,400评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,479评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,883评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,535评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,743评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,544评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,612评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,309评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,881评论 3 306
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,891评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,136评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,783评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,316评论 2 342

推荐阅读更多精彩内容