java面向对象随机数组_Java 面向对象(七)

枚举

枚举的引入(模拟枚举)

class Student {

private int restDay;

public int getRestDay() {

return restDay;

}

public void setRestDay(int restDay) {

this.restDay = restDay;

}

}

public class Test {

public static void main(String[] args) {

Student stu = new Student();

stu.setRestDay(1);

int res = stu.getRestDay();

if (res == 6 || res == 7) {

System.out.println("放假");

} else {

System.out.println("上课");

}

}

}

上面的代码,存在一些问题:

(1)数据不安全,输入8

stu.setRestDay(8);// 输出:上课(没有星期八)

(2)业务逻辑不合理:中外一周的第一天不一样,中国第一天是周一,外国第一天是周天。

改进后:

class WeekDay {

public static final int MONDAY = 1;

public static final int TUESDAY = 2;

public static final int WEDNESDAY = 3;

public static final int THURSDAY = 4;

public static final int FRIDAY = 5;

public static final int SATURDAY = 6;

public static final int SUNDAY = 7;

}

class Student {

private int restDay;

public int getRestDay() {

return restDay;

}

public void setRestDay(int restDay) {

this.restDay = restDay;

}

}

public class Test {

public static void main(String[] args) {

Student stu = new Student();

stu.setRestDay(WeekDay.MONDAY);

int res = stu.getRestDay();

if (res == 6 || res == 7) {

System.out.println("放假");

} else {

System.out.println("上课");

}

}

}

改进后的代码,还存在问题:

(1)数据不安全,输入8

stu.setRestDay(8);// 输出:上课(没有星期八)

再次改进:

class WeekDay {

private WeekDay() {}

public static final WeekDay MONDAY = new WeekDay();

public static final WeekDay TUESDAY = new WeekDay();

public static final WeekDay WEDNESDAY = new WeekDay();

public static final WeekDay THURSDAY = new WeekDay();

public static final WeekDay FRIDAY = new WeekDay();

public static final WeekDay SATURDAY = new WeekDay();

public static final WeekDay SUNDAY = new WeekDay();

}

class Student {

private WeekDay restDay;

public WeekDay getRestDay() {

return restDay;

}

public void setRestDay(WeekDay restDay) {

this.restDay = restDay;

}

}

public class Test {

public static void main(String[] args) {

Student stu = new Student();

stu.setRestDay(WeekDay.MONDAY);

WeekDay res = stu.getRestDay();

if (res == WeekDay.SATURDAY || res == WeekDay.SUNDAY) {

System.out.println("放假");

} else {

System.out.println("上课");

}

}

}

上面的代码,问题解决了,但是代码不好看,太冗余。

什么是枚举

枚举:表示一个事物固定状态。

比如:季节(春,夏,秋,冬)、星期(周一到周日)、性别(男,女)

枚举的定义

格式:

[修饰符] enum 枚举的名称 {

常量1,常量2,常量3……

}

比如:

enum Sex {

MAN, FEMALE

}

枚举的本质

java 枚举是一个语法糖。是一个特殊的类,是多个常量对象的集合。

当我们定义一个枚举后,它的本质还是一个类,一个继承了Enum的类。

enum Sex {

MAN, FEMALE

}

反编译后:

final class Sex extends Enum

{

public static final Sex MAN;

public static final Sex FEMALE;

private static final Sex ENUM$VALUES[];

private Sex(String s, int i)

{

super(s, i);

}

public static Sex[] values()

{

Sex asex[];

int i;

Sex asex1[];

System.arraycopy(asex = ENUM$VALUES, 0, asex1 = new Sex[i = asex.length], 0, i);

return asex1;

}

public static Sex valueOf(String s)

{

return (Sex)Enum.valueOf(Test/Sex, s);

}

static

{

MAN = new Sex("MAN", 0);

FEMALE = new Sex("FEMALE", 1);

ENUM$VALUES = (new Sex[] {

MAN, FEMALE

});

}

}

f1299154cca39f7e6e5722c4011c053c.png

70068b466a04bbebcca579e3bb57504d.png

程序 main 方法

public static void main(String[] args) {

}

当点击运行时,JVM自动会调用main方法。

public : 被JVM调用的方法,它的权限要足够的大。

static : 被JVM调用的方法,不需要创建对象,直接使用类名调用

void : 被JVM调用的方法,不需要有任何 的返回值。

main : 方法 的名称 ,只能这样写,不然JVM识别不了

String[] args : 以前是指键盘录入。

常用类之Scanner

Scanner类常用的场景为:

(1)控制台输入(等待从键盘录入一个数);

(2)字符串分割;

(3)文本整行读取。

控制台输入

