模拟发红包案例-Java

模拟发红包

  • 结构分析

代码

  • User类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
public class User {
private String name;
private double money;

public User() {
}

public User(String name, double money) {
this.name = name;
this.money = money;
}

//显示信息
public void show() {
System.out.println("我叫:" + this.name + "剩余金额:" + this.money);
}

public String getName() {
return name;
}

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

public double getMoney() {
return money;
}

public void setMoney(double money) {
this.money = money;
}
}

  • Manager类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
public class Manager extends User {
public Manager() {
}

public Manager(String name, int money) {
super(name, money);
}

//发平均红包
public ArrayList<Double> send(double totoalMoney, int count) {
/**红包金额平等
//存放若干红包金额
ArrayList<Integer> integerArrayList = new ArrayList<>();
if (totoalMoney > super.getMoney()) {
System.out.println("余额不足!");
return integerArrayList;
}
int avg = totoalMoney / count;//均分
int mod = totoalMoney % count;//余数
//修改余额
super.setMoney(super.getMoney() - totoalMoney);
for (int i = 0; i < count - 1; i++) {
integerArrayList.add(avg);
}
//最后一个人分红包
int last = mod + avg;
integerArrayList.add(last);
return integerArrayList;
**/

//随机分配金额,最少一分钱。最多不超过剩下金额平均值的2倍
//公式:0.01 + random.nextInt(leftMoney /leftCount * 2)

Random r = new Random();
//totoalMoney最多两位小数,计算完强转为int
int leftMoney = (int) (totoalMoney* 100);//转换成分计算

int leftCount = count;
int max = leftMoney / leftCount * 2;
ArrayList<Double> list = new ArrayList<>();
//随机发前count-1个
for (int i = 0; i < count - 1; i++) {
int money = r.nextInt(leftMoney / leftCount * 2) + 1;
list.add((double) money / 100);
leftMoney -= money;
leftCount--;
}
list.add((double) leftMoney / 100);
super.setMoney(super.getMoney()-totoalMoney);
return list;
}

}

  • Member类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Member extends User {
public Member() {
}

public Member(String name, int money) {
super(name, money);
}

public void receive(ArrayList<Double> list) {
//随机获取一个集合中的索引编号
int index = new Random().nextInt(list.size());
//根据索引,从集合中删除,得到被删除的红包金额
double delta = list.remove(index);
//加法,重新设置剩余金额
super.setMoney(super.getMoney() + delta);
}
}
  • 主类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public static void main(String[] args) {
Manager manager = new Manager("hxx", 100);
Member one = new Member("qzy", 0);
Member two = new Member("zyx", 0);
Member third = new Member("wn", 0);
Member four = new Member("hxs",0);
//发红包
ArrayList<Double> list = manager.send(3.1, 4);
//分红包
one.receive(list);
two.receive(list);
third.receive(list);
four.receive(list);

manager.show();

one.show();
two.show();
third.show();
four.show();
}
  • 运行结果
1
2
3
4
5
我叫:hxx剩余金额:96.9
我叫:qzy剩余金额:0.56
我叫:zyx剩余金额:0.66
我叫:wn剩余金额:0.67
我叫:hxs剩余金额:1.21

抽象类-Java

抽象类的使用

  • 类中成员方法在返回类型前面加上abstract关键字
  • 抽象类:抽象方法所在的类必须是抽象类。在class之前加abstract
  • 不能直接创建抽象类对象,必须使用子类继承抽象父类的所有抽象方法。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public abstract class Fu {
public abstract void eat();
}
public class Zi extends Fu {
@Override
public void eat() {
System.out.println("子类实现父类抽象方法");
}
}
public static void main(String[] args) {
// Fu fu = new Fu();报错
Zi zi = new Zi();
zi.eat();
}

抽象类调用自己的抽象方法,实现来自实现类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public abstract class Fu {
public abstract void eat();
public void dosomething(){
eat();
System.out.println("父类调用自己的抽象方法");
}
}
public class Zi extends Fu {
@Override
public void eat() {
System.out.println("子类实现父类抽象方法");
}
}
public static void main(String[] args) {
Zi zi = new Zi();
zi.dosomething();
}
  • 当真正实例化去使用的时候,使用的是子类重写后的实例方法

运行结果

1
2
子类实现父类抽象方法
父类调用自己的抽象方法

继承中的覆盖重写-Java

