JAVA OO
8种基本数据类型: byte , short , int , long, float , double , boolean , char
byte 字节类型, 8位2进制数, 范围: -128 ~127, 使用不多, 作为底层数据单元使用.
short 短整数, 16位2进制数, 范围: -32768 ~ 32767, 实用性不好, 很少用.
int 类型, 整数类型, 是最常用的类型, 32位2进制整数, 范围: -2147483648 ~ 2147483647
long 类型, 长整型, 64位2进制整数, 范围 很大: -2的63次方, 2的63次方-1 末尾 + l/ L
float 单倍精度浮点数, 采用32位浮点数格式存储, 精度低, 不常用 末尾 + f /F
double 双倍精度浮点数类型, 采用64位浮点数格式存储, 精度高, 常用
boolean 布尔类型, 只有两个状态 true\false, 用于代表判断结果, true表示成立 false表示不成立
三元 boolean? a : b 四元(三元嵌套) guess == i ? "Bingo!" : (guess > i ? "Big!" : "Small!")
char 字符类型 底层是 16为2进制整数, 存储一个字符的编码, 范围:0~65535
++a先运算 后执行 a++先执行 后运算
+= (扩展赋值 会强转类型)
&& || ! 与(见false后面不执行)或(见true短路)非
- 自动类型转换: 小范围类型到大范围类型, 可以自动完成, 不需要显式转换
- 强制类型转换: 大范围类型到小范围类型, 不能自动完成, 需要显式转换类型.
- 如果数值是小范围内的,就能转换成功
- 如果数值超过小范围, 就发生溢出
- 浮点数转换为整数, 截掉小数部分
算数:+ - * / % ++ --
关系:> < >= <= == !=
逻辑:&& || !
赋值:= += -= *= /= %=
字符串连接:+
条件:boolean
Scanner scan = new Scanner(System.in);
能不嵌套就不嵌套
if(true){
if(true){if(true){}else{}}else{}
}else{}
if(false){}
else if{}else if{} else{}
switch case
效率高 结构清晰
只能对整数判断相等 byte short int char String 枚举
int i = 6;
System.out.println("Guess!");
Scanner scan = new Scanner(System.in);
int guess = scan.nextInt();
while (guess != i) {
System.out.println(guess > i ? "Big!" : "Small!");
guess = scan.nextInt();
}
System.out.println("Bingo!");
int i = 6;
System.out.println("Guess!");
Scanner scan = new Scanner(System.in);
int guess ;
do {
guess = scan.nextInt();
System.out.println(guess == i ? "Bingo!" : (guess > i ? "Big!" : "Small!"));
}
while (guess != i);
//直接输入6 输出:Small!
do while 最少执行一次
arrays
int[] a = {1,2,3};
int[] b = new int [5];
System.arraycopy(a,srcPro(a起始位置),b,destPro(b起始位置),length(复制的长度 注意长度 会溢出)); 灵活性好
Arrays.copyOf(original(源 a),length(复制的长度<原数组长度 截掉 反之补默认值)); 灵活性差 可以扩容 Arrays.copyOf(a,a.length+1)
Arrays.sort();
方法签名:方法名+参数列表
数字 _ $ 在特定情况下用
重写:发生在父子类中 方法名相同 参数列表相同
派生类中修改超类中的方法
重载:发生在同一类中 方法名相同 参数列表不同
完全同的方法 方法名相同
重写遵循:两同两小一大
两同:
方法名相同
参数列表相同
两小:
派生类方法的返回值类型小于或等于超类方法的
void 基本类型(int double等) 必须相等
超类中引用父类(子类引用父、子类)
超类中引用子类(子类引用子类)
派生类方法抛出的异常小于或等于超类方法的
一大:
派生类方法的访问权限大于或等于超类方法的
父类:public void move(){} 子类:public void move(){} 或者 void move(){}
父类中声明为public 的方法在 子类中也必须为 public
父类中声明为protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private
父类中声明为private 的方法,不能够被继承(需要get set 取值 赋值)
public void moveRight() {
x = Math.min((x + speed), (641 - this.width));
}
public void moveRight() {
setX(Math.min((getX() + getSpeed()), (641 - this.getWidth())));
}
实例变量:属于对象 在创建对象是存储在内存堆中
创建多少个对象 则实例变量就会在内存中存储多少份
需要通过引用变量(对象)来访问
静态变量:属于类的 在类被加载时存储在内存方法区中
无论创建多少个对象 静态变量在内存中只存储一份
常常通过类名点来访问
继承的是超类中的成员变量和普通方法 而不包括构造方法
超类的构造方法是被派生类通过super来调用的
class Aoo{
int a;
Aoo(){}
void show(){}
}
class Boo extends Aoo{
继承a和show()不包括构造方法Aoo()
构造方法十倍派生类通过super来调用的 super.Aoo()
}
java中无论是基本类型还是引用类型 都是值传递
对于基本类型而言 传递的是具体的值的副本
对于引用类型而言 传递的是具体的地址的值的副本
隐式的引用:
this:指代当前对象
super:指代当前对象的超类对象
外部类.this:指代当前对象的外部类对象
匿名内部类:---简化代码
若想创建一个类的对象 并且对象只被调用一次
匿名内部类中不能修改外面局部类的值 该变量在匿名内部类中默认为final的
内部类也有独立的.class
Aoo a1 = new Aoo(); 抽象类不能直接new
Aoo a1 = new Aoo(){
void show(){}(重写Aoo中的show)
};
创建了Aoo的派生类 但是没有名字
为该派生类创建一个对象 名为a1
大括号中的派生类的类体
abstract class Aoo {
void show(){}
}
控制概率:
void Roll(){
Random rand = new Random();
int i = rand.nextInt(30);
if(i<15){}
else if(i<25){}else{}
}
接口:
接口是一种数据类型 引用类型
接口由interface定义
只能包含抽象类方法 和 常量(默认)
接口不能被实例化
接口需要被实现/继承 实现类/派生类 必须重写所有抽象方法
一个类可以继承多个接口 用逗号分隔 若又继承又实现时 应先继承后实现
接口可以继承接口
接口相当于制定了一个标准 规范
向上造型/自动类型转换:---就是多态
超类型的引用指向派生类的对象
能点出来什么 看引用的类型
能造型成为的类型有 超类+所实现的接口
强制类型转换 不符合会发生ClassCastException异常
引用所指向的对象 就是该类型
引用所指向的对象 实现了该接口或继承了该类
equals //s==s1 比对的是地址 所以不一样
substring //要头不要尾 包含start 不包含end(4,8)->4-7位
我爱Java!
s.toLowerCase() //转换英文为小写 我爱java!
s.toUpperCase() //转换英文为小写 我爱JAVA!
s.startsWith("") //判断以""开头 验证
s.endsWith("") //判断以""结尾
s.charAt(x); //取第x位的字符 随机生成字符串
0123456789012345
thinking in java
s.IndexOf("in") //检索""第一次出来的位置 找不到为-1 sout-> 2
s.IndexOf("in" , x) //从x位开始检索""第一次出来的位置 找不到为-1 sout-> 5
s.lastIndexOf("in") //检索""最后一次出来的位置 找不到为-1 sout-> 9
字符串内容若需要查看 建议String (实际应用中多)
字符串内容若需要经常修改 建议StringBuilder
StringBuilder:非线程安全的 并发处理的(异步) 性能稍快 (一般用StringBuilder)
StringBuffer :线程安全的 同步处理的(同步) 性能稍慢
StringBuilder //是专门用于修改字符串的一个类 内部维护一个可变的char数组 所做的操作都是在这个数组之上进行的 修改速度 性能优秀
//并且提供了修改字符串的常见方式 增删改插
append()
delete()
replace()
insert()
StringBuilder builder1 = new StringBuilder(); //空串
StringBuilder builder2 = new StringBuilder("abc"); //abc串
String s = "abc";
StringBuilder builder3 = new StringBuilder(s);
String s1 = builder3.toString();
String s2 = builder3+"";
0123456789012345
System.out.println(builder2.append("123")); //abc123
System.out.println(builder2.replace(2,5,"ABCDE")); //abABCDE3 //要头不要尾 包含start 不包含end(2,5)->2-4位
System.out.println(builder2.delete(2,5)); //abDE //要头不要尾 包含start 不包含end(2,5)->2-4位
System.out.println(builder2.insert(2,"5")); //ab5DE //(start,x) x可以为各种类型 (2,double: 123.456) sout-> ab123.456DE
getter/setter
很多框架都是基于getter/setter来配置获取数据的 可以理解为他是一种行为的标准
getter/setter是可以对数据进行控制 而public权限无法对数据进行控制
public void setX(int x) {
if (x >= 0) {
this.x = x;
}
}
[]:表示一个字符 该字符可以是[]中指定的内容
[abc] 可以是a或b或c
[a-z] 小写字母
[a-zA-Z] 小写+大写字母
[a-zA-Z0-9] 字母+数字
[a-zA-Z0-9_] 字母+数字+下划线
[^abc] 不是a或b或c
. 任意一个字符 没有范围限制
\d 任意一个数字 [0-9]
\w 人员一个单词字符 [a-zA-Z0-9_] 单词字符指 字母+数字+下划线
\s 任意一个空白字符
\D 不是数字
\W 不是单词字符
\S 不是空白字符
? 表示前面的内容出现0-1次
[abc]? 可以是a或b或c 或什么也不写
但是不能匹配 m n(除abc外字符)或aaa(出现超过1次)
+ 表示前面的内容最少出现1次
[abc]+ 可以是b或aaaaaaaaa...或abcabcabcabc....
但是不能匹配 什么都不写 或者 abcdefg(abc以外的)
* [abc]* 表示前面的内容出现任意次 (0-n)次 ---匹配内容与 + 一致 只是可以一次都不写
但是不能匹配 abcdefg(abc以外的)
{n} 表示前面的内容出现n次
[abc]{3} 可以匹配aaa 或 bbb 或 aab 或 abc 或 bbc
但是不能匹配 aaaa(4次) 或 aad(abc以外的)
{n,m} 表示当前面的内容最少出现n次最多m次
[abc]{3,5} 可以匹配aaa 或 abcab 或 abcc
但是不能匹配 aaaaaa(6次) 或 aabbd(abc以外的)
{n,} 表示前面的内容出现n次以上(含n次)
[abc]{3,} 可以匹配 aaa 或 aaaaa... 或 abcabcabcabc...
但是不能匹配 aa(2次) 或 abbdaw(abc以外的)
()用于分组 设计奖小括号里面的内容看做是一个整体
(abc){3} 表示abc整体出现3次 可以匹配abcabcabc
但是不能匹配 aaa(不是abc) 或 abcabc(2次)
(abc|def){3}表示abc或def整体出现3次
可以匹配 abcabcabc 或 defdefdef 或 abcdefabc
但是不能匹配 abcdef(2次) 或 abcdfbdef(dfb)
s = ""; //xxxxxxxxx@xx.xxxx
regex = "[a-zA-Z0-9_]+@[a-zA-Z0-9]+(\\.[a-zA-Z]+)+"; //验证邮箱 + 不是拼接 代表 最少出现1次
//\. 代表 任意一个字符(\为正则表达式的转义字符)
//\\.(\为java中转义字符)
s.matches(regex);
line = "abc123def456ghi789";
line = line.replaceAll(regex:"[0-9]+", replacement"#NUM#"); //如果不带+ ([0-9]+) 则每个数字替换一次
sout -> "abc#NUM#def#NUM#ghi#NUM#" //sout -> "abc#NUM##NUM##NUM#def#NUM##NUM##NUM#ghi#NUM##NUM##NUM#"
split("[0-9]+");
Collection接口: 是所有集合的顶级接口 封装了所有集合所共有的东西 下面有多种实现类 因此我们有更多的数据结构可以选择
List: 线性表 是可以重复集合 并且有序
Set: 不可重复集合 大部分实现类是无序的
List:
ArrayList list1= new ArrayList(); //[c, c++, .net]
list1.add("c");
list1.add("c++");
list1.add(".net");
ArrayList list2= new ArrayList(); //[android, ios, java]
list2.add("android");
list2.add("ios");
list2.add("java");
ArrayList list3= new ArrayList(); //[android, ios, php]
list3.add("android");
list3.add("ios");
list3.add("php");
add:
addAll:将list2中所有元素添加到list1中(2里有几个添加几个 不是作为一个元素添加)
list1.add(list2); //sout-> [c, c++, .net, [android, ios, java]]
list1.addAll(list2); //sout-> [c, c++, .net, android, ios, java]
isEmpty:
等同于 List.size()==0;
contains
判断当前集合中是否包含元素 (默认equals比较 地址)
containsAll:
判断当前集合中是否包含参数集合中的所有元素
remove:remove(Object o)
从集合中删除与给定元素equals比较为true的元素,若存在重复元素则只删除一次(第一个一样的)
removeAll:
删交集 将list1中与list3中共有的元素删除
list1.removeAll(list3); //[c, c++, .net, java]
retainAll(list3);
取交集 list1中仅保留list1与list3中共有的元素
list1.retainAll(list3); //sout-> [android, ios]
Collection接口提供了统一的遍历集合方式: 迭代器模式 通过Iterator()方法可以获取一个用于遍历当前集合元素的迭代器
Iterator接口:定义了迭代器遍历集合的相关操作 不同集合都实现了用于遍历自身元素的迭代器实现类
迭代器遍历遵循的步骤为 问 取 删 其中删除元素并不是必要的操作
迭代器的常用方法:
hasNext();
询问集合是否还有 下一个 元素可供迭代
注意:迭代器默认开始位置是在集合第1个元素之前 (0前面)
无论调用多少次hasNext()方法 迭代器的位置都不会变
next()
迭代器向后移动一个位置来指向集合的下一个元素并将其获取
迭代器在遍历时不能通过集合方法增删元素 需要用迭代器删除
Collection c = new ArrayList();
c.add("one"); c.add("#"); c.add("two"); c.add("#"); c.add("three");
c.add("#"); c.add("four"); c.add("#"); c.add("five");
System.out.println(c); //[one, #, two, #, three, #, four, #, five]
Iterator it = c.iterator();
while (it.hasNext()){
System.out.print((String) it.next());
//one, #, two, #, three, #, four, #, five
if(str.equals("#")){
//c.remove(str); //报异常
it.remove(); //删除next()所取得元素
}
} //sout-> [one, two, three, four, five]
asList();
List<String> list = Arrays.asList(arr);
方法会返回Arrays定义的ArrayList 该集合内部直接饮用给定数组的array(指向地址)
添加删除元素相当于网数组中加减元素(用Arrays.copyOf)(list.add list.remove 报异常)
List<String> list = new ArrayList<>(Arrays.asList(arr));
String[] ss = list.toArray(new String[0]);
若参数数组元素个数>集合元素个数 末尾补默认值
ArrayList: 内部使用数组实现 查询性能好(直接通过下标查找) 增删性能不太好
LinkedList: 内部使用链表实现 查询性能不太好(通过链接地址查找下一个元素) 首尾增删元素性能更好
subList();
sublist = list.subList();
对子集的操作就是对原集合对应元素操作(指向地址)
list = new ArrayList<>(list.subList());
原集合修改后 子集将不能进行操作 但是可以重新获取子集进行造作
list.remove(0);
sout-> list
sout-> sublist //异常
sublist.remove(0);
sout-> list //对应sublist第一个元素删除
sout-> sublist //
Collections.sort(); //按ASCII码排序 必须是可比较的 否则发生编译错误
//判定是否可比较的标准为元素是否实现了Comparable接口
jdk1.8后可以直接list.sort(); //实际开发中 不会让我们自己定义的类去实现Comparable接口 因为这对我们的程序有侵入性
//侵入性 当我们调用每个API功能时 其要求我们为其修改其他额外的代码 这个现象叫做侵入性
//侵入性越强越不利于程序的后期维护 应尽量避免
//重载的 Collections.sort(list, new Comparator<Point>(){})方法 (常用)
Collections.reverse(); //倒序(赋值 数组元素位置发生变化)
Collections.sort(c, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return 0;
//返回值>0 则表示o1>o2
//返回值<0 则表示o1<o2
//返回值=0 则表示o1==o2
//o1-o2 升序
//o2-o1 降序
}
});
Collections.sort(list, new Comparator<Point>() {
@Override
public int compare(Point o1, Point o2) {
return o1.getX()-o2.getX();
}
});
Set:
HashSet 常见的类
可以去重
List<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(1);
list1.add(2);
list1.add(3);
list1.add(4);
list1.add(5);
list1.add(3);
System.out.println(list1);
HashSet<Integer> hashSet =new HashSet<>(list1);
System.out.println(hashSet);
list1 = new ArrayList<>(hashSet);
System.out.println(list1);
Thread.yield();//该方法可以让运行的方法的线程主动放弃本次剩余时间片
synchronized 同步方法 多个线程不能同时在方法内部执行 SyncDemo
在成员方法上使用synchronized后 同步监视器对象不可选 就是this
spring框架要求,只有被注解@Controller标注的类才是处理业务的类aController
@RequestMapping注解用于标注处理某个具体业务的方法,参数传入的字符串与对应页面中表单的action地址一致
/**
* 单例模式
* 1:私有化构造器(防止外界通过new来实例化对象)
* 2:提供一个静态方法用于将当前类实例返回给外界
* 3:提供一个静态的私有的当前类型实例的属性并初始化(确保只有一个实例)
*/