JavaNote
Java中的数据类型
基本数据类型
整数:默认的整数类型是int
int (整形)
byte (字节)
short (短整型)
long (长整型)
byte < short < int < long
小数:浮点型,默认的是double类型
float (单精度浮点型)
double (双精度浮点型)
字符:
char (字符类型)
布尔: boolean (布尔类型)
true
false
引用数据类型
类:
class
扫描二维码关注公众号,回复: 8581609 查看本文章接口:
interface
数组:
[]
byte 1字节 内存中占用一个字节 8位 最高位用来保存符号(正负)
short 2字节 16位
int 4字节 32位
long 8字节 64位
float 4字节 32位
double 8字节 64位
char 默认占2个字符 16位
boolean 1个字节
字符会使用到一个字符编码表,不同的字符编码表对于的字符占用的字节是不同的
字符在内存中其实就是一个整数,哪一个字符对于哪一个整数由谁来决定 ↓
程序中 最基本的一个编码表 → ASCII码表
类型的强转
可以将高类型的值强转给低类型,溢出的即将被丢失 — 类型的强转
int i = 256;
b = (byte)i;
小数强转整数会丢失小数部分,而不是四舍五入
double d = 23.01;
int age = (int)d;
整数字符在内存中的体现是相同的,所以可以直接相互转换
char c = 67;
int i2 = 'a';
三元运算符/三目运算符
int sum1 = 10;
int sum2 = 20;
int max = sum1 > sum2 ? sum1 : sum2;
两数做交换的三种方法
int i = 10;
int j = 20;
int k = i;
i = j; method one
j = k;
i = i + j;
j = i - j; method two
j = i - j;
i = i ^ j;
j = i ^ j; method three
i = i ^ j;
逻辑运算符
&(逻辑与) |(逻辑或) ^(异或) !非(取反) &&双与 ||双或
逻辑运算符的结果一定是布尔类型 boolean
逻辑运算符两边的表达式结果只能是Boolean类型
int age = 60;
System.out.println(18 <= age & age < 50);
System.out.println(true | false); // 只有两边都为true,结果为true
System.out.println(true & false); // 只有两边都为false,结果为false
System.out.println(true ^ true); // 异或,相同为false,不同为true
System.out.println(!true); // 取反
单与、双与的区别 &、 && 、|、 ||
System.out.println(i ++ > 0 & j ++ > 0); // i = 1; j = 1;
System.out.println(i ++ > 0 | j ++ > 0); // i = 1; j = 1;
// && 会短路,当左边的表达式已经不成立为false,右边的表达式就不会再进行判断
System.out.println(i ++ > 0 && j ++ > 0); // i = 1; j = 0;
// || 会短路,当左边的表达式已经成立为true,右边的表达式就不会再进行判断
System.out.println(i ++ > 0 || j ++ > 0); // i = 1; j = 0;
比较运算符
比较运算符组合的算数叫做比较表达式
比较表达式的结果一定是boolean 结果只有true、false
int age = 21;
boolean res = age == 20;
System.out.println(res);
System.out.println(age != 20);
System.out.println(age > 20);
System.out.println(age < 20);
自定义函数
函数就是将一个小功能的代码单独包装起来,可以选择性的来执行
函数的定义位置:类的{}中,main函数的外面
函数只能定义在类中,不能定义在其它函数中,函数不能嵌套
函数中只能执行函数,不能定义函数
字符串拼接
int num = 20,
num2 = 30;
// + 号前或后如果由字符串,这个+讲究不是算术运算符的求和,而是拼接
System.out.println("num=" + (num + num2));
条件判断语句
if(true or false) {
if true and run this code
} else if (true or false) {
if true and run this code
} else if (...) {
...
} else {
if false and run this code
}
Scanner类的用法
Scanner in = new Scanner(System.in);
int num = in.nextInt();
double num2 = in.nextDouble();
String num3 = in.nextLine(
Random随机数的使用
Random ran = new Random();
int ranNum = ran.nextInt(); // 方法1
int ranNum = (int)(Math.random()*10)+1; // 方法2
// 取10-20之间的随机数,包括10和20
Random ran = new Random();
for(int i = 0 ; i < 100 ; i ++){
int ranNum = ran.nextInt(11)+10; // 11表示取0-10的数字
ranNum
}
选择结构
switch (可以是表达式,也可以是具体的值) {
case "A":
case "a": //用来跟上面()中进行匹配的值 匹配成功(相同)就执行这里面的代码,
// 一直往下执行,直到遇到break才结束
// 如果不写break,会直接执行下一个case,这种现象叫穿透
break;
default: //default相当于if语句中的else
// 所有的case都匹配不上就会进入default
//default语句可以写在前中后都行
System.out.println("输入错误");
break;
}
switch能够匹配的值的类型是有限制的
1.5之前 switch匹配的值只有int类型 (byte short char) long 是不行的
1.5之后 新增了支持 String enum 类型(此为引用类型)
for循环
// 作用域 {}
// 1.执行初始化语句
// 2.执行条件语句
// 3.如果条件为true,执行循环体
// 4.执行 i++
// 5.回去执行条件语句,判断是否成立
// 6.成立就循环,否则终止
// for(;;){} 永真循环
for (int i = 0 ; i < 10 ; i ++){
循环体
}
百钱百鸡问题 与 猴子吃桃问题
//分析:
//假如每天有x个桃子,猴子吃了一半加一个,就是吃了x/2+1个,那么剩余x-(x/2+1)=x/2-1个;
//这样,第二天有x/2-1个桃子供当天使用。
//我们可以看出这么一个规律:今天的桃子个数+1再乘2等于昨天的桃子个数;用上面的表达式就是( x/2-1 +1 )*2=x。
//如此,只要知道了最后一天的桃子个数,知道了最后一天是第几天,就可以逆推出第一天总共多少个桃子了
public class test2 {
public static void main(String[] args){
int t = 1;
for(int i=1;i<10;i++){
t=(t+1)*2;
}
System.out.println("the initial number of peachs is:"+t);
}
}
嵌套循环
-
99乘法表
for (int i = 1 ; i < 10 ; i ++){ // i控制乘号左边的数字 for (int j = 1 ; j <= i ; j ++){ // j控制乘号右边的数字 // 输出格式 System.out.print(j + "×" + i + "=" + i*j + " "); } System.out.println(); //内循环结束后换行 }
Java 中内存是怎样分配的
jvm虚拟机中执行Java代码时也是根据功能分区域放置的
寄存器(cpu)
本地方法区(jvm系统使用的)
方法区(也叫代码区)
栈区(方法栈) ====> 用来保存局部变量
系统自己管理空间的申请和释放
空间使用时按照先进后出的方式(压栈)
所有变量都必须手动设置初始值才可以使用
- 堆区
用来保存对象(数组也是对象),要使用new关键字创建的变量都是对象,都在堆中。
需要程序员来管理空间,对象的申请和销毁都需要手动执行
现在大部分的情况,堆区的对象都是由垃圾回收机制来处理对象的销毁。
堆中的对象(变量)系统会默认初始化
整数的默认值为 0
小数默认为 0.0(0.0f)
字符默认为 ’ ’
布尔值默认为false
对象类型默认值null
new 关键字 就表示要在堆区中创建一个新的对象
数组
需要先创建一个空的数组,然后定义其长度
数组一旦创建长度就已经固定
数组的长度时固定的,如果超出已有下标,就会报错,报错如下
java.lang.ArrayIndexOutOfBoundsException
break continue的用法
break结束语句
break loop; 跳到指定外层循环
continue继续循环,以下语句不会执行到
String方法的调用
大写转小写
str.toLowerCase();
小写转大写
str.toUpperCase();
替换字符
str.replace('a','b');//把a替换成b
替换字符串
str.replace("aa","");//把aa替换成空
切割
str.split(",");//以逗号为分隔,并返回一个String数组
判断字符串是否为空 //是判断”“ 不是null
str.isEmpty();//是空返回true 否则false
判断字符串的开始
str.startWith("aaa");//开头是aaa就返回true否则false
判断字符串的结尾
str.endWith("aaa");//结尾是aaa就返回true否则false
判断字符串中是否包含
str.contains("google");//包含就返回true否则false
比较字符串是否相同
str.equals(str2);//相同就返回true否则false
忽略大小写比较是否相同
str.equalsIgnoreCase(str2);//相同就返回true否则false
比较字符串大小
str.compareTo(str2);//大就返回正数 等于返回0 否则返回负数
去除字符串两边的空白
str.trim();//返回一串两边没有空白的字符串
字符串的常量池
通过常量的方式创建字符串,字符串不会直接在堆中b保存因为字符串常量是不变的,所以可以进行共享使用,因此字符串常量会保存到一个可以供大家使用的地方
这个地方叫:字符串常量池
创建一个字符串常量,系统不会第一时间就new对象,而是先去找,是否已经有相同的字符串
如果有就直接将地址复制给变量,如果没有,就在常量池new一个字符串
集合
ArrayList
数组
LinkedList
链表
// 集合里面装对象
private static ArrayList<BookInfo> books = new ArrayList<>();
// 遍历
for (BookInfo bookInfo : books) {
System.out.println(bookInfo);
}
//根据图书的id号查询图书
for ( BookInfo book : books) {
if (book.getBookId() == id) {
return book;
}
}
return null;
//修改
delBoo.setBookName("java从入门到入土");
for (BookInfo book : books) {
if (book.getBookName().equals("java从入门到入土")) {
book.setAuthor("诸葛亮");
}
}
//删除
//通过下标删除
BookInfo delBoo = queryBook(1003);
//books.remove(2);
printBooks(books);
//排序
for (int i = 0; i < list.size()-1; i++) {
for (int j = i+1; j < list.size(); j++) {
if (list.get(i).compareTo(list.get(j)) > 0) {
// 定义一个三方变量
String temp = list.get(i);
// 利用set方法来调换
list.set(i, list.get(j));
list.set(j, temp);
}
}
}
HashSet
哈希表
//hashSet判定元素是否相同,首先是去检查元素的哈希值 是否相同
HashSet<BookInfo> books = new HashSet<>();
//获取:通过迭代器获取所有元素
for (BookInfo bookInfo : books) {
System.out.println(bookInfo);
}
//HashSet 内部是使用哈希表来存储元素
//整数的哈希值就是数据本身,字符会转换为ASCII码
//hashSet的第一个特点:输出顺序跟添加顺序不一致
//set集合没有修改方法
//有这个方法的对象称为具备了自然排序规则
//重写 comparable
@Override
public int compareTo(StuInfo o) {
int ageRes = this.age - o.getAge();
int nameRes = this.name.compareTo(o.getName());
/* if (nameRes == 0) {
return ageRes;
}else {
return nameRes;
}*/
return nameRes == 0 ? ageRes : nameRes;
//return this.age - o.getAge();
}
//重写toString
@Override
public String toString() {
return name + " " + gender + " " + age;
}
//重写哈希算法
//目的:为了让里边儿 不 能够存相同的数据,所以重写,让他们哈希值不同
@Override
public int hashCode() {
System.out.println("hashCode----");
return this.age + this.name.hashCode() * 31
+ this.gender.hashCode();
}
//重写equals 方法
@Override
public boolean equals(Object obj) {
//1.先判断当前对象与传入的对象是否相同
if (this == obj) {
return true;
}
//判断传入的值是不是Student类型,是才进行判断,不是直接返回false
if (obj instanceof StuInfo) {
//转为最高形态
StuInfo stu = (StuInfo)obj;
//2.比较对象的属性
if (this.name.equals(stu.getName()) &&
this.age == stu.getAge() &&
this.gender.equals(stu.getGender())) {
//如果属性都相同,就返回true
return true;
}
}
return false;
}
TreeSet
二叉树
TreeSet<Integer> tSet = new TreeSet<>();
//小走左边 大走右边
//最后从左到右排
//treeSet保存自定义对象
TreeSet<BookInfo> tSet = new TreeSet<>();
//创建对象并存入
tSet.add(new BookInfo(1005,"aaa","bbb",88));
//遍历
for (BookInfo bookInfo : tSet) {
System.out.println(bookInfo);
}
//重写哈希算法,目的:避免出现同一个哈希值后挂桶影响性能
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
//重写equals方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
创建一个新的类,实现接口Comparator,重写接口中的compare
再compare方法中定制自己的比较规则
使用定义好的类创建对象,传递给TreeSet的构造函数作为参数 就可以了
TreeSet<String> tSet2 = new TreeSet<>(new CompartorWithStringLen());//CompartorWithStringLen为自定义类
public class CompartorWithStringLen implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
//在这里定制你想要的比较规则,谁大谁小
int len = o1.length() - o2.length();
int charR = o1.compareTo(o2);
//return o1.length() - o2.length();
return len == 0 ? charR : len;
}
}
使用匿名内部对象的方式创建一个比较器对象传递给集合实现元素的排序
TreeSet<Person> tSet = new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int ageRes = o1.getAge() - o2.getAge();
int nameRes = o1.getName().compareTo(o2.getName());
return ageRes == 0 ? nameRes : ageRes;
}
});
// 匿名内部类实现
tSet.add(new Person("小李8", 18));
tSet.add(new Person("小李7", 23));
tSet.add(new Person("小李6", 63));
tSet.add(new Person("小李5", 11));
tSet.add(new Person("小李2", 11));
tSet.add(new Person("小李3", 17));
tSet.add(new Person("小李1", 19));
tSet.add(new Person("小李9", 8));
tSet.add(new Person("小李11",0));
for (Person person : tSet) {
System.out.println(person);
}
HashMap
HashMap<Integer, String> users = new HashMap<>();
// 添加 账号和密码
// 键 值
users.put(574180312, "zxc123456");
// put方法在键不同(不重复)的情况下,它就是添加
users.put(350888, "zxc654321");
// pu方法在键相同的情况下,就是修改 键只允许存在一个,不允许存在相同的
users.put(350888, "zxc456789");
// 获取 根据键获取值
System.out.println(user.get(574180312));//获取但是不会修改集合数据
// 删除
System.out.println(user.remove(350888));//获取但是会删除集合数据
// 获取 键值对数
System.out.println(users.size());
// 判断 是否为空
System.out.println(userss.isEmpty());
// 清空 所有的键值对 (比如清空购物车)
users.clear();
// 检查是否 包含
System.out.println(users.containsKey(574180312)); // Key
System.out.println(users.containsValue("zxc123456"));// value
TreeMap
// 比较器创建方式,第一种创建类实现comparator接口,实现方法,创建对象
// 使用匿名内部类的方式来实现对象创建 ↓↓↓↓↓
TreeMap<Integer, String> tMap = new TreeMap<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
// 升序为 o1-o2,降序则相反
return o2-o1;
}
});
tMap.put(1005, "小牛11");
tMap.put(1002, "小牛21");
tMap.put(1003, "小牛31");
tMap.put(1004, "小牛41");
tMap.put(1001, "小牛51");
tMap.put(1008, "小牛61");
for (Integer stuid : tMap.keySet()) {
System.out.println(stuid+"="+tMap.get(stuid));
}
// Map的遍历方法
for (String key : hMap.keySet()) {
// 根据遍历获得的每一个键,到map中去获取对应的值
Integer value = hMap.get(key);
System.out.println(key+ "------" +value);
}
泛型
// 自定义一个泛型类
class myClass<V1, V2>{
private V1 value1;
private V2 value2;
public MvClass(V1 value1, V2 value2){
super();
this.value1 = value1;
this.value2 = value2;
}
public void setValue21(V1 value21) {
this.value21 = value21;
}
public V1 getValue21() {
return value21;
}
public V2 getValue22() {
return value22;
}
public void setValue22(V2 value22) {
this.value22 = value22;
}
}
public static void main(String[] args){
ArrayList<Integer> arrayList = new ArrayList<>();
ArrayList<String> arrayList2 = new ArrayList<>();
ArrayList<Number> arrayList3 = new ArrayList<>();
function(arrayList);
// ? 泛型要实现类似于多态的实现方式,需要使用泛型的通配符,所有泛型的类型都会匹配
// 泛型类型的约束泛型的上限和下限
function(arrayList2); // 不行,因为限制了上限和下限
// 也行
function(arrayList3);
}
private static void function (ArrayList<? extends Number> arrayList) {
System.out.println(arrayList);
}
// 转班
Person selPerson = null;
for (Person person : hMap.get("w1903")) {
if (person.getName().equals("Tom")) {
// 修改年龄
selPerson = person;
}
}
//调换班级
hMap.get("w1903").remove(selPerson);
hMap.get("j1903").add(selPerson);
printClassPNum(hMap);
===================================================================
集合Collection的一些技巧:
需要唯一吗?
需要:Set
需要制定顺序:
需要: TreeSet
不需要:HashSet
但是想要一个和存储一致的顺序(有序):LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
如何记录每一个容器的结构和所属体系呢?
看名字!
List
|--ArrayList
|--LinkedList
Set
|--HashSet
|--TreeSet
后缀名就是该集合所属的体系。
前缀名就是该集合的数据结构。
看到array:就要想到数组,就要想到查询快,有角标.
看到link:就要想到链表,就要想到增删快,就要想要 add get remove+frist last的方法
看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖 hashcode 方法和 equals 方法。
看到tree:就要想到二叉树,就要想要排序,就要想到两个接口Comparable,Comparator 。
而且通常这些常用的集合容器都是不同步的。
===================================================================
Map:一次添加一对元素。Collection 一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实map集合中存储的就是 键 值 对。
map集合中必须保证键的唯一性。
===================================================================
1903").add(selPerson);
printClassPNum(hMap);
```java
===================================================================
集合Collection的一些技巧:
需要唯一吗?
需要:Set
需要制定顺序:
需要: TreeSet
不需要:HashSet
但是想要一个和存储一致的顺序(有序):LinkedHashSet
不需要:List
需要频繁增删吗?
需要:LinkedList
不需要:ArrayList
如何记录每一个容器的结构和所属体系呢?
看名字!
List
|--ArrayList
|--LinkedList
Set
|--HashSet
|--TreeSet
后缀名就是该集合所属的体系。
前缀名就是该集合的数据结构。
看到array:就要想到数组,就要想到查询快,有角标.
看到link:就要想到链表,就要想到增删快,就要想要 add get remove+frist last的方法
看到hash:就要想到哈希表,就要想到唯一性,就要想到元素需要覆盖 hashcode 方法和 equals 方法。
看到tree:就要想到二叉树,就要想要排序,就要想到两个接口Comparable,Comparator 。
而且通常这些常用的集合容器都是不同步的。
===================================================================
Map:一次添加一对元素。Collection 一次添加一个元素。
Map也称为双列集合,Collection集合称为单列集合。
其实map集合中存储的就是 键 值 对。
map集合中必须保证键的唯一性。
===================================================================