Java lecture 11 API、String、StringAPI和StringBuilder

一、游戏阶段收尾

游戏应该有几个状态:

1.游戏开始状态:当运行程序后,应该有一个开始的界面,一般认为当按下了空格键,切换运行状态。

2.游戏运行状态(已实现):潜艇/雷 自动生成,自动移动.... 战舰移动,攻击等等......

3.游戏结束状态: 当战舰命数为0时,游戏结束值得游戏画面暂停,并显示GameOver界面。

所以目前需要完善开始和结束状态。

在GameWorld类结构上方定义3个常量 1个变量。(常量的名称是需要全部大写的)

    public static final int GAME_START= 0;//开始状态
    public static final int RUNNING = 1;//运行状态
    public static final int GAME_OVER = 2;//结束状态
    public int gameCurrentState = GAME_START;//先默认开始状态。

1.需求:当按下空格键,需要判断一下当前游戏状态是否为开始状态

所以要在action方法里按到空格键那里进行更改:

   //e.getKeyCode(); 返回当前用户按下的按键
                if (e.getKeyCode() == KeyEvent.VK_SPACE) {//判断用户按下的键是不是键盘的空格键
                    if (gameCurrentState == GAME_START) {//判断当前游戏状态是否为开始状态
                        gameCurrentState = RUNNING;//切换为运行状态
                    } else {
                        bombEnterAction();//深水炸弹入场
                    }
                }

并且,原先的run方法里,应该是在运行状态下才能运行,所以要加一句判断语句,判断当前游戏状态是否为运行状态。

2.需求:在run中应该加一个条件限制,当游戏状态为运行状态时,再执行游戏逻辑

 public void run() {
                if (gameCurrentState == RUNNING) { //判断当前游戏状态是否为运行状态。
                    submarineEnterAction();//调用潜艇入场的方法。
                    thunderEnterAction();//调用雷入场的方法。
                    stepAction();//调用stepAction移动的方法
                    bombBangAction();//调用深水炸弹与潜艇的碰撞方法。
                    thunderBangAction();//调用雷与战舰的碰撞方法
                    outOfBounds();//自动删除越界对象,删除死亡对象的方法。
                    // System.out.println("潜艇数组的容量:" + submarines.length + ", 雷数组的容量:" + thunders.length);
                    repaint();//刷新绘制的方法
                }
            }

3.需求:游戏结束的状态是战舰的命数小于或等于0时,就要结束游戏。

那其实就需要单独写一个方法,来时刻检查战舰的命数,来改变游戏的状态,并把这个方法放在run中实时调用,

 /**
     * 检测游戏是否结束    -------当到run中实时调用
     * */
    public void  checkIsGameOver(){
        if(ship.getLife() <= 0){ //若战舰的命数小于等于0
            gameCurrentState = GAME_OVER;//修改为游戏结束状态。
        }
    }

最后,在GameWorld类的原先的paint方法里添加不同状态下绘制的内容:

注意,这里的ImageResources.start就是游戏开始界面的图片。要在游戏还在初始阶段时绘制。

而ImageResources.gameover就是游戏结束时显示的页面图片。

//绘制的方法 Java已经提供了 我们直接使用就可以了
    @Override               //g --- 画笔
    public void paint(Graphics g) {
        switch (gameCurrentState){
            case GAME_START: //if(gameCurrentState == GAME_START )
                ImageResources.start.paintIcon(null,g,0,0);
                break;
            case RUNNING://if(gameCurrentState == RUNNING )
                ImageResources.sea.paintIcon(null, g, 0, 0);//绘制背景图片
                ship.paintImage(g);
                for (int i = 0; i < submarines.length; i++) {
                    submarines[i].paintImage(g);
                }
                for (int i = 0; i < thunders.length; i++) {
                    thunders[i].paintImage(g);
                }
                for (int i = 0; i < bombs.length; i++) {
                    bombs[i].paintImage(g);
                }
                g.setFont(new Font("", Font.BOLD, 20));
                g.drawString("Score:" + score, 200, 50);
                g.drawString("Life:" + ship.getLife(), 400, 50);
                break;
            case GAME_OVER:if(gameCurrentState == GAME_OVER )
                ImageResources.gameover.paintIcon(null,g,0,0);
                break;
        }
​
    }

至此,整个游戏已完成!!!!

相当于所有的基础知识已讲完,接下来进行一个基础知识的回顾,检测一下自己的基础:

-------------------------------------------------------------------------------------------

基础知识:

1.声明个变量会不会?

2.常用数据的类型,知不知道都可以用来存什么?

int ? long ? double ? char ? boolean ? String ?

3.运算符会不会用?