输入八大基本数据类型

在输入之前最好先使用 hasNextXxx() 方法进行验证是否还有输入的数据,再使用 nextXxx() 来读取。

public static void main(String[] args) {

Scanner in = new Scanner(System.in);

if (in.hasNextInt()) {

System.out.println("请输入一个数:");

int input = in.nextInt();

System.out.println("input ==> " + input);

}

in.close();

}

这时候,我们可能希望的是:先输出“请输入一个数:”,然后我们就可以在控制台输入一个字符串或数字。

但是,事实却是:控制台要我们先输入,输入后才显示“请输入一个数:”。

61d84a8cc3dec35d6e2e8bb9b78e7767.png

个人理解如下:

首先,in.hasNextInt() 和 in.nextInt() 都可以用来输入。

in.hasNextInt()输入:

Scanner in = new Scanner(System.in);

boolean b = in.hasNextInt();// 输入1:12输入2:12.5

System.out.println(b);// 输出1:true输出2:false

in.hasNext:读取数据存储区,有下一个则返回布尔true,否则一直等待输入(不会返回false)

可设置终止符:hasNext(String patten),如果下一个标记与从指定字符串构造的模式匹配,则返回 true。

Scanner in = new Scanner(System.in);

boolean b = in.hasNext("0");// 输入1:0输入2:java

System.out.println(b);// 输出1:true输出2:false

in.nextInt()输入:

Scanner in = new Scanner(System.in);

int i = in.nextInt();// 输入1:12输入2:java

System.out.println(i);// 输出1:12输出2:抛异常

可以发现,hasNextXxx()返回的是boolean类型,而nextXxx()返回的是输入的那个值。

in.hasNextXxx()可以理解为: 从一段用于用户输入的内存(可以理解为in)当中扫描,

如果该内存中有值,判断是否符合类型。符合就返回true,不符合就返回false。

如果该内存中没有值,会阻塞,先从键盘读取一个值存到该内存中,在进行判断是否符合类型。

in.next()可以理解为:从一段用于用户输入的内存(可以理解为in)中取值,

如果该内存中有值,会先判断是否符合类型,如果符合直接取值,取值后将标识符后移(可以理解为:取完值后这个值就不在了),如果不符合会报异常;

如果该内存中没有值,会阻塞,先从键盘读取一个值存到该内存中,再取值(取值时也要判断是否符合类型)。

输入字符串

可以使用 next() 与 nextLine()。在输入之前也是最好先使用 hasNext() 方法进行验证是否还有输入的数据。

next() 与 nextLine() 区别

next():

1、一定要读取到有效字符后才可以结束输入。

2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。

3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。

注意:next() 不能得到带有空格的字符串。

nextLine():

1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。

2、可以获得空白。

字符串分割

public static void main(String[] args) {

String inputStr = "123 456,abc.def...张三|李四";

Scanner in = new Scanner(inputStr);

in.useDelimiter(" |,|\\.|\\|");

while(in.hasNext()){

String input = in.next();

System.out.println("input ==> " + input);

}

in.close();

}

文本整行读取

