美文网首页
Java入门系列06 -- 枚举,包装类,Math常见计算,字符

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

作者: YanZi_33 | 来源:发表于2021-11-10 17:36 被阅读0次

    枚举类型

    • 如果一个变量的取值只可能是固定的几个值,可以考虑使用枚举类型;
      • 枚举是由一组预定义的常量构成;
    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

    相关文章

      网友评论

          本文标题:Java入门系列06 -- 枚举,包装类,Math常见计算,字符

          本文链接:https://www.haomeiwen.com/subject/nsibzltx.html