数学运算符:+ - * / %

自增自减运算符: ++ -- ? 作用于变量

关系运算符: > < >= <= == !=

逻辑运算符: 并且(&&)? 或者(||)? 非 (!)? 

赋值运算符: = 扩展赋值运算符: += -= *= /= %=

三元表达式: int max = 1 > 2 ? 1 : 2; 

字符串拼接符: 什么是字符串? " 4162342564546fdtrsfa"

1 + “1 ” ------- "11"

4.分支结构:

单路分支: if(boolean){ 成立所执行代码块 }

双路分支: if(boolean){成立所执行代码块 } else { 不成立所执行代码块 }

多路分支: 当对一个数据 有多种判定条件时...

if(boolean1){ } else if(boolean2) { } ......

5.循环结构:

while: 不明确循环次数,已知循环条件 while(boolean){ 执行}

do while: 不明确循环次数,已知循环条件,且循环体至少执行一次 do { } while(boolean);

for : 当不明确循环条件,已知循环次数。 

for(1. ; 2. ; 3. ){ 循环代码块}

6.数组:

当有同一类型的多个数据时需要存储,可以使用数组来存储。

int[] array = new int[3]; //动态初始化(只开辟空间,没有数据)

int[] array2 = {1,2,3};//静态初始化(开辟空间并存储数据)

7.方法:

当程序中有重复冗余的代码,可能某个地方会用,另一个地方也可能会用,把经常使用的逻辑封装成方法,需要用的时候调用即可。

1.无参无返回值的方法 : void method (){ }

2.有参无返回值的方法: void sayHi( String name) { }

3.无参有返回值的方法: double getPI(){ return 3.1415926; }

4.有参数有返回值的方法: int sum(int a,int b) { return a+b;}

--------------------------------------------------------------------------------------

面向对象,三大特征知识

1. 封装

所有的学生对象 都有一些共性的属性和行为。

类的封装:封装同一类别下,所有对象共有的属性和行为。(大部分)

方法的封装:重复的业务逻辑封装成方法,达到复用原则(一次定义多次使用)

属性的封装:属性私有化,方法公开化。(目的:保护程序属性,防止会被任意修改)

先有类的封装,才有类的继承。

2. 继承 :
好处 实现代码的复用,但是必须是is a 是一种概念的关系。

坏处:耦合性高!耦合性也就是不利于修改。(举例:比如我们的智能手机,耦合性就很高,就是封装的太多了,把零零散散的封装在一起,就不利于维修。因为一旦修改了父类某个地方,子类很多都会报错)

接口:好处,定义的内容小而精(功能专一),并非集成化的代码。

真正实际开发的过程中:若多个类之间仅仅只是想复用某一个行为的话,推荐使用接口。
因为耦合度低.

3. 多态:
一旦实现了继承 或者 接口 ,也就意味着已经实现多态了!

声明 父 new 子。 

行为上的多态:调用父执行子。

二、API

Application Programing Interface(应用程序接口(功能))

什么是API:API表示的是功能,我们可以通过学习API,快速实现我们的编程开发。

API的设计初衷:设计者将复杂的业务逻辑,封装成方法,供调用者会更好使用。对于使用者而言,不需要关注功能的具体逻辑,只需要知道如何使用就可以了。

java提供的很多包,有一些包是需要导入的,常用的包不需要导入:

1.java.lang 包:java的核心语法包,内部封装了Java最核心的API,一般使用的时候不需要导入。

例如:String , Object , System ,Integer....

2.java.io包:可以实现文件的输入和输出等功能。

3.java.net 包: 网络相关的功能 。

4.java.util : 工具包

注意!这些用法是不用背的,需要时候再去查。

三、String(字符串)

为什么要单独讲,因为后面面试题很多会涉及到。

1.java.lang.String包下,且String这个类用final修饰的 .

2.String内部封装了一个用fianl修饰的char数组,也就意味着我们使用字符串,本质上是由字符数组组成,且一旦创建不可变。

3.字符串一旦创建,对象的内容不可以修改的,若重新为字符串类型的变量赋值新的内容或者拼接的内容,都不能在原有基础上修改。都相当于开辟了一个新的内存空间。

4.String是引用类型

            引用类型
           //"123"是字符串的直接量,本质上就已经发生创建对象的操作。
String a = "123";
String b = a;
b = "456";
System.out.println(a);//123
System.out.println(b);//456
String c = new String("789");
System.out.println(c);//789
char[] a1 = {'1','2','3'};