public static void main(String[] args) {

InputStream is = null;

try {

is = new FileInputStream(new File("D:\\Desktop\\Hello.txt"));

Scanner in = new Scanner(is);

while (in.hasNextLine()) {

String input = in.nextLine();

System.out.println("input ==> " + input);

}

in.close();

} catch (FileNotFoundException e) {

e.printStackTrace();

} finally {

try {

is.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

常用类之System(java.lang.System)

常用类主要说的是常用类当中常用的方法 (系统已经给我们提供了很多可以直接使用的方法)

常用类一般都不允许你创建对象。 一般都私有化了构造器。

java.lang 是不需要导入包的。

数组拷贝

public static void main(String[] args) {

int[] src = { 1, 2, 3, 4, 5, 6 };

int[] dest = new int[8];

/*

* 数组拷贝

* public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)

* src:源数组

* srcPos:源数组中的起始位置

* dest:目标数组

* destPos:目标数据中的起始位置

* length:要复制的数组元素的数量

*/

System.arraycopy(src, 2, dest, 2, 4);

// 数组打印

System.out.println(Arrays.toString(src));// [1, 2, 3, 4, 5, 6]

System.out.println(Arrays.toString(dest));// [0, 0, 3, 4, 5, 6, 0, 0]

}

返回以毫秒为单位的当前时间(用于计算代码耗时)

public static void main(String[] args) {

// 获取当前时间与 1970 年 1 月 1 日午夜之间的时间差(以毫秒为单位测量)。

long time1 = System.currentTimeMillis();

for (int i = 0; i < 100; i++) {

System.out.println(i);

}

long time2 = System.currentTimeMillis();

long time3 = time2 - time1;

System.out.println("总耗时:" + time3 + " ms");

}

终止当前正在运行的 Java 虚拟机

public static void exit(int status)

非 0 的状态码表示异常终止。

正常终止:

System.exit(0);

运行垃圾回收器

System.gc();

例子:

public class Test {

/**

* 当一个对象被垃圾回收时,自动调用的一个方法

*/

@Override

protected void finalize() throws Throwable {

super.finalize();

System.out.println("我被回收了");

}

public static void main(String[] args) {

new Test();

new Test();

/*

* 一个对象并不是立即被回收

* 执行gc,立即运行垃圾回收器

*/

System.gc();

}

}

常用类之Math(java.lang.Math)

java.lang 是不需要导入包的。

说明

方法

求绝对值

abs

求平方根

sqrt

求立方根

cbrt

求最大值

max

求最小值

min

求 n 次方

pow

随机数

random

三角函数

……

对数

……

指数

……

public static void main(String[] args) {

// abs : 求绝对值

int abs = Math.abs(-62);

System.out.println(abs);

// sqrt : 求平方根

double sqrt = Math.sqrt(4.0);

System.out.println(sqrt);

// cbrt : 求立方根

double cbrt = Math.cbrt(27);

System.out.println(cbrt);

// max : 求最大值

// min : 求最小值

int max = Math.max(6, 10);

double min = Math.min(6.0, 3.0);

System.out.println("max: " + max + ", min: " + min);

// pow : 求一个数的 n 次方

double pow = Math.pow(2, 3);

System.out.println(pow);

// random : 返回一个 [0,1) 的随机数

double random = Math.random();

System.out.println(random);

// 返回 [0,100) 的随机数

double random2 = Math.random() * 100;

System.out.println(random2);

// 返回 [0,100) 的随机整数

int random3 = (int)(Math.random() * 100);

System.out.println(random3);

}

大精度小数

先来看个例子:

// float double 表示小数,但是不能表示精确的小数

System.out.println("0.09 + 0.01 = " + (0.09 + 0.01));

System.out.println("1.0 - 0.33 = " + (1.0 - 0.33));

System.out.println("4.015 * 1000 = " + (4.015 * 1000));

System.out.println("12.3 / 100 = " + (12.3 / 100));

输出结果:

0.09 + 0.01 = 0.09999999999999999

1.0 - 0.33 = 0.6699999999999999

4.015 * 1000 = 4014.9999999999995

12.3 / 100 = 0.12300000000000001

这里结果精度差了点,如果用来表示金钱,问题就大了。

金钱对精度要求比较高,所以不用 float 和 double,用 BigDecimal

BigDecimal b1 = new BigDecimal(0.09);

BigDecimal b2 = new BigDecimal(0.01);

BigDecimal add = b1.add(b2);

System.out.println(add);

// 输出结果: 0.09999999999999999687749774324174723005853593349456787109375

发现结果精度更高了,但还不是我们想要的结果。这是构造器的原因:

public BigDecimal(double val):

(1)此构造方法的结果有一定的不可预知性。有人可能认为在 Java 中写入 new BigDecimal(0.1) 所创建的 BigDecimal 正好等于 0.1,但是它实际上等于 0.1000000000000000055511151231257827021181583404541015625。这是因为 0.1 无法准确地表示为 double(或者说对于该情况,不能表示为任何有限长度的二进制小数)。这样,传入到构造方法的值不会正好等于 0.1(虽然表面上等于该值)。

(2)另一方面,String 构造方法是完全可预知的:写入 new BigDecimal("0.1") 将创建一个 BigDecimal,它正好等于预期的 0.1。因此,比较而言,通常建议优先使用 String 构造方法。

BigDecimal b1 = new BigDecimal("0.09");

BigDecimal b2 = new BigDecimal("0.01");

BigDecimal add = b1.add(b2);

System.out.println(add);

// 输出结果: 0.10

BigDecimal 加减乘除:

public static void main(String[] args) {

double d1 = 0.09;

double d2 = 0.01;

BigDecimal b1 = new BigDecimal(Double.toString(d1));

BigDecimal b2 = new BigDecimal(Double.toString(d2));

// d1+d2

BigDecimal add = b1.add(b2);

System.out.println(add);

// d1-d2

BigDecimal sub = b1.subtract(b2);

System.out.println(sub);

// d1*d2

BigDecimal mul = b1.multiply(b2);

System.out.println(mul);

// d1/d2

BigDecimal div = b1.divide(b2);

System.out.println(div);

// BigDecimal -> double

double d3 = div.doubleValue();

System.out.println(d3);

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值