继承关键字

  • public class 子类名称 extends 父类名称{ …….. }

  • 当子类和父类成员相同时,直接通过子类对象访问该成员,等号左边是谁,就有先用谁,没有就向上找

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Fu {
int numFu = 10;
int num = 100;
public void methodFu(){
System.out.println(num);
}
}
public class Zi extends Fu {
int numZi = 20;
int num = 200;
public void methodZi(){
System.out.println(num);
}
}
public class HelloWorld {
public static void main(String[] args) {
Fu fu = new Fu();
Zi zi = new Zi();
System.out.println(zi.num); //200
zi.methodFu();//100
zi.methodZi();//200
}
  • 子类中局部变量、子类变量、父类变量重名时的访问
1
2
3
4
5
6
7
8
9
public class Zi extends Fu {
int num = 200;
public void method(){
int num = 300;
System.out.println(num);//局部变量
System.out.println(this.num);//本类当中
System.out.println(super.num);//访问父类变量
}
}

覆盖重写

  • 父子之间方法名称和参数列表相同

  • @Override:写在方法前面,用来检测是不是有效的重写

  • 子类方法的返回值必须小于等于父类方法的返回值。

    提示:java. lang.Object类是所有类的公共最高父类,java. lang.Strubg类是Object的子类

  • 子类方法的权限必须大于等于父类方法的权限修饰符

    提示:public > protected > (default) > private

1
2
3
4
5
6
7
8
9
10
11
12
public class Fu {
public void method(){
System.out.println("显示号码");
}
}
public class Zi extends Fu {
@Override
public void method() {
super.method();
System.out.println("显示姓名");
}
}

继承中的构造

  • 当父类没有写有参的构造函数时,子类构造方法中会有一个默认隐含的super()调用。
  • 子类构造可以通过super关键字来调用父类重载构造
  • super的父类构造调用必须是子类构造方法中的第一个语句,也不可出现多次
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Fu {
public Fu(int num) {
System.out.println("有参的父类构造");
}
public Fu() {
System.out.println("无参的父类构造");
}
}
public class Zi extends Fu {
public Zi() {
//super();
super(20);
System.out.println("子类构造");
}
}

继承的特点

  • 单继承:一个类的直接父类只能有一个。
  • 多级继承
  • 一个子类的父类是唯一的,但是一个父类可以有多个子类

Array和math工具类-Java

Arrays常用方法

  • public static String toString(数组名):将数组转化为字符串
1
2
3
4
5
public static void main(String[] args) {
int[] arrays = {10,20,30};
String string = Arrays.toString(arrays);
System.out.println(string);
}
  • public static void sort(数组):按照默认升序对数组元素排序
1
2
3
4
5
public static void main(String[] args) {
int[] arrays = {20,10,30};
Arrays.sort(arrays);
System.out.println(Arrays.toString(arrays));
}

math工具类

  • public static double abs(double num):获取绝对值
  • public static double ceil(double num);向上取整
  • public static double floor(double num);向下取整
  • public static long round(double num);四舍五入
1
System.out.println(Math.ceil(3.1));//输出4.0

静态static关键字-Java

static修饰成员

  • 修饰成员变量,多个对象共享使用该变量,也可类名.静态变量来使用。
  • 修饰成员方法,称为静态方法。
    1. 可以通过对象名调用(不推荐),也可以通过类名调用(类名称.静态方法),如果在本类中调用可省略类名。
    2. 如果没有static关键字,那么必须首先创建对象,通过对象使用。
    3. 静态方法不能直接访问非静态成员,因为在内存中先有的静态内容。
    4. 静态方法中不能使用this。

静态代码块

  • 当第一次使用到本类时,静态代码块执行唯一一次。用来一次性的对静态成员变量进行赋值

  • 在类中

    static { 代码 }

1
2
3
4
5
6
7
8
9
public class Student {
static {
System.out.println("这是静态代码块");
}
}
public static void main(String[] args) {
Student student = new Student();
Student student1 = new Student();
}

运行结果

1
这是静态代码块

String字符串和StringBuilder类-Java

1. String类

字符串概述和特点

  • Java程序中的所有字符串字面值(如“abc”)都作为此类的实例实现,即程序当中所有的双引号字符串,都是String类的对象(包括没有使用new)
  • 字符串的内容用不可变,所以字符串可以共享使用
  • 字符串效果上相当于char[]字符数组,但是底层原理是byte[]字节数组

字符串的创建

  • **public String()**:创建一个空白字符串,内容为空
1
String str = new String();
  • **public String(char []array)**:根据字符数组的内容,创建对应的字符串
1
2
char[] charArray = {'q','z','y'};
String str = new String(charArray);
  • **public String(byte[]array)**:根据字节数组的内容,创建对应的字符串
1
2
3
byte[] byteArray = {97,98,99};
String str = new String(byteArray);
System.out.println(str);
  • 直接创建
1
String str = "hello";

字符串比较相关方法