String对象一旦被创建了,不可变的原因在于,String的内容是非常常用的,这么设计就是为了优化内存,因为在堆中会有一个常量池的存在,常量池放的则是已经创建过的字符串内容的地址

  String a = "ABC";
        String b = "ABC";
        System.out.println(a == b); //引用类型的变量 使用双等比较的是两个变量的内存地址是否相同。    // 注意,这里比较的是指向的地址是否一样,不是内容。
//        int c = 10;
//        int d = 20;
//        System.out.println(c == d);//基本类型的变量 使用双等比较的是两个变量的数据是否相同。

 也就是说,假设a和b的字符串是一样的,那指向的地址也是一样的,因为它是引用类型。

String对象可以复用的条件,String创建对象的方式有两种!

1.静态字符串的创建方式(是可以复用的!): 是推荐的!

1.1:以字符串字面量的方式来创建的字符串对象。例如:String a = "ABC";

1.2:  字符串的常量。就是用static final的字符串

1.3:以字符串字面量的方式拼接而成的字符串对象。

例子:

 public static final String C = "ABC";
    public static void main(String[] args) {
//        String a = "123";
//        String b = a;
//        a = a + "456";
//        System.out.println(a);//123456
//        System.out.println(b);//123
        String a = "ABC";
        String b = "ABC";
        String d = "A" + "BC";
        System.out.println(a == b); //引用类型的变量 使用双等比较的是两个变量的内存地址是否相同。
        System.out.println(a == C);
        System.out.println(a == d);
//        int c = 10;
//        int d = 20;
//        System.out.println(c == d);//基本类型的变量 使用双等比较的是两个变量的数据是否相同。
​
​
    }

例子里打出a == b 和 a==c a == d都是返回true。

-------------------------------------------------------------

2.动态字符串的创建方法: 不推荐使用!不能复用String对象。

2.1 使用new关键字来创建的String对象 。 例如: new String("ABC");

2.2 String类型的变量 拼接 字符串字面量。例如:a + "456"

例子:

  //使用动态的方式创建的字符串对象
        String b1 = new String("ABC");
        System.out.println(a == b1);//false
        String b2 = "A";
        String b3 = b2 + "BC";//注意,字面量的拼接才可以
        System.out.println(a == b3);//false

面试题:

String str = new String ("ABC");

问:上述代码,创建了几个String对象?

答:创建了2个String对象("ABC",str)

问:上述代码,创建了几个对象?

答:创建了3个对象,2个String对象1个char数组对象

四、StringAPI

String类,提供一些方法(API),例如:可以获取字符串的长度,也可以通过下标来获取字符串中的某个字符,将字符串的内容转换为大写,小写........查找相关的.....

1.获取字符串内容的长度以及通过下标获取对应字符内容。(.charAt())

package stringdemo;
​
/**
 * StringAPI的使用演示类:
 */
public class StringAPIDemo {
    public static void main(String[] args) {
        String str = "Thinking in Java是一本好书";
        str.length(); 通过String类型的变量打点调用length() 则返回一个 int类型的长度
        int length = str.length();
        System.out.println(length);//21
        str.charAt(20);通过String类型的变量打点调用char()方法,传入一个索引 返回对应索引的字符
        char c = str.charAt(20);
        System.out.println(c);
​
        //-----------------------------
        //面试题:请编写一段程序,将 "Thinking in Java是一本好书" 中字符 i 所存在的次数 统计出来。
        String str = "Thinking in Java是一本好书";
        int count = 0;
        for (int i = 0; i < str.length() ; i++) {
            if( str.charAt(i) == 'i' ){//判断当前遍历到的字符 是否等于  i这个字符
                count++;//计数
            }
        }
        System.out.println("统计i的次数为:"+count);
​
    }
}
​

2. indexOf(); 从首到尾 检索传入的字符/字符串 ,检索到则返回对应的字符下标。

LastIndexOf();从尾到首 检索传入的字符/字符串,检索到则返回对应的字符下标。

  //indexof();
        String str = "Thinking in Java是一本好书";
        //str.indexOf('i'); 该方法从头到尾检测每个字符是否等于字符i ,若等于 立刻返回 字符i对应的下标
        int index = str.indexOf('i');
        System.out.println(index);//2
        //indexOf('i',3);该用法从指定索引位置3到尾检测每个字符是否等于字符i ,若等于 立刻返回 字符i对应的下标
        int index1 = str.indexOf('i',3);
        System.out.println(index1);//5
        int index2 = str.indexOf('x');//若查找的字符不存在,返回的数据为-1
        System.out.println(index2);
        //str.indexOf("Java");该方法从头到尾检测字符串对象中内容 是否等于传入的字符串 ,若等于 立刻返回字符串首字母对应的下标
        index2 = str.indexOf("Java");
        System.out.println(index2);//12

