1.25
小fleeting 学习java
关于辅助书籍:
Core Java 字典
比如学习完了IO的知识,觉得意犹未尽,那么就通过这本字典一样的Java书籍,把IO的知识更丰满的刷一遍
Effective Java 零食,提升代码质量
作为初学者,首要任务不是提升质量,而是掌握完成功能的基本手法。这本书就像零食一样,只要主食吃了,你不吃零食也没关系,但是吃点零食会觉得生活质量得到了提升。不用通看,碰到什么,看什么,一次也不应该看太多,当做有益的课外补充。
1. JDK环境配置
win+R: cmd
2. 用命令行编译、运行java文件
前情:
小fleeting已经在c盘配置了jdk,并并列建立了project文件
project下设j2se文件,再下设src文件,用来存放java源文件
第一个代码源文件
public class HelloWorld{
public static void main(String[] args){
System.out.println("hello world");
}
}
命令行效果:
其中:
cd c:\project\j2se\src 切换目录到源文件目录
javac filename.java 编译 java文件,并且得到一个class文件
java filename 运行class文件
----------------------------------------------------------------------------------------------
1.26
1.what i learn
-
eclipse
-
面向对象
类、属性(字段)、方法形象表述
代码
public class Hero {
String name; //姓名
float hp; //血量
float armor; //护甲
int moveSpeed;//移动速度
//超神
void lengendary(){
System.out.println("超神");
}
//坑队友
void keng(){
System.out.println("坑队友!");
}
//获取护甲值
float getArmor(){
return armor;
}
//加速
void addSpeed(int speed){
moveSpeed= moveSpeed+speed;
}
//回血
void recovery(float blood){
hp=hp+blood;
}
public static void main(String[] args) {
Hero garen = new Hero();
garen.name = "盖伦";
garen.hp = 616.22f;
garen.armor=27.5f;
garen.moveSpeed = 350;
garen.addSpeed(100);
}
}
-
变量
基本类型,类型转换,作用域,命名,final
-
操作符
异或^:左右两数相同则返回0,不同则为1
任何数和0 进行异或 都等于自己
带符号右移 >>: 移动后正的还是正的,负的还是负的,符号不变
无符号右移>>>:移动后,变正的了
** eg1:**
public class HelloWorld {
public static void main(String[] args) {
int i = 1;
boolean b = !(i++ == 3) ^ (i++ ==2) && (i++==3);
//i值 2 3
//表达式 false true
// true ^ true
// false
System.out.println(b);
System.out.println(i);
}
}
所以,输出结果为:
false
3
**eg2:**
public class HelloWorld {
public static void main(String[] args) {
int i = 1;
int j = ++i + i++ + ++i + ++i + i++;
//i值 2 3 4 5 6
//取值 2 2 4 5 5
System.out.println(j);
}
}
所以结果为18
eg3
public class HelloWorld {
public static void main(String[] args) {
int i = 1;
i+=++i;
// 2
// 3
System.out.println(i);
}
}
相当于i+=++i -->i=i+(++i)–>i=1+(2)–>I=3。
2.新学的programmer
-1 输出
public class HelloWorld{
public static void main(String[] args){
int a;
System.out.println(“输入身高(m):”);
System.out.println(“体制为:” + a);
}
}
-2 输入
import java.util.Scanner;
public class HelloWorld{
public static void main(String[] args){
Scanner s= new Scanner(System.in);
int a=s.nextInt();
float height=s.nextFloat();
}
}
-3 整数转二进制
Integer.toBinaryString()
----------------------------------------------------------------------------------------------
1.27
一、控制流程
- deeeeeebug
int f=10000*Math.pow(1.05, n);//会报错
不是int,因为应该是double类型
2.使用boolean变量结束外部循环
public class HelloWorld {
public static void main(String[] args) {
boolean breakout = false; //是否终止外部循环的标记
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println(i + ":" + j);
if (0 == j % 2) {
breakout = true; //在内部修改这个变量值
break;
}
}
if (breakout) //判断是否终止外部循环
break; //借助boolean变量结束外部循环
}
}
}
- 使用标签结束外部循环
//在外部循环的前一行,加上标签
outloop:
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
System.out.println(i+":"+j);
if(0==j%2)
break outloop; //在break的时候使用该标签,结束外部循环
}
}
outloop这个标示是可以自定义的比如outloop1,ol2,out5
4.练习-黄金分割点:
寻找某两个数相除,其结果 离黄金分割点 0.618最近
分母和分子不能同时为偶数
分母和分子 取值范围在[1-20]
public class HelloWorld{
public static void main(String[] args){
float result=0.382f,maybe;
int a,b,a1=1,a2=1;
for (a = 1; a <=20; a++) {
for (b = 1; b <=a; b++) {
//分母和分子不能同时为偶数
if(a%2==0&&b%2==0)
continue;
//下面这个必须要先加(float),才能得到正确结果
maybe=(float)b/a;
if(Math.abs(result-0.618)>Math.abs(maybe-0.618))//绝对值
{
result=maybe;
a1=a;
a2=b;
}
}
}
System.out.println("分母"+a1+"分子"+a2);
}
}
结果:分母13,分子8
- 练习 水仙花数(三位数)
个位:i%10
十位:i/10%10
百位:i/100
- 调试,断点,单行运行
二、数组
{ 声 明 一 个 引 用 a : i n t [ ] a ; 创 建 一 个 由 a 指 向 的 数 组 : a = n e w i n t [ 5 ] ; 初 始 化 数 组 : a [ 0 ] = 1 ; a [ 2 ] = 2 ; \left\{ \begin{matrix} 声明一个引用a :int [] a; \\ \\ 创建一个由a指向的数组:a =new \ int[5]; \\ \\ 初始化数组:a[0]=1;a[2]=2; \\ \end{matrix} \right. ⎩⎪⎪⎪⎪⎨⎪⎪⎪⎪⎧声明一个引用a:int[]a;创建一个由a指向的数组:a=new int[5];初始化数组:a[0]=1;a[2]=2;
同时进行
写法一: 分配空间同时赋值
int[] a = new int[]{100,102,444,836,3236};
写法二: 省略了new int[],效果一样
int[] b = {100,102,444,836,3236};
{
第
i
个
−
>
长
度
a
.
l
e
n
g
t
h
=
i
下
标
i
−
1
−
>
下
标
范
围
\left\{ \begin{matrix} 第i个 ->长度 a.length=i\\ \\ 下标i-1->下标范围\\ \end{matrix} \right.
⎩⎨⎧第i个−>长度a.length=i下标i−1−>下标范围
(i=1,2,3…)
- 排序
- 选择
i:0; length-1;++
j: i+1; length ;++
for (int j = 0; j < a.length-1; j++) {
for (int i = j+1; i < a.length; i++) {
if(a[i]<a[j]){
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
}
}
- 冒泡
i: 0;length;++
j: 0; length-1-i;++
for (int j = 0; j < a.length; j++) {
for (int i = 0; i < a.length-j-1; i++) {
if(a[i]>a[i+1]){
int temp = a[i];
a[i] = a[i+1];
a[i+1] = temp;
}
}
}
-
二维数组
//创建+初始化 int[][] a = new int[2][3]{ //2表示有两个一维数组,3表示每个一维数组的长度是3 {1,2,3}, {4,5,6}, };
》
//遍历 for (int i = 0; i < a.length ; i++) { for (int j = 0; j < a[i].length; j++) { a[i][j]。。。。。。 } }
三.新学的programmer
-
随机分配0-100
(int) (Math.random()*100)
-
复制数组
System.arraycopy(src, srcPos, dest, destPos, length)
eg:合并数组
首先准备两个数组,他俩的长度是5-10之间的随机数,并使用随机数初始化这两个数组;然后准备第三个数组,把前两个数组合并到第三个数组中
public class HelloWorld{
public static void main(String[] args){
int a[]=new int[(int) (Math.random() * 5)+5];
int b[]=new int[(int) (Math.random() * 5)+5];
int c[]=new int[a.length+b.length];
for (int i = 0; i < a.length; i++) {
a[i]=(int) (Math.random()*100);
}
for (int i = 0; i < b.length; i++) {
b[i]=(int) (Math.random()*100);
}
for(int i : a)
{
System.out.println(i+" ");
}
for(int i : b)
{
System.out.println(i+" ");
}
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
for(int i : c)
{
System.out.println(i);
}
}
}
注意:1.增强型for循环
- 增强型for循环只能用来取值,却不能用来修改数组里的值!赋值不可以!
- 内部的i直接表示一个数组元素,不用再额外a[i]。
- 二维数组也可以for增强
for (int[] row : a) {
for (int each : row) {
System.out.print(each + "\t");
}
System.out.println();
}
2.例题中,放好a后,放b时的destPos是a.length,而不是a.length-1.
-
Arrays
import java.util.Arrays;
关键字 | 简介 | 用法 |
---|---|---|
copyOfRange | 数组复制 | int a[ ]=Arrays.copyOfRange(original, from, to) // 第一个参数表示源数组 , 第二个参数表示开始位置(取得到) , 第三个参数表示结束位置(取不到) |
toString() | 转换为字符串 | System.out.println(Arrays.toString(a)); |
sort | 正排序 | Arrays.sort(a); |
binarySearch | 搜索 | System.out.println(Arrays.binarySearch(a, n)); //n表示要找的数字,返回其所在数组的下标位置。 //使用binarySearch之前,必须先使用sort进行排序 |
equals | 判断是否相同 | System.out.println(Arrays.equals(a, b)); |
fill | 填充 | Arrays.fill(a, 5); |
eg:练习-二维数组排序
首先定义一个5X8的二维数组,然后使用随机数填充满。
借助Arrays的方法对二维数组进行排序。
参考思路:
先把二维数组使用System.arraycopy进行数组复制到一个一维数组
然后使用sort进行排序
最后再复制回到二维数组。
import java.util.Arrays;
public class HelloWorld{
public static void main(String[] args){
int a[][]=new int[5][8];
int b[]=new int [40];
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i].length; j++) {
a[i][j]=(int)(Math.random()*100);
}
}
for(int []row:a)
{
System.out.println(Arrays.toString(row));
}
System.out.println(" ");
// 把二维数组复制到一维数组
for(int i = 0; i < a.length; i++) {
System.arraycopy(a[i], 0, b, i*8, a[i].length);
}
// 对一维数组进行排序
Arrays.sort(b);
// 把一维数组复制到二维数组
for(int i = 0; i < a.length; i++)
{
System.arraycopy(b, i*8, a[i], 0, a[i].length);
}
System.out.println("结果:");
for(int []row:a)
{
System.out.println(Arrays.toString(row));
}
}
}
运行效果:
----------------------------------------------------------------------------------------------
1.28
一、类和对象
1.方法
调用:
以下:方法名一样,方法的参数不一样
》》1个参数时:
输出:盖伦攻击了提莫
》》2个参数时
升级:继承下的调用:
eg:类Support继承类Hero
结果:
升级:方法的重载:
-public void attack(类名 … 参数名)
-自动给匹配不同的参数对应情
构造
-方法名和类名一样(包括大小写)
-实例化一个对象的时候,必然调用构造方法
不过一般默认提供一个
-显式写法没有返回类型!!!
-构造也可以带参数
输出:
Hero 类的构造方法
Hero 类的构造方法
new:实例化
2.this
实例:
public class Hero {
String name;
float hp;
float armor;
int moveSpeed;
public Hero(String name,float hp){
System.out.println(name+"dl");
}
public Hero(String name, float hp,float armor, int moveSpeed){
this(name,hp);//通过this调用其他的构造方法
System.out.println(" bjyxszd");
this.armor=armor;通过this访问属性
}
//打印this看到的
//格式:Hero@c17164 c17164即虚拟地址,每次执行,得到的地址不一定一样
public void showAddressInMemory(){
System.out.println("虚拟地址:"+this);//this代表当前对象,此处及hp
}
public static void main(String[] args) {
Hero hp= new Hero("兵长",12,100,12);
System.out.println(hp.armor);
hp.showAddressInMemory();
}
}
结果:
3.传参
eg
main{ int xueping = 100;
teemo.huixue(xueping);
System.out.println(xueping);
}
public void huixue(int xp){
xp=0;
}
则输出的仍为100,没变
eg:
public void attack(Hero hero, int damage) {
hero.hp = hero.hp - damage;
}
public static void main(String[] args) {
Hero teemo = new Hero("提莫", 383);
garen.attack(teemo, 100);
System.out.println(teemo.hp);
}
则输出的为283,变
- 包
- 修饰符
继承就是extend后,这个类有了父类的字段和方法 (获得了父类属性)
访问就是new了对象后,能直接对象。父类方法或者字段(查看父类属性)
- private修饰的字段或方法,除了自己这个类,其他类都不能访问和继承
- 默认的字段属性,同一个包下的类都可以继承或者访问,不同包则不行
- protected修饰的字段或方法,同包可以继承和访问;但是不同包的类只能继承,不能访问查看
- public修饰的字段或方法,都能访问,都能继承
- 别忘记final关键字
- 类属性static
类属性是公有的,一变都变
- 类方法static
不需要对象的存在,直接就访问;功能性色彩
- 属性初始化
eg:对象属性的初始化有三种方式
这三种方式,谁先执行?谁后执行?
public class Hero {
public String name = "some hero";
public Hero(){
name = "one hero";
}
{
name = "the hero";
}
}
解析:
【实践打印】先设计一个类方法 public static String getName(String pos)
在属性初始化的时候,调用这个方法的返回值。 观察这个方法的输出顺序
package charactor;
public class Hero {
public String name =Hero.getName("属性声明") ;
public Hero(){
name = Hero.getName("构造方法");
}
{
name = Hero.getName("初始化块");
}
public static String getName(String pos){
System.out.println(pos);
return pos;
}
public static void main(String[] args) {
new Hero();
}
}
得到
- 单例模式
饿汉/懒汉(尤其是视频)
三要素 :1.构造方法私有化 (private) 2.类属性实例化一次 (private static) 3.类方法getInstance,返回上一步的类属性。(public static)
这样,外部无法通过new 得到新的实例
- 枚举类型
枚举enum的地位和class一样,是一种特殊的类
1.预先定义常数
public enum Season {
SPRING,SUMMER,AUTUMN,WINTER
}
2.不能实例化。
- Season jijie= new Season(); 会报错
- Season jijie= Season.SPRING; ✔
3.常用于固定情景,如switch。
使用枚举,就能把范围死死的限定在这目标范围当中
4.遍历枚举:通过 values返回数组
Season a[]=Season.values(); //values返回枚举数组
for(Season i:a)
{
System.out.println(i);
}
二、接口与继承
-
接口
AD.java:
package character;
//设计了这么一个接口,在接口里规定了他会物理攻击这个方法。
public interface AD {
public void physicAttack();//仅声明了方法,没有方法体。
}
//某一个类如果要实现这个接口,就必须要提供这里边的这个方法。
ADhero.java:
package charactor;
public class ADHero extends Hero implements AD{
//某一个类如果要实现这个接口,就必须要提供这里边的这个方法。
@Override //只是一个规范化注解
public void physicAttack() {
System.out.println("进行物理攻击");
}
}
- 对象转型
- 向上转型(子类转化成父类,类转化为接口)都成功;反之不一定
练习1:
package charactor;
import charactor1.Support;
public class Hero {
public String name;
protected float hp;
public static void main(String[] args) {
Hero h =new Hero();
ADHero ad = new ADHero();
Support s =new Support();
h = ad;
ad = (ADHero) h;
h = s;
ad = (ADHero)h;
}
}
以上 1.前情:ADHero和Support都是Hero的继承,是其子类
2. Hero ad = new Hero();
引用 指向 对象类型
3. h = ad; //子类转成父类,恒成立
Hero类 指向 ADHero类
ad = h; //父类转成子类,不一定
ADHero类 指向 Hero
第一个 ad = (ADHero) h; //成立
ADHero类 指向 Hero被强制转化成ADHero类
第二个 ad = (ADHero) h; //不成立
ADHero类 指向 support无法强制转化成adhero,因为没有继承关系
练习2:
package charactor;
public class Hero {
public String name;
protected float hp;
public static void main(String[] args) {
ADHero ad = new ADHero();
AD adi = ad;
ADHero adHero = (ADHero) adi;
adapHero.magicAttack();
}
}
以上 1. AD adi = ad;
把一个ADHero类型转换为AD接口
从语义上来讲,把一个ADHero当做AD来使用,而AD接口只有一个
physicAttack方法,这就意味着转换后就有可能要调用physicAttack
方法,而ADHero一定是有physicAttack方法的,所以转换是能成功的。
2. ADHero adHero = (ADHero) adi;
adi引用所指向的对象是一个ADHero,要转换为ADAPHero就会
失败。假设能够转换成功,那么就可以使用magicAttack方法,而
adi引用所指向的对象ADHero是没有magicAttack方法的。
- instanceof
//判断引用h1指向的对象,是否是ADHero类型
System.out.println(h1 instanceof ADHero);
//判断引用h1指向的对象,是否是Hero的子类型
System.out.println(h1 instanceof Hero);
重写
关键:子类继承父类后,于子类中重新提供该方法。
是子类覆盖父类的对象方法
隐藏:
是子类覆盖父类的类方法
∵是类方法,所以调用只与其类型有关,而与指向哪个对象无关
- 多态
-要实现类的多态,需要如下条件
1. 父类(接口)引用指向子类对象
2. 调用的方法有重写
练习
1. 设计一个接口
接口叫做Mortal,其中有一个方法叫做die
2. 实现接口
分别让ADHero,APHero,ADAPHero这三个类,实现Mortal接口,不同的
类实现die方法的时候,都打印出不一样的字符串
3. 为Hero类,添加一个方法,在这个方法中调用 m的die方法。
public void kill(Mortal m)
4. 在主方法中
首先实例化出一个Hero对象:盖伦
然后实例化出3个对象,分别是ADHero,APHero,ADAPHero的实例
然后让盖伦 kill 这3个对象
代码如下:
----------------------------------------------------------------------------------------------
1.29
一、接口与继承(续上)
使用关键字super 显式调用父类带参的构造方法
则实例化子类的时候,调用父类有参的构造方法。
对比:关键词this调用当前对象
eg:
\ !结果
但是,当父类没有无参构造方法的时候( 提供了有参构造方法,并且不显示提供无参构造方法),子类就会抛出异常,因为它尝试去调用父类的无参构造方法。
遇到这种情况,有2种解决办法。
第一,把父类当中的无参构造方法补上去。
第二,不补父类的无参构造方法,直接调用父类存在的的有参构造方法,但是参数为空字符,即super(“ ”)
package character;
public class Hero {
public String name;
public float price;
//toString()的意思是返回当前对象的字符串表达
public String toString()
{
return "这位"+name+"怒气值"+price;
}
//当一个对象没有任何引用指向的时候,它就满足垃圾回收的条件
//当它被垃圾回收的时候,它的finalize() 方法就会被调用
public void finalize()
{
System.out.println("他的团长被回收了");
}
//equals() 用于判断两个对象的内容是否相同
public boolean equals(Object o)
{
if(o instanceof Hero){
Hero oo=(Hero) o;
return(this.price==oo.price); //更准确的讲,==用于判断两个引用,是否指向了同一个对象
}
return false;
}
public static void main(String[] args) {
for (int i = 0; i < 80000; i++) {
//不断生成新的对象
//每创建一个对象,前一个对象,就没有引用指向了
//那些对象,就满足垃圾回收的条件
//当,垃圾堆积的比较多的时候,就会触发垃圾回收
//一旦这个对象被回收,它的finalize()方法就会被调用
Hero h= new Hero();
}
Hero h1= new Hero();
h1.name = "兵长";
h1.price=10000f;
Hero h2= new Hero();
h2.price=1000f;
System.out.println(h1.toString());
System.out.println(h1.equals(h2));
}
}
-
abstract抽象类
抽象方法:
在类中声明一个方法,这个方法没有实现体,是一个“空”方法
抽象类:
一旦一个类被声明为抽象类,就不能够被直接实例化
当一个类有抽象方法的时候,该类必须被声明为抽象类
package charactor;
public abstract class Hero {
String name;
float hp;
float armor;
int moveSpeed;
public static void main(String[] args) {
}
// 抽象方法attack
// Hero的子类会被要求实现attack方法
public abstract void attack();
}
抽象类和接口的区别
区别1:
子类只能继承一个抽象类,不能继承多个
子类可以实现多个接口
区别2:
抽象类可以定义
public,protected,package,private
静态和非静态属性
final和非final属性
但是接口中声明的属性,只能是public static final的
即便没有显式的声明,也是这么默认的
1.
{
非
静
态
内
部
类
:
n
e
w
外
部
类
对
象
内
部
类
(
)
;
静
态
内
部
类
:
n
e
w
外
部
类
.
静
态
内
部
类
(
)
;
匿
名
类
:
声
明
一
个
类
的
同
时
实
例
化
它
本
地
类
:
申
明
时
无
需
与
属
性
和
方
法
平
等
\left\{ \begin{matrix} 非静态内部类 : new 外部类对象内部类(); \\ \\静态内部类:new 外部类.静态内部类(); \\ \\匿名类:声明一个类的同时实例化它 \\ \\本地类:申明时无需与属性和方法平等 \end{matrix} \\ \right.
⎩⎪⎪⎪⎪⎪⎪⎪⎪⎨⎪⎪⎪⎪⎪⎪⎪⎪⎧非静态内部类:new外部类对象内部类();静态内部类:new外部类.静态内部类();匿名类:声明一个类的同时实例化它本地类:申明时无需与属性和方法平等
详见内部类
- 匿名类举例:
public abstract class Hero {
public abstract void seal();//声明抽象方法。
public static void main(String[] args) {
//匿名类
Hero bz=new Hero(){ //直接实例化一个抽象类
public void seal(){ //并“当场”实现其抽象方法。
System.out.println("binzhang");
}
};
bz.seal();
}
}
- 在匿名类中使用外部的局部变量,外部的局部变量必须修饰为final
-接口也可以提供具体方法
-声明成 default
package charactor;
public interface Mortal {
public void die();
default public void revive() { //默认方法revive
System.out.println("本英雄复活了");
}
}
二、练习
练习-Animal类
- 创建Animal类,它是所有动物的抽象父类。
- 声明一个受保护的整数类型属性legs,它记录动物的腿的数目。
- 定义一个受保护的构造器,用来初始化legs属性。
- 声明抽象方法eat。
- 声明具体方法walk来打印动物是如何行走的(包括腿的数目)。
练习-Spider类
- Spider继承Animal类。
- 定义默认构造器,它调用父类构造器来指明所有蜘蛛都是8条腿。
- 实现eat方法
练习-Pet接口
根据UML类创建pet(宠物)接口
- 提供getName() 返回该宠物的名字
- 提供setName(String name) 为该宠物命名
- 提供 play()方法
练习-Cat类
- 该类必须包含String属性来存宠物的名字。
- 定义一个构造器,它使用String参数指定猫的名字;该构造器必须调用超类构造器来指明所有的猫都是四条腿。
- 另定义一个无参的构造器。该构造器调用前一个构造器(用this关键字)并传递一个空字符串作为参数
- 实现Pet接口方法。
- 实现eat方法。
public abstract class Animal {
protected int legs;
protected Animal(int legs)
{
this.legs=legs;
}
public abstract void eat();
public void walk(){
System.out.println("动物走路用"+legs+"只脚");
}
}`
package exercise;
public class Spider extends Animal{
public void eat(){
System.out.println("实现了eat方法");
}
public Spider(){
super(8);
}
}
package exercise;
public interface pet {
public String getName();
public void setName(String name);
public void play();
}
package exercise;
public class Cat extends Animal implements pet{
// 该类必须包含String属性来存宠物的名字。
private String name="猫";
//定义一个构造器,它使用String参数指定猫的名字;该构造器必须调用超类构造器来指明所有的猫都是四条腿。
public Cat(String name){
super(4);
this.name=name;
}
// 另定义一个无参的构造器。该构造器调用前一个构造器(用this关键字)并传递一个空字符串作为参数
public Cat(){
this(" ");
}
//实现Pet接口方法。
@Override
public String getName(){
return name;
}
@Override
public void setName(String name){
this.name=name;
System.out.println("实现setname方法");
}
@Override
public void play(){
System.out.println("实现play方法");
}
// 实现eat方法。
public void eat(){
System.out.println("实现eat方法");
}
}
三、日期
- Date类
– java.util.Date
–时间原点(1970年),过一毫秒则+1
–基本用法:
new Date():当前时间
new Date(数字x):表示从原点开始,+x毫秒后的时间
getTime():表示从原点开始经历的毫秒数
package date;
import java.util.Date;
//注意:是java.util.Date;
//而非 java.sql.Date,此类是给数据库访问的时候使用的
public class TestDate {
public static void main(String[] args) {
Date now= new Date();
//打印当前时间
System.out.println("当前时间:"+now);
Date zero = new Date(0);
System.out.println("用0作为构造方法,得到的日期是:"+zero);
Date zero2 = new Date(5000);
System.out.println("从1970年1月1日 早上8点0分0秒 开始经历了5秒的时间"+zero2);
//getTime() 得到一个long型的整数
//这个整数代表 1970.1.1 08:00:00:000,每经历一毫秒,增加1
System.out.println("当前时间getTime()返回的值是:"+now.getTime());
}
}
package date;
//
import java.text.SimpleDateFormat;
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
//y 代表年
//M 代表月
//d 代表日
//H 代表24进制的小时
//h 代表12进制的小时
//m 代表分钟
//s 代表秒
//S 代表毫秒
SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS" );
Date d= new Date();
String str = sdf.format(d);
System.out.println("当前时间格式化后的输出: "+str);
}
}
ADD: syso出的都是String类型,所以日期类如果要syso输出,需要先format成String。
- 字符串转日期:parse
–import java.text.ParseException;
package date;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class TestDate {
public static void main(String[] args) {
SimpleDateFormat sdf =new SimpleDateFormat("yyyy/MM/dd HH:mm:ss" );
String str = "2016/1/5 12:12:12";
System.out.println(str);
try {
//字符串通过格式转换为日期对象
Date d = sdf.parse(str);
System.out.println(d);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
练习-日期格式化
准备一个长度是9的日期数组
使用1970年-2000年之间的随机日期初始化该数组
按照这些日期的时间进行升序排序
比如 1988-1-21 12:33:22 就会排在 1978-4-21 19:07:23 前面,因为它的时间更小,虽然日期更大
package date;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class TestDate {
public static Date getRandomDate(int start,int end)
{
SimpleDateFormat sdf =new SimpleDateFormat("yyyy");
try{
//将年份转化为字符串,再转化成日期类型
Date dstart=sdf.parse(String.valueOf(start));//将基本数据型态转换成 String 的 static 方法
Date dend=sdf.parse(String.valueOf(end+1));// 2001 不是 2000,要在2001的基础上减少以毫秒,才表示2000最后一刻
//获得相对时间原点,并进行随机分布
long tstart=dstart.getTime();
long tend=dend.getTime();
long timeRandom = (long) (tstart + Math.random() * (tend - tstart));
Date randomDate=new Date(timeRandom);
return randomDate;
}catch(ParseException e){
e.printStackTrace();
}
return null;
}
//日期转化为字符串格式
public static String toString(Date d, String format) {
SimpleDateFormat sdf = new SimpleDateFormat(format);
return sdf.format(d);
}
public static void main(String[] args) {
//准备一个长度是9的日期数组
Date d[]=new Date[9];
//使用随机日期初始化该数组
for(int i=0;i<d.length;i++)
{
d[i]=getRandomDate(1970,2000);
}
//输出日期数组
System.out.println("得到的随机日期数组:");
for(int i=0;i<d.length;i++)
{
//日期转化为字符串输出
System.out.println(toString(d[i],"yyyy-MM-dd HH:mm:ss")+"\t");
if(i%3==2)
System.out.println();
}
//选择法排序
for (int i = 0; i < d.length-1; i++) {
for (int j = i+1; j < d.length; j++) {
//日期转字符串
String istr = toString(d[i],"HHmmss");
String jstr = toString(d[j],"HHmmss");
//字符串转整型
int ilnt = Integer.parseInt(istr);
int jlnt = Integer.parseInt(jstr);
//排序
if( ilnt>jlnt ){
Date temp = d[j];
d[j] = d[i];
d[i] = temp;
}
}
}
//输出排序后日期数组
System.out.println("排序后的随机日期数组:");
for (int i = 0; i < d.length; i++) {
System.out.print(toString(d[i],"yyyy-MM-dd HH:mm:ss")+"\t");
if(2==i%3)
System.out.println();
}
}
}
Calendar类
常用于进行“翻日历”,比如下个月的今天是多久
- Calendar与Date进行转换
import java.util.Calendar;
import java.util.Date;
public class TestDate {
public static void main(String[] args) {
//采用单例模式获取日历对象Calendar.getInstance();
Calendar c = Calendar.getInstance();
System.out.println("1:"+c);
//通过日历对象得到日期对象
Date d = c.getTime();
System.out.println("2:"+d);
Date d2 = new Date(0);
System.out.println("3:"+d2);
c.setTime(d2); //把这个日历,调成日期 : 1970.1.1 08:00:00
System.out.println("4:"+d2);
System.out.println("5:"+c);
}
}
- 翻日历
add方法,在原日期上增加年/月/日
set方法,直接设置年/月/日/
Calendar c = Calendar.getInstance();
Date now = c.getTime();
// 下个月的今天
c.setTime(now);
c.add(Calendar.MONTH, 1);
System.out.println("下个月的今天:\t" +format(c.getTime()));
// 去年的今天
c.setTime(now);
c.add(Calendar.YEAR, -1);
System.out.println("去年的今天:\t" +format(c.getTime()));
// 上个月的第三天
c.setTime(now);
c.add(Calendar.MONTH, -1);
c.set(Calendar.DATE, 3);
System.out.println("上个月的第三天:\t" +format(c.getTime()));
**练习-Calendar**
== 找出下个月的倒数第3天是哪天==
package date;
//
import java.util.Calendar;
import java.util.Date;
import java.text.SimpleDateFormat;
public class TestDate {
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
public static void main(String[] args) {
//采用单例模式获取日历对象Calendar.getInstance();
Calendar c = Calendar.getInstance();
//通过日历对象得到日期对象
//***输出方法一
Date d = c.getTime();
System.out.println("今天是:"+sdf.format(d));
//先翻到下下个月
c.add(Calendar.MONTH,2);
//设置到月初
c.set(Calendar.DATE,1);
//再往回翻3天
c.add(Calendar.DATE,-3);
//***输出方法二
String str=sdf.format(c.getTime());
System.out.println("这个月的倒数第三天:"+str);
}
}
//两种输出方法,其实质都是把日历------》日期------》字符串------》输出
// (getTime) (format) (syso)
----------------------------------------------------------------------------------------------
1.30
=
一、数字与字符串
-
封装类
即:所有的基本类型对应的类类型
比如int对应的类是Integer -
拆装箱
基本类型和封装类型间的相互转化
两种方法
-
最大值、最小值
封装类.MAX_VALUE
封装类.MIN_VALUE
用于
- 字符串转换
步骤 1 : 数字转字符串
步骤 2 : 字符串转数字
比如:String类与int类转化,Integer为中介
- 数学方法
- java.lang.Math
- 静态方法:
四舍五入(round), 随机数(random),开方(sqrt),次方(pow)
π(PI),自然常数(E)
练习:求1000,0000内质数个数 方一:`
package digit;
public class TestNumber {
public static void main(String[] args){
int n=0;
for(int i=1;i<=10000000;i++){
int flag=1;
for (int j = 2; j <=Math.sqrt(i); j++) {
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
n++;
}
System.out.println(n);
}
}
方二:
package digit;
public class TestNumber {
public static void main(String[] args) {
int max = 10000*1000;
int count = 0 ;
for (int i = 1; i <=max; i++) {
if(isPrime(i)){
count++;
}
}
System.out.println("一千万以内的质数一共有 : " + count);
}
private static boolean isPrime(int i) {
for (int j = 2; j <= Math.sqrt(i); j++) {
if(0==i%j)
return false;
}
return true;
}
}
-
格式化输出
-printf和println
eg:
//直接使用+进行字符串连接,
System.out.println( name+ " 在进行了连续 " + kill);
//使用格式化输出
System.out.printf("%s 在进行了连续 %d " ,name,kill);
- %n换行,%r回车- printf和format能够达到一模一样的效果
- 总长度,左对齐,补0,千位分隔符,小数点位数,本地化表达
int year = 2020;
//直接打印数字
System.out.format("%d%n",year);
//总长度是8,默认右对齐
System.out.format("%8d%n",year);
//总长度是8,左对齐
System.out.format("%-8d%n",year);
//总长度是8,不够补0
System.out.format("%08d%n",year);
//千位分隔符
System.out.format("%,8d%n",year*10000);
//小数点位数
System.out.format("%.2f%n",Math.PI);
输出:
字符
char, Character
- 字符转成字符串
String a = 'a'; //不能够直接把一个字符转换成字符串
String a2 = Character.toString('a'); //转换为字符串
- 字符串转化为字符数组
String str = "abc123";
char[] cs = str.toCharArray();
- 一个 \t 制表符长度是8,可以达到对齐的效果
System.out.println("abc\tdef");
System.out.println("ab\tdef");
System.out.println("a\tdef");
-
字符串
Java中,字符串是一个类,所以我们见到的字符串都是对象
字符串创建好后,不可改变。
String类 不能被继承常见创建字符串手段:
-
每当有一个字面值出现的时候,虚拟机就会创建一个字符串
-
调用String的构造方法创建一个字符串对象
String teemo = new String(“提莫”); // 通过String创建了一个字符串对象
char[] cs = new char[]{‘崔’,‘斯’,‘特’};
String hero = new String(cs); // 通过字符数组创建一个字符串对象
-
通过+加号进行字符串拼接也会创建新的字符串对象
-
练习:创建一个长度是5的随机字符串,随机字符有可能是数字,大写字母或者小写字母
package digit;
public class TestNumber {
public static void main(String[] args) {
int n=0;
String str="";
while(n<5)
{
//ASCII表中,‘0’到‘z‘间包含的所有字符
char aa=(char)(Math.random()*74+48);
//挑出满足的字符
if(Character.isDigit(aa)||Character.isLetter(aa))
{
str+=aa; //通过+加号进行字符串拼接也会创建新的字符串对象
n++;
}
}
System.out.println(str);
}
}
练习:字符串数组排序
创建一个长度是8的字符串数组
使用8个长度是5的随机字符串初始化这个数组
对这个数组进行排序,按照每个字符串的首字母排序(无视大小写)
package digit;
public class TestNumber {
//创建长度是5的随机字符串
static String randomString(){
int n=0;
String str="";
while(n<5)
{
//ASCII表中,‘0’到‘z‘间包含的所有字符
char aa=(char)(Math.random()*74+48);
//挑出满足的字符
if(Character.isDigit(aa)||Character.isLetter(aa))
{
str+=aa; //通过+加号进行字符串拼接也会创建新的字符串对象
n++;
}
}
return str;
}
//返回该字符串的第一个首字母
static char getFirstletter(String str)
{
char []c =str.toCharArray();
for (int i = 0; i < c.length; i++) {
if(c[i]>='0'&&c[i]<='9')
continue;
if(c[i]>='a'&&c[i]<='z')
c[i]-=32;
return c[i];
}
return 0;
}
public static void main(String[] args) {
//创建一个长度是8的字符串数组
String []a=new String[8];
//使用随机字符串初始化这个数组
System.out.println("原数组为:");
for(int i=0;i<a.length;i++)
{
a[i]= randomString();
System.out.printf("%s ",a[i]);
}
//对这个数组按照每个字符串的首字母排序(无视大小写)
char cc[]=new char[8];
for(int i=0;i<a.length;i++)
{
cc[i]= getFirstletter(a[i]);
//System.out.printf("%c ",cc[i]);
}
//按照每个字符串的首字母选择排序
for (int j = 0; j < cc.length-1; j++) {
for (int k = j+1; k < cc.length; k++) {
if(cc[k]<cc[j]){
String temp = a[j];
a[j] = a[k];
a[k] = temp;
char TEMP = cc[j];
cc[j] = cc[k];
cc[k] = TEMP;
}
}
}
//输出排序后的数组
System.out.println("");
System.out.println("排序后数组为:");
for(int i=0;i<a.length;i++)
{
System.out.printf("%s ",a[i]);
}
}
}
练习:破解密码
-
生成一个长度是3的随机字符串,把这个字符串作为当做密码
-
使用穷举法生成长度是3个字符串,匹配上述生成的密码
package digit;
public class TestNumber {
//创建长度是3的随机字符串
static String randomString(){
int n=0;
String str="";
while(n<3)
{
//ASCII表中,‘0’到‘z‘间包含的所有字符
char aa=(char)(Math.random()*74+48);
//挑出满足的字符
if(Character.isDigit(aa)||Character.isLetter(aa))
{
str+=aa; //通过+加号进行字符串拼接也会创建新的字符串对象
n++;
}
}
return str;
}
//使用递归生成 长度为3的字符串,并匹配
public static boolean found=false;
//递归
public static void generate(char[] guessword,int index,String password){
if(found)
return;
//生成
for(char c='0';c<='z';c++)
{
if(!Character.isLetterOrDigit(c))
continue;
guessword[index]=c;
//下一层
if(index!=guessword.length-1){
generate(guessword,index+1,password);
}
//最后一层
else{
String guess= new String(guessword);
//匹配
if(guess.equals(password)){
System.out.println("找到了,密码是" + guess);
found =true;
}
}
}
}
public static void main(String[] args) {
String password= randomString();
System.out.println("密码是:" + password);
char[] guessword=new char[3];
generate(guessword,0,password);
}
}
- 字符串基本操作
- .charAt(int index) :获取指定位置的字符(基0)
.toCharArray(): 获取对应的字符数组
.substring(int):截取子字符串(基0)(“左开右闭”或“从左边开始”)
.split(char c) 分隔 (根据分隔符进行分隔,得到几个字符串)
.trim() 去掉首尾空格
.toLowerCase()
.toUpperCase() 大小写
.indexOf(char)
.lastIndexOf(char)
.contains(char) 定位
.replaceAll(char,char)
.replaceFirst(char,char) 替换
练习:每个单词的首字母都转换为大写
给出一句英文句子: “let there be light”
得到一个新的字符串,每个单词的首字母都转换为大写
解析:
句子------------------ 单词---------------------字母
字符串(间隔符) 字符串数组 (字符数组) 字符
package digit;
public class TestNumber {
public static void main(String[] args) {
//字符串
String s = "let there be light";
System.out.println(s);
//字符串数组
String words[]=s.split(" ");
for(int i=0;i<words.length;i++){
//首字符
char FirstLetter = Character.toUpperCase(words[i].charAt(0));
//剩余字符
String rest=words[i].substring(1);
//组建1
words[i]=FirstLetter+rest;
}
//组建2(成字符串)
String result="";
for(String word : words){
result+=word+" ";
}
result=result.trim();
System.out.println(result);
}
}
练习:单词间隔大写小写模式
把 lengendary 改成间隔大写小写模式,即 LeNgEnDaRy
package digit;
public class TestNumber {
public static void main(String[] args) {
String s = "lengendary";
char[] cs =s.toCharArray();
for (int i = 0; i < cs.length; i++) {
if(0==i%2)
cs[i] = Character.toUpperCase(cs[i]);
}
String result = new String(cs);
System.out.printf(result);
}
}
**练习:把最后一个two单词首字母大写 **
Nature has given us that two ears, two eyes, and but one tongue, to the end that we should hear and see more than we speak
把最后一个two单词首字母大写
package digit;
public class TestNumber {
public static void main(String[] args) {
String s = "Nature has given us that two ears, two eyes, and but one tongue, to the end that we should hear and see more than we speak";
char sc[]=s.toCharArray();
int location=s.lastIndexOf("two");
sc[location]='T';
String result="";
for(char i:sc)
{
result+=i;
}
System.out.printf(result);
}
}
使用equals进行字符串内容的比较,必须大小写一致
equalsIgnoreCase,忽略大小写判断内容是否一致
eg:
str1.equals(str2)
str1.equalsIgnoreCase(str3)
返回true/false
- 所指对象是否相同:==
- 是否以子字符串开始或者结束顶折纠问
startsWith //以…开始
endsWith //以…结束
练习:比较字符串
创建一个长度是100的字符串数组
使用长度是2的随机字符填充该字符串数组
统计这个字符串数组里重复的字符串有多少种
如:
package digit;
public class TestNumber {
//创建长度是2的随机字符串
static String randomString(){
int n=0;
String str="";
while(n<2)
{
//ASCII表中,‘0’到‘z‘间包含的所有字符
char aa=(char)(Math.random()*74+48);
//挑出满足的字符
if(Character.isDigit(aa)||Character.isLetter(aa))
{
str+=aa; //通过+加号进行字符串拼接也会创建新的字符串对象
n++;
}
}
return str;
}
static String[]cc = new String[100];
static int pos=0;
private static int putIntoDuplicatedArray(String s) {
int flag=1;
for (int i = 0; i < pos; i++) {
if(s.equals(cc[i])==true){
flag=0;
break;
}
}
if(flag==1){
cc[pos++]=s;
return 1;
}
else
return 0;
}
public static void main(String[] args) {
//创建一个长度是100的字符串数组
int count=0;
String []a=new String[100];
//使用随机字符串初始化这个数组
System.out.println("原数组为:");
for(int i=0;i<a.length;i++)
{
a[i]= randomString();
System.out.printf("%s ",a[i]);
}
for(int i=0;i<a.length;i++){
int flag=0;
for(int j=i+1;j<a.length;j++){
if(a[i].equals(a[j]))
{
flag++;
if(flag==1)
count+=putIntoDuplicatedArray(a[i]);
break;
}
}
}
System.out.println("");
System.out.println("有"+count+"种重复");
for(int i=0;i<pos;i++){
System.out.println("它是:"+cc[i]);
}
}
}
输出结果:
============================================================================================================================================
1.31
- StringBuffer是可变长的字符串(基0)
- 本质:留有冗余长度
- 基本操作:
append(String str); //追加字符串
append(char c); //追加字符
insert(int pos,char b); //指定位置插入字符
insert(int pos,String b); //指定位置插入字符串
delete(int start); //从开始位置删除剩下的
delete(int start,int end); //从开始位置删除结束位置-1
reverse(); //反转
length(); //返回长度
String str1 = "let there ";
StringBuffer sb = new StringBuffer(str1); //根据str1创建一个StringBuffer对象
//其实也可以直接创建 StringBuffer sb = new StringBuffer();
sb.append("be light"); //在最后追加
System.out.println(sb);
sb.delete(4, 10);//删除4-10之间的字符
System.out.println(sb);
sb.insert(4, "there ");//在4这个位置插入 there
System.out.println(sb);
sb.reverse(); //反转
System.out.println(sb);
length: “the”的长度 3
capacity: 分配的总空间 19
解析:插入insert 和 append
(1)边界条件判断
插入之前,首先要判断的是一些边界条件。 比如插入位置是否合法,插入的字符串是否为空
(2)扩容
1. 要判断是否需要扩容。 如果插入的字符串加上已经存在的内容的总长度超过了容量,那么就需要扩容。
2. 数组的长度是固定的,不能改变的,数组本身不支持扩容。 我们使用变通的方式来解决这个问题。
3. 根据需要插入的字符串的长度和已经存在的内容的长度,计算出一个新的容量。 然后根据这个容量,创建一个新的数组,接着把原来的数组的内容,复制到这个新的数组中来。并且让value这个引用,指向新的数组,从而达到扩容的效果。
(3)插入字符串
1. 找到要插入字符串的位置,从这个位置开始,把原数据看成两段,把后半段向后挪动一个距离,这个距离刚好是插入字符串的长度
2. 然后把要插入的数据,插入这个挪出来的,刚刚好的位置里。
(4)修改length的值
最后修改length的值,是原来的值加上插入字符串的长度
(5)insert(int, char)
参数是字符的insert方法,通过调用insert(int, String) 也就实现了。
append
追加,就是在最后位置插入。 所以不需要单独开发方法,直接调用insert方法,就能达到最后位置插入的效果
delete
代码如下:
IStringBuffer.java
package digit;
public interface IStringBuffer {
public void append(String str); //追加字符串
public void append(char c); //追加字符
public void insert(int pos,char b); //指定位置插入字符
public void insert(int pos,String b); //指定位置插入字符串
public void delete(int start); //从开始位置删除剩下的
public void delete(int start,int end); //从开始位置删除结束位置-1
public void reverse(); //反转
public int length(); //返回长度
}
MyStringBuffer.java
package digit;
public class MyStringBuffer implements IStringBuffer{
int capacity = 16;
int length = 0;
char[] value;//value:用于存放字符数组
//无参构造方法
public MyStringBuffer(){
value = new char[capacity];//根据容量初始化value
}
//有参构造方法
public MyStringBuffer(String str){
this();
if(null==str)
return;
if(capacity<str.length()){
capacity = value.length*2;
value=new char[capacity];
}
if(capacity>=str.length())
System.arraycopy(str.toCharArray(), 0, value, 0, str.length());
// 或:value =str.toCharArray();(字符数组指向字符串转化过来的字符数组)
length = str.length();
}
@Override
//追加字符串
public void append(String str) {
insert(length,str);
}
//追加字符
@Override
public void append(char c) {
append(String.valueOf(c));
}
//指定位置插入字符
@Override
public void insert(int pos, char b) {
insert(pos,String.valueOf(b));
}
@Override
//从开始位置删除剩下的
public void delete(int start) {
delete(start,length);
}
@Override
//从开始位置删除结束位置-1
public void delete(int start, int end) {
//边界条件判断
if(start<0)
return;
if(start>length)
return;
if(end<0)
return;
if(end>length)
return;
if(start>=end)
return;
System.arraycopy(value, end, value, start, length- end);
length-=end-start;
}
@Override
//反转
public void reverse() {
for (int i = 0; i < length/2; i++) {
char temp = value[i];
value[i] = value[length-i-1];
value[length-i-1] = temp;
}
}
@Override
//返回长度
public int length() {
// TODO Auto-generated method stub
return length;
}
@Override
//指定位置插入字符
public void insert(int pos, String b) {
//边界条件判断
if(pos<0)
return;
if(pos>length)
return;
if(null==b)
return;
//扩容
while(length+b.length()>capacity){
capacity = (int) ((length+b.length())*2.0f);
//因为数组长度不能变
//等号右边:创建一个新的字符数组 ;等号左边:通过一个新的引用指向这个字符数组
char[] newValue = new char[capacity];
System.arraycopy(value, 0, newValue, 0, length);//把老的数组(内容)复制到新的数组
value = newValue;//通过老引用=新引用,让value间接指向一个新的字符数组
}
char[] cs = b.toCharArray();
//通过复制arraycopy
//先把已经存在的数据往后移
System.arraycopy(value, pos, value,pos+ cs.length, length-pos);
//把要插入的数据插入到指定位置
System.arraycopy(cs, 0, value, pos, cs.length);
length = length+cs.length;
}
//返回真正有效(有内容)的字符串
public String toString(){
char[] realValue = new char[length];
System.arraycopy(value, 0, realValue, 0, length);
return new String(realValue);
}
public static void main(String[] args) {
MyStringBuffer sb = new MyStringBuffer("there light");
System.out.println(sb);
sb.insert(0, "let ");
System.out.println(sb);
sb.insert(10, "be ");
System.out.println(sb);
sb.insert(0, "God Say:");
System.out.println(sb);
sb.append("天哪");
System.out.println(sb);
sb.append('?');
System.out.println(sb);
sb.reverse();
System.out.println(sb);
sb.reverse();
System.out.println(sb);
sb.delete(0,4);
System.out.println(sb);
sb.delete(4);
System.out.println(sb);
}
}
输出:
---------------------------------------------------------------------------------------------------------------------------
小fleeting的寒假宅喵java学习 基础篇在此就告一段落啦!!! 呼,花了快一周的时间, 不过小fleeting很有成就感💪 寒假宅味之 《进阶收获upup篇》 马上就要来啦 ~~要follow下去呦~ 下一夜,我也会向你展示一个甜美的梦… |