  • public boolean equals(Object obj):参数可以是任何对象
  • public boolean equalsIgnoreCase(Object obj):不区分大小写

字符串获取

  • public String concat(String str):字符串连接
  • public char charAt(int index):获取指定索引位置
  • public int indexOf(String str);查找str在字符串中首次出现的位置,若没有返回-1

字符串截取

  • public String substring(int index):从index的位置到字符串末尾,返回字符串
  • public String substring(int begin,int end):[begin,end)的位置到字符串末尾,返回字符串

字符串转换

  • public char[] toCharArray();将字符串拆分成字符数组并返回
  • public byte[] getBytes();将字符串拆分成字节数组并返回
  • public String replace(CharSequence oldString,CharSequence newString);将所有出现的老字符串替换成新的字符串,返回替换之后的结果新字符串

字符串分割

  • public String[] split(String regex);按照参数的规则,将字符串划分;

    其参数是正则表达式,如果按照英文据点”.”分割,必须写“\\.”

2. StringBuilder类

原理

  • 使一个字符串缓冲区,可以提高字符串的操作效率。底层也是一个数组,但是没有被final修饰,可以改变长度,如果超出StringBuilder的容量弧自动扩容。

构造方法

  • public StringBuilder():构造一个空的StringBuilder容器
  • public StringBuilder(String str):构造一个StringBuilder容器,并将字符串添加进去

常用方法

  • public StringBuilder append(...) :添加任意数据类型的字符串形式,并返回档期啊对象自身
  • public String toString() 将当前StringBuilder转换成String对象

3. 基本类型和字符串类型之间转换

基本类型–>字符串

  • 基本类型的值 + “”
  • 包装类的静态方法toString(参数)
  • String类的静态方法valueOf(参数)

字符串–>基本类型

  • 使用包装类的静态方法parsexxx(String)方法
1
2
3
4
5
int i1 = 10;
String s1 = i1 + "";
String s2 = Integer.toString(100);
String s3 = String.valueOf(100);
int i = Integer.parseInt("10");

Arraylist-java

定义格式

  • ArrayList< E > 名称= new ArrayList<>();,< E >代表泛型,E只能是引用类型
1
ArrayList<String> arrayList= new ArrayList<String>();
  • 若要再集合中存储基本数据类型,必须使用基本数据类型对应的包装类

常用方法

  • public boolwan add(E a):向集合中添加元素,参数的类型和泛型一致
  • public E get(int index):从集合中获取元素,参数是索引编号
  • public E remove(int index):从集合中删除元素,参数是索引编号
  • public int size():获取集合的长度,返回值是集合中元素的个数

注意事项

  • 对于ArrayList集合来说,直接打印得到的不是地址值,而是内容。如果内容为空,得到的是空的中括号
1
2
3
4
5
6
public static void main(String[] args) {
ArrayList<String> arrayList= new ArrayList<String>();
System.out.println(arrayList);
arrayList.add("qizeyu");
System.out.println(arrayList);
}

运行结果

1
2
[]
[qizeyu]

生成随机数(java)

方法一:Random.nextInt()

1
2
Random random = new Random();
int num = random.nextInt();//生成int范围内的数字

方法二:Random.nextInt(bound)

1
num = random.nextInt(11);//生成0~(bound-1)之内的整数

方法三:Math.Random()

1
2
3
4
int max = 100;
int min = 0;
double ran = Math.random() * (max - min + 1) + min;//生成min~max之间的随机浮点数
ran = Math.random() * (max - min) + min;//不含最大值,含最小值

先输入数字,后字符串(java)

java中使用Scanner先输入数字,后输入字符串,需要吸收输入数字之后的回车

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();

String str = scanner.nextLine();//吸收输入数字之后的回车

str = scanner.nextLine();

System.out.println("num:"+num);
System.out.println("str:"+str);
}

运行结果

1
2
3
4
100
str
num:100
str:str

局部变量和成员变量(java)

局部变量和成员变量(java)

  1. 定义的位置

    局部变量:在方法的内部

    成员变量:直接写在类中

  2. 作用范围

    局部变量:只有在方法中可以使用

    成员变量:整个类全部可以通用

  3. 默认值

    局部变量:没有默认值,如果想要使用,必须初始化。

    成员变量:如果没有赋值,会有默认值,规则和数组的默认值一样4.

  4. 内存位置

    局部变量:位于栈

    成员变量:位于堆

  5. 生命周期

    局部变量:随着方法进栈而产生,随着方法出栈而消失

    成员变量:随着对象创建而产生,随着对象被垃圾回收而消失