快捷键
- 批量修改 Alt Shift R
- 打println一行 syso Alt /
- 快速输入for循环 for Alt /
- 注释 选中要变成注释的代码 Ctrl Shift c
- 错误提示 在错误的地方Ctrl 1
变量类型
- 字符型char只能存放一个字符
- 默认的小数值是double类型的,在小数后面加f可把该数字声明为float类型
- 布尔型用于表示真假,真正存放的数据是0,1,但是不能用于赋值
- String类型不是基本类型
字面值
double a1=3.24;
int a2=123;
这里,3.24,123就是字面值
- 以L结尾的字面值就是long型
- 对于int类型,字面值前加0x即为十六进制
- 字面值前加0为八进制
- 0b开头为二进制
- 浮点数可以用科学计数法,如e2等于十的二次方
\表示转义
char tab ='\t';//制表符
char carriageReturn = '\r';//回车(清除该行的字符,并将光标移到该行首位)
char newline = '\n';//回车(换行)
char doubleQuote = '\"' ;//双引号
char singleQuote = '\'';//单引号
char backslash = '\\';//反斜杠
命名
- 最好使用完整单词命名便于理解
- 可以包含关键字
- 数字不能是第一个字符
- 符号只能包含$ _
作用域
- 定义在类下的变量被称为属性,其作用域是声明位置开始到整个类
- 变量声明在方法上叫参数,其作用域是该方法
- 生命在方法内的叫局部变量,其作用域是从声明位置到其所处于的块结束的位置
- 当访问变量被多个作用域影响的时候,按照就近原则
final
- final修饰一个变量,该变量只有一次赋值的机会
- final修饰的全局变量应在声明时赋值
- final修饰的类不能被继承
- final定义的方法不能被重写
运算符
- 关于自增一道题
int i=1;
int j = ++i + i++ + ++i + ++i + i++;
答案18
- 短路与 && 如果左边为false就不会计算右边了
- 长路与 & 两边无论如何都会执行
- 短路或 || 如果左边为true就不会计算右边了
- 长路或 | 两边无论如何都会计算
- 异或 ^ 和!属性正好相反
三元操作符
- 表达式?值1:值2
- 真返回值1,假返回值2
- 定义一个返回值类型的数等于表达式
一个代码理解,‘ 判断是否是工作日 ’
Scanner cin=new Scanner(System.in);
System.out.println("请输入今天星期几:");
int day=cin.nextInt();
String a= day>=6 ?"是周末":"工作日";
System.out.println("今天是"+a);
输入
注意,在用nextInt()读出整数之后,再接着读取字符串的话,读取来的将是换行或者回车(因为在键盘输入数字后会输入回车或换行结束操作,而nextInt只能读取数字不能读取回车或者换行),所以要注意想要接着读出字符串的话,得写两个nextLine
如:
Scanner cin=new Scanner(System.in);
int a=cin.nextInt();
System.out.println(a);
String b=cin.nextLine();
String d=cin.nextLine();
System.out.println(d);
此时,输入2输出2 再输入abc输出abc
switch
例(注意不要遗漏break)
Scanner cin=new Scanner(System.in);
System.out.println("请输入月份:");
int month=cin.nextInt();
String season="";
switch(month){
case 1:
case 2:
case 3:
season="春天";
break;
case 4:
case 5:
case 6:
season="夏天";
break;
case 7:
case 8:
case 9:
season="秋天";
break;
case 10:
case 11:
case 12:
season="冬天";
break;
default:
season="出错啦~";
}
System.out.println(season);
while
- 括号条件成立会一直循环执行
- do-while 不管是否成立都会先执行一次
do{
}while();
for
例:2的幂累加
int daymoney=0;
int day=10;
int sum=0;
for(int i=0;i<day;i++)
{
if(daymoney==0)
daymoney=1;
else
daymoney*=2;
sum+=daymoney;
}
System.out.println(sum);
原题是(因为知道自己的性格可能以后回看会反复想知道这个题变量为什么这样命名,不找到原题不罢休)
//第一天要了1块钱
//第二天要了2块钱
//第三天要了4块钱
//第四天要了8块钱
//以此类推
//
//问题: 洪乞丐干10天,收入是多少?
continue
如果写在for循环的if下,如果条件满足,那么会直接进行下次循环,后面代码不执行
break
如果写在for循环的if下,如果条件满足,那么会直接结束循环
结束外部循环
第一种是利用boolean变量
boolean a=false;
for(int i=0;i < 10;i++)
{
for(int j=0;j<10;j++)
{
if(j%2==0)
{
System.out.println(" ");
a=true;
break;
}
}
if(a)
break;
}
第二种使用标签结束外部循环
outloop: //outloop这个标示是可以自定义的比如outloop1,ol2,out5
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; //如果是双数,结束外部循环
}
}
数组
- 创建数组时要指明数组的长度
- 如果用一个变量代表一个数组,称该变量为一个引用,让这个引用指向数组
- 数组的长度是不能改变的,定义好了多长就是多长不能改变
数组初始化
- 分配空间和赋值分步进行
- 分配空间同时赋值(两种)
1.int[] a=new int[]{2,3,4,5,6};
2.int[] a={2,3,4,6,5}; - 注意如果指定了数组的内容,就不能同时指定数组的长度
- 比如以下就是错误的会报错坚决不能有
int[] c = new int[]{100,102,444,836,3236};错的错的错的
随机数多写几个
零到一百的随机整数获取方式
(int) (Math.random() * 100)
给数组赋随机值
两个数组,长度是5-10之间的随机数,并使用随机数初始化这两个数组(既要随机数组长度又要随机数组里面的数字)数组c将a b合并
int []a=new int[(int)(Math.random()*5)+5];
int[] b=new int[(int)(Math.random()*5)+5];
for(int i=0;i<a.length;i++)
a[i]=(int)(Math.random()*100);
for(int j=0;j<b.length;j++)
b[j]=(int)(Math.random()*100);
for(int i:a)
System.out.print(i+" ");
System.out.println();
for(int i:b)
System.out.print(i+" ");
System.out.println();
int[] c=new int[a.length+b.length];
System.arraycopy(a, 0, c, 0, a.length);
System.arraycopy(b, 0, c, a.length, b.length);
for(int i:c)
{
System.out.print(i+" ");
}
选择排序
- 第一位和所有位比较,比第一位小则放入第一位,第二位也是这样从本位往后一一比较
- 代码演示
增强型for循环
for(int a:m);//a指的是数组里的元素,m指的是数组
例如:求最大值
int[] a={1,2,3,4,5};
int max=a[0];
for(int i:a)
{
if(max<i)
max=i;
}
System.out.println(max);
复制数组
System.arraycopy(src, srcPos, dest, destPos, length);
即为,被复制数组的名字,被复制数组被复制位置的起始下标,复制过去的数组的名字,复制进去的起始下标,和需要复制的长度
例如,要复制A数组的(2,4,5,6)到B数组的(6,7,8,9)位置,代码演示如下
int[] A=new int[]{1,2,4,5,6,7,8};
int[] B=new int[]{2,3,6,7,8,9,7};
for(int i=0;i<B.length;i++)
{
System.out.print(B[i]+" ");
}
System.out.println();
System.arraycopy(A, 1, B, 2, 4);
for(int j=0;j<B.length;j++){
System.out.print(B[j]+" ");
}
以下为运行结果
二维数组
- 二维数组的每个元素都是一个一维数组,所以二维数组又叫数组的数组
- 初始化二维数组
int[][] g=new int[2][3]; //两个一维数组,每个一维数组的长度为3
int[][] f=new int[][]{ {2,3},{3,4}};
int[][] k={ {2,3},{5,6},{9,0} };
对于
有
- 二维数组的例题,注意两点,一个是加强for循环的输出(让输出变得简单),另一个这个题是随机值然后找最大值和其下标
int[][] a=new int[5][5]; //定义一个5*5的二维数组
for(int i=0;i<a.length;i++)
for(int j=0;j<a[i].length;j++)
a[i][j]=(int)(Math.random()*100);//存放随机数
int max=-1;
int t_x=-1;
int t_y=-1;
for(int[] te:a)
for(int td:te)
System.out.print(td+" ");//加强for循环输出整个二维数组
for(int i=0;i<a.length;i++)
for(int j=0;j<a[i].length;j++)//注意这里循环的条件哦
{
if(a[i][j]>max)
{
max=a[i][j];
t_x=i;
t_y=j;
}
}
System.out.println();
System.out.println("max:"+max);
System.out.println("x:"+t_x+"y:"+t_y);
java中arrays工具类的使用
package jj;
import java.lang.reflect.Array;
import java.util.Arrays;
public class Test_copy {
public static void main(String[] args) {
int[] a={2,5,7,8,9,0};
int[] b=Arrays.copyOfRange(a,2,3);
//数组复制,(原数组,初始位置,末位置),需要注意末位置不能被取出哦
for(int i:b)
{
System.out.print(i+" ");
}//测试结果为7
System.out.println();
String content=Arrays.toString(a);//打印一个数组的内容
System.out.println(content);
System.out.println();
System.out.println("排序之前:"+content);
Arrays.sort(a);
System.out.println("排序之后:"+Arrays.toString(a));
//注意这里的排序是从小到大的排序
System.out.println();
Arrays.sort(a);//查询数字出现的位置
//需要注意两点
//第一点,数组在查询之前必须用sort排序
//第二点,如果数组内有多个相同元素查询结果则是不确定的
System.out.println("数字8出现的位置:"+Arrays.binarySearch(a, 8));
System.out.println();
int[] c={3,4,5,6,1,8};
System.out.println(Arrays.equals(a, c));
//比较两个数组内容是否一样
//测试结果是false
System.out.println();
int[] f=new int[8];
Arrays.fill(f, 6);//填充,用一个数字填满整个数组
System.out.println(Arrays.toString(f));
System.out.println();
}
}
引用
- 如果一个变量的类型是类类型,那么该变量又称为引用
- 可以 多个引用 一个对象
Hero h=new Hero();
Hero h1=h;
Hero h2=h;//三个引用都指向同一个对象
- 一个引用,同一时间,只能指向一个对象
继承
- extends
方法重载
- 方法名相同,参数类型不一样 举个例子了:(一般重载)
package guanwone;
public class Hero {
String name;
}
package guanwone;
//可以看出attack方法名是一样的但是参数不一样
public class ADHero extends Hero{
public void attack()
{
System.out.println(name + "进行了一次攻击,但是不确定打中谁了");
}
public void attack(Hero h1)
{
System.out.println(name +"对"+h1.name+"进行了一次攻击");
}
public void attack(Hero h1,Hero h2)
{
System.out.println(name +"同时对"+h1.name+"和"+h2.name+"进行了攻击");
}
public static void main(String[] args) {
ADHero bh = new ADHero();
bh.name = "赏金猎人";
Hero h1 = new Hero();
h1.name = "盖伦";
Hero h2 = new Hero();
h2.name = "提莫";
bh.attack(h1);
bh.attack(h1,h2);
}
}
- 可以看出很麻烦,如果里面要放更多参数呢,所以优化一下
package guanwone;
public class GoodAD extends Hero{
public void attack()
{
System.out.println(name + "进行了一次攻击,但是不确定打中谁了");
}
public void attack(Hero...heros)
{
for(int i=0;i<heros.length;i++)
{
System.out.println(name+"攻击了"+heros[i].name);
}
}
public static void main(String[] args) {
GoodAD bh = new GoodAD();
bh.name = "赏金猎人";
Hero h1 = new Hero();
h1.name = "盖伦";
Hero h2 = new Hero();
h2.name = "提莫";
bh.attack(h1);
bh.attack(h1,h2);
}
}
构造方法
- 如果没写,那么系统会默认给一个无参的构造函数
- 如果写了一个有参的构造函数(且自己没有显示写一个无参构造函数),那么默认的无参构造函数就没了
this
- 相当于’我‘,代表当前对象
public void setname(String name){
this.name=name;
//name是指参数name
//this.name指的是属性name
}
- this()调用本类其他构造方法时,只能放在构造方法的首行,方便理解直接放代码
//写一个英雄的信息类,类中提供如下四个属性:名称、职业、派系、身价,还有4个构造方法:
public class Hero {
private String name;
private String job;
private String dept;
private double sal;
public Hero(String name,String job,String dept,double sal)//四参构造
{
this.name=name;
this.job=job;
this.dept=dept;
this.sal=sal;
}
public Hero()
//无参构造,名称为火锅,职业是法师,派系好吃派,身价200
{
this("火锅","法师","好吃派",200.0);
}
public Hero(String name)
//单参构造,职业是刺客,派系要命派,身价100
{
this(name,"刺客","要命派",100);
}
public Hero(String name,String dept)
//双参构造,职业是琴师身价900
{
this(name,"琴师",dept,900.0);
}
}
传参
- 在方法内,不能修改方法外的基本类型参数
package包
- 把比较接近的类规划在同一个包下
- 使用其他包下的类必须import 包名.类名
修饰符
- private 私有的
- protected 受保护的
- public 公共的
- package/friendly/default 不写
注意下面这个表里的其他类是指不同包的类
- private修饰属性
- 无修饰符修饰属性即为package/friendly/default
- protecte修饰属性
- public修饰属性
- 使用情景
1,属性一般用private;
2,方法一般用public;
3,会被子类继承的方法一般用protected;
4,作用范围最小原则,能用private就不用protected能用protected就不要用public;
类属性和对象属性
- 类属性定义:当一个属性被static修饰的时候,该属性叫做类属性 ,又叫做静态属性
- 当一个属性被声明为类属性,所有的对象都共享一个值
- 个人理解,类属性有点类似于final修饰的变量,但是它不是只能被赋值一次
- 对象属性定义:又叫做实例属性,非静态属性
- 下面举代码例子来理解
public class Heroo {
public String name;//实例属性,对象属性,非静态属性
protected float hp;
static String copyright;//版权//类属性,静态属性
}
- 访问类属性
1,对象.类属性
2,类.类属性(更建议) - 使用环境:如果一个属性,每个对象都不一样,这个属性就应该设计成对象属性;如果一个属性,每个对象都是一样的,就应该设计为类属性
- 一个点:如果通过对象调用了类属性并且给类属性赋了新值,那么后面对象再使用类属性的时候,类属性就变成更改后的值了
类方法
- 类方法:又叫做静态方法(用static修饰)
- 访问类方法,不需要对象存在,可以直接访问;访问一个对象方法,必须建立在有一个对象的前提的基础上
- 代码示例:
public class Heroo {
public String name;//实例属性,对象属性,非静态属性
protected float hp;
static String copyright;//版权//类属性,静态属性
public static void ah()//类方法
{
System.out.println("敲代码腰疼啊--");
}
public static void main(String[] args) {
Heroo garen = new Heroo();
garen.name = "盖伦";
Heroo.copyright = "版权由Riot Games公司所有";
System.out.println(garen.name);
System.out.println(garen.copyright);
Heroo teemo = new Heroo();
teemo.name = "提莫";
System.out.println(teemo.name);
System.out.println(teemo.copyright);
Heroo.ah();//不需要对象直接调用
}
}
- 调用类方法当然也可以用对象调用,但是最好还是使用类来调用
- 使用环境:没有调用对象属性的方法;这样的方法更具有功能性
- 注意类方法中不能调用对象方法
属性初始化
- 对象属性初始化: 1,声明该属性的时候初始化 2,构造方法中初始化 3,初始化块
- 代码示例
public class Tired {
int n;
public String name = "为什么我还没对象";//声明该属性的时候初始化
protected double live;
{
n=9;//初始化块(不需要紧跟着属性)
}
public Tired()
{
live=9;//构造方法中初始化
}
}
- 类属性初始化
1,声明该属性的时候初始化 2,静态初始化块 - 代码示例:
public class Sleep {
public static int a=9;
protected static String m;
static{
m = "为什么又封校了";
}
}
- 当一个属性被三种方式初始化的时候,构造方法最后执行,声明时候初始化和初始化块看位置决定
单例模式
单例模式是指一个类,在一个jvm里只有一个实例存在
饿汉式单例模式
1,构造方式私有化
2,静态属性指向实例
3,public static的getlnstance方法,返回第二步的静态属性
public class Hero {
private Hero(){
}//私有化构造方法,让该类无法在外部通过new进行实例
private static Hero instance=new Hero();
//写一个类属性指向一个实例化对象,类属性所以只有一个值
public static Hero getIntance()
{
return instance;//获取上上行定义的对象
}
}//调用者只能通过getIntance获取对象哦
懒汉式单例模式
1,构造方式私有化
2,静态属性指向实例(声明一个静态属性暂时指向空,然后在第一次访问get方法时实例化一个对象)
3,public getIntance的方法,返回instance指向的对象
public class Test {
private Test(){
}//私有化构造方法使得该类无法在外部通过new进行实例化
private static Test intance;
//准备一个类属性,用于指向一个实例化对象,但是暂时指向null
public static Test getIntance(){
if(intance == null){
//第一次访问的时候,intance没有指向任何对象,这时实例化一个对象
intance = new Test();
}
return intance;//返回intance指向的对象
}
}
- 【区别】
1,饿汉式,立即加载,无论是否使用都会加载这个对象,如果有充分的启动和初始化时间可以用这个。
2,懒汉式,延迟加载,只有使用的时候才会加载,而且有线程安全的考量。
枚举
- 枚举enum是一种特殊类,使用枚举可以很方便的定义常量,可以将范围卡在这几个常量中,不会出现二义性什么的
public enum Season{
SPRING,SUMMER,AUTUMN,WINTER;
}//因为是常量所以一般全大写
- 可以通过增强型for循环来遍历枚举
字符串
关于字符串的关键字
- charAt 获取指定位置的字符
public class Testr {
public static void main(String[] args) {
String m = "好想有钱啊";
char n = m.charAt(0);//括号里面,0代表第一个元素即‘好’,1代表‘想’,以此类推
System.out.println(n);//输出结果是 想
}
}
- toCharArray 字符串转化为对应的字符数组
public static void main(String[] args) {
String m = "钟鼓馔玉不足贵";
char[] n = m.toCharArray();//没有参数,将字符串转化成对应的字符数组
for(char s : n)
System.out.print(s); //输出结果为 钟鼓馔玉不足贵
System.out.println();
System.out.println(m.length() == n.length); //输出结果为true
}
- subString 截取子字符串(获取想要的字符串片段)
public class Cut {
public static void main(String[] args) {
String m = "食堂什么时候卖雪梨粥,好想喝,别放那么多盐可以吗";
String n = m.substring( 15 );//获得第14位(从0开始的)以及往后的字符串
System.out.println(n); //输出结果为 别放那么多盐可以吗
String s = m.substring(7 , 14);//左闭右开
System.out.println(s); //输出结果为 雪梨粥,好想喝
}
}
- split 根据分隔符进行分隔
public static void main(String[] args) {
String m = "为什么我没有对象呢,今天下雨了,小冷。但不能阻止我穿裙子,今天又是new对象的一天,开心。";
String[] n = m.split(","); //按分隔符把字符串分割,分割后分隔符会删掉
for(String h:n)
System.out.println(h);
}
测试结果是:
测试了一下,如果在()里,写一个符号加另一个符号,那么只有两个符号相连的时候才会被分隔,如下:
public static void main(String[] args) {
String m = "为什么我没有对象呢,今天下雨了,小冷,。但不能阻止我穿裙子,今天又是new对象的一天,开心。";
//注意这里在‘小冷,’的后面加了‘。’
String[] n = m.split(","+"。");
for(String h:n)
System.out.println(h);
}
然后,如果写两个的话,按后一个的分隔符分隔,如下:
应该注意的是对于多个连续空格,用split(" "),有时候会报错,所以,应该用split("\s+") ,可以得到理想结果,比如"6 h8 9",会得到"6" "h8" "9"
- trim 去掉首尾空格
public static void main(String[] args) {
String m = " 今天绝对不熬夜了(破输入法啊,别影响我打字) ";
String n = m.trim(); //去掉首尾空格
System.out.println("去掉之前:"+m+"单纯的想证明一下尾部空格也没掉了");//输出原字符串
System.out.println("去掉之后:"+n+"单纯的想证明一下尾部空格也没掉了");//输出的字符串首尾空格全没有了
}
测试结果如下:
- toLowerCase 全部小写 toUpperCase 全部大写
public static void main(String[] args) {
String m = "Should know your love was a game.Now i cannot get you out of my brain";
System.out.println(m.toLowerCase()); // 全部小写
System.out.println(m.toUpperCase()); // 全部大写
//输出结果为
// should know your love was a game.now i cannot get you out of my brain
// SHOULD KNOW YOUR LOVE WAS A GAME.NOW I CANNOT GET YOU OUT OF MY BRAIN
}
- (好懒啊不想打字了真的懒得打字了想睡觉啊)
- indexOf 判断字符或者子串出现的位置 contains 是否包含字符串的判断
public static void main(String[] args) {
String m = "饿了,饿了,好饿好饿,能v我10r买饭吗(真的很诚恳)";
System.out.println(m.indexOf('1')); //'1'第一次出现的位置(字符)
System.out.println(m.indexOf('饿')); //'饿'第一次出现的位置(字符)
System.out.println(m.indexOf("饿了")); //"饿了"第一次出现的位置(字符串)
System.out.println(m.lastIndexOf('饿')); //'饿'最后一次出现的位置(字符)(字符串也可以哦)
System.out.println(m.indexOf(',', 2)); //从第2位开始往后,第1次出现','的位置(包括第二位)
System.out.println(m.contains("饿了")); //判断是否包含字符串 输出boolean型
}
- replaceAll
public static void main(String[] args) {
String m = "小花很好,小草很好,黑板很好,窗帘很好";
String n = m.replaceAll("很好", "好个头");
//将字符串中所有的"很好"都替换成"好个头"
System.out.println(n);
n = n.replace("小", "大");//将小替换成大
System.out.println(n);
n = n.replaceFirst(",", "并且");
//只把第一次出现的","换成"并且"
System.out.println(n);
}
测试结果: