前言:前面讲了一大堆理论,拿几个例子试试
一共两个小例子:
试题:设置一个类, 命名为 MyList
类中包含属性:Object[] element
方法有如下几个:
增加方法 add : 可以向数组属性中依次存储 Object,数组内容
存满时,需实现动态扩容(详解在下面)。
删除方法 remove :可以根据数据或下标,从数组属性中删除
Object 数据,删除后,数组后续元素需前移。
查询方法 get :方法传入下标,返回数组中指定下标的数据。
当前存储数据量 size : 获取当前存储的有效数据长度
动态扩容详解:无需真正增加原数组的容量,只用将原内容复制到新
的大数组,然后让原数组名称重新等于大数组即可。由于原数组数据在堆中,
失去引用会被 GC 自动回收。
public class MyList {
//类属性
//当前存储量
//根据MyList类创建即设置size,只有动态扩容的时候才会增加size
public int size = 0;
//控制数组长度
private Object[] element;
//在创建对象时就初始化好数组
// 默认创建对像必须定义数组长度
public MyList(int size) {
this.size = size;
element = new Object[size];
}
//增加
public void add(Object o,int index){
//下标小于数组长度
if (index < size){
//直接把要增加值o 赋值给 要添加的下标所对应的值element[index]
element[index] = o;
}else {
//动态扩容
//创建新的大数组
Object[] newElement = new Object[size+1];
for (int i = 0; i < element.length; i++) {
//将所有值赋值给新的大数组
newElement[i] = element[i];
}
//element指向大数组的地址,element原有的数组被GC回收
element = newElement;
//扩容之后给扩容后的element赋值
element[index] = o;
//System.out.println("扩容数组为:"+Arrays.toString(element));
//以上扩容是成功了,但是size计数需要在原来的基础上增加一
size++;
}
//System.out.println("当前数组为:"+Arrays.toString(element));
}
public int getSize() {
return size;
}
//根据数据删除
//逻辑:判断是否有相等的值,如果有则移位覆盖即可,
// 如果用break在内循环里,结果只移动一位 错误 内部循环必须完整循环结束
//如果没有相等值,也不能直接else输出
//如果有对应的else会输出所有外层循环相比较的次数内容
//解决方法:使用boolean值判读是否有查找的值
public void remove(Object o) {
//首先判断是否有查找的数据
boolean isExists = false;
//外循环是循环数组下标
for (int i = 0; i < element.length; i++) {
//判断是否有下标所对应值 等于 删除值o,
if (o == element[i]) {
//能找到对应值
isExists = true;
//能找到对应值则把对应值后面的都往前移一位
for (int j = i; j < element.length-1; j++) {
element[j] = element[j+1];
}
}
}
//设置最后一位重复的为null
element[size-1] = null;
if (isExists){
System.out.println(Arrays.toString(element));
}else{
System.out.println("没有数据");
}
}
//根据下标删除
/*可以直接将后面一位往前移一位将
*前面的数据覆盖,最后再将最后一个没有覆盖的数据重新定义成null
* */
public void remove(int index){
//判断下标是否超出数组范围,数组从0开始
if (index > size-1 || index < 0){
System.out.println("错误:输出超出范围");
}else {
for (int i = index ; i < element.length - 1; i++) {
//后一个直接往前移
element[i] = element[i+1];
}
element[size-1]= null;
}
System.out.println("当前数组为:"+Arrays.toString(element));
}
//查询方法
public Object get(int index){
return this.element[index];
}
public static void main(String[] args) {
MyList myList = new MyList(5);
myList.add(5,0);
myList.add("sdf",1);
myList.add(45.5,2);
myList.add(15,3);
myList.add(12,4);
// myList.remove(3);
myList.add(14,5);
// myList.add(13,6);
// myList.remove("sdf");
System.out.println(myList.getSize());
}
今天的任务是通过控制台方式实现一个人机对战的猜拳游戏,用户通过输
入(1.剪刀 2.石头 3.布),机器随机生成(1.剪刀 2.石头 3.布),胜者积分,
n 局以后通过积分的多少判定胜负。
public class MoraGame {
public static void main(String[] args) {
MoraGame game = new MoraGame();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一共进行局数:");
//局数
int n = scanner.nextInt();
System.out.println("游戏开始!");
for (int i = 0; i < n; i++) {
System.out.println("请输入要出的手势(1.剪刀 2.石头 3.布)");
int j = scanner.nextInt();
game.person(j);
game.robot();
game.result();
}
game.print();
}
//记录人出的手势
int p;
//记录机器人出的手势
int r;
int pNum=0,rNum=0;
//机器人出的手势
void robot(){
Random ran = new Random();
int i = ran.nextInt(3)+1;
if (i == 1){
System.out.println("机器人出的是:剪刀");
}else if (i == 2){
System.out.println("机器人出的是:石头");
}else if (i == 3){
System.out.println("机器人出的是:布");
}
r = i;
}
//人出的手势
void person(int i){
if (i == 1){
System.out.println("人出的是:剪刀");
}else if (i == 2){
System.out.println("人出的是:石头");
}else if (i == 3){
System.out.println("人出的是:布");
}else {
//人特有的会出错,而机器不会出错
System.out.println("请重新输入");
}
p = i;
}
//比较人和机器人猜拳的结果
void result(){
if (p==r){
pNum += 1;
rNum += 1;
}else if (p==1 && r==2){
rNum++;
}else if (p==1 && r==3){
pNum++;
}else if (p==2 && r==1){
pNum++;
}else if (p==2 && r==3){
rNum++;
}else if (p==3 && r==1){
rNum++;
}else if (p==3 && r==2){
pNum++;
}else {
System.out.println("输入错误,游戏错误");
}
}
//输出结果
void print(){
System.out.println("人得分:"+pNum+" 机器人得分:"+rNum);
if (pNum > rNum){
System.out.println("你赢啦!");
}else if(pNum < rNum){
System.out.println("真可惜,机器人赢了!");
}else {
System.out.println("没意思,平局");
}
}
}