3.字符串转换大小写,去除两端空白(trim),判断是否以..开头 或以..结尾的方法(startsWith)

     // 字符串的转换大小写的方法
        String str = "Thinking in Java是一本好书";
        str = str.toUpperCase();//将字符串中英文转换为大写  会产生新对象
        System.out.println(str);
        str = str.toLowerCase();
        System.out.println(str);
​
        //去除两端空白的方法(比如帐号密码输入时自动去除空白)
        String str1 = " Tom ";
        System.out.println(str1);
        str1 = str1.trim();
        System.out.println(str1);
​
        //用来判断是以...开头 或以..结尾的方法
        boolean r = str1.startsWith("T");
        System.out.println(r);
        r= str1.endsWith("m");
        System.out.println(r);

4.截取字符串 subString(); (传入下标值)和 将数值类型转换为String 的方法 valueOf();

  String str = "bjzhangpeng@tedu.cn";
        //截取时“包头不包尾”
        //substring() 截取区间的字符串内容 ,可以传入两个参数  1. 开始截取的下标   2.结束截取的下标(截不到当前结束的索引)
        str = str.substring(0, 11);
        System.out.println(str);
​
        //练习需求:练习完上面代码后,想想,如果想要截取通用的用户名的话,程序应该怎么写?
        //例如:liucs@tedu.cn   bjzhangpeng@tedu.cn
        String str1 = "liucs@tedu.cn";
        str1 = str1.substring(0, str1.indexOf("@"));
        System.out.println(str1);
​
        //截取字符串的用法有两种:
        //1.subString(开始索引,结束索引); 会截取出区域的字符串内容
        //2.subString(开始索引,开始索引+要截取的长度);
        str1= str1.substring(1,1+3);
        System.out.println(str1);//iuc
​
        //String 提供了静态方法: valueOf 可以将数值类型的内容转为字符串的方法
        int a = 123;
        String b= String.valueOf(a);
        System.out.println(b);
        int c = 234;
        System.out.println(c);//本质上 打印在显示台中的数据 都是已经被String.valueOf转换了的。

5.判断是否包含...内容的方法(.contains()), 是否字符串长度为0的方法(isEmpty()), 将字符串对象转换为char数组(toCharArray())

   //判断是否包含XX的内容的方法
        String d = "AOP";
        boolean result= d.contains("O");
        System.out.println(result);
​
​
        String e ="";
        //isEmpty()判断调用该方法的字符串对象是否是0个长度
        System.out.println(e.isEmpty());
​
        String f = "abcdefg";
        char[] r = f.toCharArray();
        for (int i = 0; i < r.length; i++) {
            System.out.println(r[i]);
        }

String不适合频繁修改的,一旦发生修改,就是创建新的对象。若频繁的创建对象,对内存的消耗是非常大的,容易出现OutOfMemoryError 内存溢出异常。

五、StringBuilder

如果对String进行频繁修改时,可以使用Java提供的StringBuilder类来解决。

其实就是一个类似于列表那种感觉,能够自由实现字符串的更改。

因为StringBuilder内部维护了一个可变的char数组。修改性能小, 而且提供了很多字符串修改的相关操作。

增删改插

//字符串追加的方法使用。
        String str = "好好学习Java";
        StringBuilder builder = new StringBuilder(str);//创建StringBuilder对象 并传入要处理的字符串对象
        //append 追加的方法: 将需要追加的内容 放在 括号中即可。
        builder.append(",为了找份好工作");
        System.out.println(builder);
​
        //字符串修改的方法使用
        //replace 替换的方法:1.替换开始的索引 2.结束的索引(也是不包尾) 3.要替换的内容
        builder.replace(9, 16, "为了改变世界!");
        System.out.println(builder);
​
        //删除的方法使用
        //delete 方法 : 第一个参数代表 开始的索引  第二个参数代表结束的索引(不包尾)
        builder.delete(0, 9);
        System.out.println(builder);
​
        //插入的方法使用
        builder.insert(0, "活着,");
        System.out.println(builder);
​
        //反转的方法使用
        builder.reverse();
        System.out.println(builder);
​
        str = builder.toString();//将builder 转换为 String对象
        System.out.println(str);
 String s = "a";
        StringBuilder builder = new StringBuilder(s);
        long start= System.currentTimeMillis();//获取当前的系统时间,单位是毫秒
        for (int i = 0; i <= 100000; i++) {
//            s += s;  //指数级的增长
            builder.append(s);
        }
        long end= System.currentTimeMillis();
        System.out.println("运行时间是"+(end - start)+"毫秒");

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq030928

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值