基本数据类型(byte,short,int,long,float,double,char,boolean)
- byte a=1; //byte 整数,1个字节 -128~127
- short b=2; //short 整数,2个字节 -32768~32767
- int c=3; //int 整数,4个字节 -2147483648~2147483647
- long d=4; //long 整数,8个字节 范围为 -9223372036854775808~223372036854775807
- float e=1.2f; //float 浮点型,4个字节,定义时变量后面要加f,因为浮点数系统默认为double型
- double f=2.3; //double 浮点型,8个字节
- char h=‘d’; //char 字符型,2个字节,定义变量时使用‘ ’(单引号)
- boolean a=true; // boolean 布尔型,1个字节,有两个取值,false和true.
什么是jdk,jre,jvm?
jdk称为java开发工具 包含了jre..并且jdk的api适合开发使用
jre称为java运行环境 包含了jvm..jre用于运行java程序.
jvm称为java虚拟机 java程序运行的编译,运行的内存分配...都是jvm来完成的
jdk包含jre包含jvm
浮点数值问题,小数点后几位 ,DecimalFormat,BigDecimal
DecimalFormat用法,解决精度问题,保留两位小数,得到的结果为String类型。
DecimalFormat decimalFormat = new DecimalFormat("#.##");
String aaa = decimalFormat.format(0.15*111);
System.out.println(aaa);
BigDecimal用法 解决精度问题,这样想乘可以保留计算原有的精度。
double res = BigDecimal.valueOf(106).multiply(BigDecimal.valueOf(0.13))
.doubleValue();
System.out.println(res);
String 解析
String为一个类,强类型,定义方法有:
String a1=“a”; String b1 = new String(“a”);
如果采用String a1=“a”;的定义方法,则声明的变量如果是一个常量,会存储在常量区中,且再次定义相同的常量给一个变量时(如:String a2=“a”;),会把该常量的地址赋给新的变量,所以此时 a== b 为true;
如果采用 String b1 = new String(“a”); 的定义方法,则定义的变量会把变量存储到堆中,每一次定义一个变量都会重新定义,所以地址不一样,于是如果再次定义一个变量 String b2 = new String(“a”); ,则 b1==b2 为false;
注意,当使用Scanner的next()输入时,可以看做是使用 String b2 = new String(“a”); 方法定义变量,会储存到堆中。
所以String如果需要比较值,有一个方法 equals ,如 “a”.equals(b1); 如果值相等则返回true,使用这种方法时,建议把需要比较的字符放在前面,把变量放在后面,原因是变量有可能为null,这样会导致程序报错,后续代码无法执行。
String为不可变的类, 如果字符串反复的累加或变更,不推荐使用,造成性能问题.浪费空间
String为final修饰的类,不可继承
String类部分方法
.toLowerCase("aBc") 将aBc全部转成小写
.toUpperCase("aBc") 将aBc全部转成大写
注意:转成大小写并不会改变原字符,如果需要得到改变后的字符,
要用一个String的变量去接返回值
.endsWith("abc") 以某段字符(abc)结尾
.startsWith("abc") 以某段字符(abc)开头
String.valueOf(num) j将num转化为String类型
lastIndexOf(String str): 返回指定子字符串在此字符串中最右边出现处的索引,如果此
字符串中没有这样的字符,则返回 -1。
lastIndexOf(String str, int fromIndex): 返回指定子字符串在此字符串中最后一次出现处
的索引,从指定的索引开始反向搜索,如果此字符串中没有这样的字符,则返回 -1。
indexOf(String str): 返回指定字符在字符串中第一次出现处的索引,如果
此字符串中没有这样的字符,则返回 -1。
indexOf(String str, int fromIndex): 返回从 fromIndex 位置开始查找指定字
符在字符串中第一次出现处的索引,如果此字符串中没有这样的字符,
则返回 -1。
charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length() - 1。
substring(int beginIndex, int endIndex)
第一个int为开始的索引,对应String数字中的开始位置,
第二个是截止的索引位置,对应String中的结束位置
1、取得的字符串长度为:endIndex - beginIndex;
2、从beginIndex开始取,到endIndex结束,从0开始数,其中不包括
endIndex位置的字符
trim() 方法用于删除字符串的头尾空白符。
replace(char searchChar, char newChar) 通过用 newChar 字符替换字
符串中出现的所有 searchChar 字符,并返回替换后的新字符串。
searchChar -- 原字符。
newChar -- 新字符。
replaceAll(String regex, String replacement)使用给定的参数 replacement
替换字符串所有匹配给定的正则表达式的子字符串。
regex -- 匹配此字符串的正则表达式。
replacement -- 用来替换每个匹配项的字符串。
concat(String s) 方法用于将指定的字符串参数连接到字符串上。
s -- 要连接的字符串。
split() 根据正则规则或某个字符对字符串进行切割,返回切割好的数组。
如果没有找到该字符,则会返回数组长度位1且该数据为原字符串的数组
StringBuilder.insert(int dstOffset, CharSequence s) 方法插入指定的
CharSequence到这个序列
CharSequence参数的字符插入的顺序,在这个顺序的指定位置,向上
移动原来的字符的位置和由参数s的长度增加该序列的长度。
String和StringBuffer、StringBuilder
String底层是不可变的类,所以每次赋值都会重新创建新的对象所以如果要频繁的修改
字符串的值,不推荐使用String
如果反复变更,我们推荐使用StringBuilder/StringBuffer, 多线程并发情况下考虑使用
StringBuffer, 因为synchronize关键字保证了该方法的安全性.
如果不考虑多线程环境,那么推荐使用StringBuilder,性能更高.
==和equlas的区别
== 基本类型比较值,
String的equals 方法是比较内容本身,和地址无关,
内容相等则返回true.
== 如果相等, 那么 equals 一定相等
反之, equals相等, ==不一定相等
包装类的equals首先判断是否同一类型, 如果类型不同直接false,
还来不及比数据.
包装类和基本数据类型比较的时候, 统一按基本数据类型比较.比较值.
常量池
“啊”,1,2,4数据称为常量,常量池中如果没有第一次会创建该常量,然后返回引用,如果有,直接返回常量的引用,不会再创建
整数常量池中默认只有 -128~127 共256个数. 后续的会在堆中开辟新的.
堆
用户每次new关键字的对象,都会在堆内存中创建
一个新的对象,并返回该新对象的引用.
包装类和基本数据类型的区别?
1. 包装类可以为null ,原生类不可以为null.
2. 包装类默认实现了一些方法,方便使用. 原生类没有方法.
3. 包装类属于强类型, 引用传递. 原生类属于值传递.
4. (PS:如果包装类要和原生类比较数据, 那么按原生类比较,因为原生类没有地址.)
switch 允许的数据类型
char, byte, short, int, Character, Byte, Short, Integer, String, enum
jdk1.8及以上
jdk1.6及以下不支持String
final关键字
final修饰类: 该类不允许被继承
final修饰方法: 该方法不可以被重写,可以重载.
final修饰属性: 该属性的值不能变. 如果是强类型,
那么该地址值指向的对象里面的属性值是可变的.
static关键字
static可以修饰内部类,方法,属性,代码块,静态导入(静态导包).
static修饰的属性和方法它们属于类的,可以使用类名和对象访问,但是推荐使用类名访
问,不依赖对象。
且只有一份空间. 多个地方调用会有数据共享安全的问题,一般在属性上面加上final使
其只读,否则多处修改会造成数据安全的为题。
static会最先执行.不需要依赖实例.
static不可以直接调用实例方法. 实例方法可以直接调用静态方法
由于是类的属性和方法,所以存放在方法区中,除非卸载类,否则GC不予回收,所以不
能够什么都去用static修饰方法。一般在工具类中的方法考虑添加static。
内部类
内部类
内部类的分类
A:成员内部类
B:局部内部类
C:静态内部类
D:匿名内部类
类定义在另一个类的内部,该类就被称为内部类。
内部类的访问规则
A:可以直接访问外部类的成员,包括私有
B:外部类要想访问内部类成员,必须创建对象
成员内部类
成员内部类——就是位于外部类成员位置的类
特点:可以使用外部类中所有的成员变量和成员方法(包括private的)
成员内部类常见修饰符:
A:private如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内
部类,这样我们就无法通过创建对象的方法来访问,想要访问只需要在外部类中定
义一个public修饰的方法,间接调用。这样做的好处就是,我们可以在这个public方
法中增加一些判断语句,起到数据安全的作用。
B:static这种被 static 所修饰的内部类,按位置分,属于成员内部类,但也可以称
作静态内部类,也常叫做嵌套内部类。具体内容我们在下面详细讲解。
局部内部类
局部内部类——就是定义在一个方法或者一个作用域里面的类
特点:主要是作用域发生了变化,只能在自身所在方法和属性中被使用
为什么局部内部类访问局部变量必须加final修饰呢?
因为局部变量是随着方法的调用而调用,使用完毕就消失,而堆内存的数据并不会
立即消失。所以,堆内存还是用该变量,而该变量已经没有了。为了让该值还存
在,就加final修饰。原因是,当我们使用final修饰变量后,堆内存直接存储的是
值,而不是变量名。
匿名内部类
匿名内部类一定是跟在new的后面,用其隐含实现一个接口或一个类,没有类名,根据
多态,我们使用其父类名。因为匿名内部类属于局部类,所以局部类的所有限制对其
生效。匿名内部类是唯一一种无构造方法的类。匿名内部类在编译时,系统自动起名
Out$1.class。如果一个对象编译时的类型是接口,那么其运行的类型为实现这个接口
的类。匿名内部类只能使用一次。
注意点:
1.不能有构造方法
2.不能定义任何静态成员、方法或类
3.不能是public,protected,private,static。
4.只能创建匿名内部类的一个实例。
静态内部类
我们所知道static是不能用来修饰类的,但是成员内部类可以看做外部类中的一个成员,
所以可以用static修饰,这种用static修饰的内部类我们称作静态内部类,也称作嵌套内
部类.
特点:不能使用外部类的非static成员变量和成员方法
解释:非静态内部类编译后会默认的保存一个指向外部类的引用,而静态类却没有。
简单理解:
即使没有外部类对象,也可以创建静态内部类对象,而外部类的非static成员必须
依赖于对象的调用,静态成员则可以直接使用类调用,不必依赖于外部类的对象,
所以静态内部类只能访问静态的外部属性和方法。
使用内部类的原因
(一) 封装性作为一个类的编写者,我们很显然需要对这个类的使用访问者的访问权限
做出一定的限制,我们需要将一些我们不愿意让别人看到的操作隐藏起来,如果我
们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就
无法通过创建对象的方法来访问,想要访问只需要在外部类中定义一个public修饰
的方法,间接调用。
(二) 实现多继承 ※我们之前的学习知道,java是不可以实现多继承的,一次只能继承
一个类,我们学习接口的时候,有提到可以用接口来实现多继承的效果,即一个接
口有多个实现,但是这里也是有一点弊端的,那就是,一旦实现一个接口就必须实
现里面的所有方法,有时候就会出现一些累赘,但是使用内部类可以很好的解决这
些问题
(三) 用匿名内部类实现回调功能
我们用通俗讲解就是说在Java中,通常就是编写一个接口,然后你来实现这个接
口,然后把这个接口的一个对象作以参数的形式传到另一个程序方法中, 然后通过
接口调用你的方法,匿名内部类就可以很好的展现了这一种回调功能
(四) 解决继承及实现接口出现同名方法的问题
重写和重载
重载发生在同一个类中, 方法名相同, 参数类型/列表个数不同,
和方法签名的其他任何关键字无关.
重写发生在子类继承父类的关系中, 方法名相同, 参数类型/列表也要相同,
权限访问修饰符不能比父类更严格(小);
返回值类型必须和父类相同或是父类返回值类型的子类/实现类.
声明的异常不能比父类更大
char型变量能不能储存一个中文汉字?为什么?
char型变量是用来存储Unicode编码的字符的,unicode编码字符集中包含了汉字,
所以,char型变量中可以存储汉字。unicode编码字符集包含了全世界所有的字体。
ArrayList、LinkedList、Map、Set
- ArrayList和LinkedList实现自List接口,基类接口为Collection
- HashSet和TreeSet实现自Set接口,基类接口为Collection
- ArrayList和LinkedList有序,可重复
- HashSet无序,不可重复
- TreeSet排序(存放的排序数据需要实现Comparable接口),不可重复
- 遍历方法:
- 1.利用 Iterator 类
- Iterator iterator = set.iterator();
while(iterator.hasNext()) {
System.out.println(iterator.next());
}
- 2.for each
- for(Object data : set) {
System.out.println(data);
}
- 3.for 循环
- Map 的遍历:
- a.Set set = map.keySet();
for (Object key : set) {
System.out.println(key + "--->" + map.get(key));
}
b.Collection values = map.values();
for (Object value : values) {
System.out.println(value);
}
java运算符 与(&)、非(~)、或(|)、异或(^)
1.位异或运算(^)
运算规则是:两个数转为二进制,然后从高位开始比较,如果相同则为0,不相同则为1。
比如:8^11.
8转为二进制是1000,11转为二进制是1011.从高位开始比较得到的是:0011.然后二进制转为十进制,就是
Integer.parseInt("0011",2)=3;
2.位与运算符(&)
运算规则:两个数都转为二进制,然后从高位开始比较,如果两个数都为1则为1,否则为0。
比如:129&128.
129转换成二进制就是10000001,128转换成二进制就是10000000。从高位开始比较得到,得到10000000,即128.
3.位或运算符(|)
运算规则:两个数都转为二进制,然后从高位开始比较,两个数只要有一个为1则为1,否则就为0。
比如:129|128.
129转换成二进制就是10000001,128转换成二进制就是10000000。从高位开始比较得到,得到10000001,即129.
4.位非运算符(~)
运算规则:如果位为0,结果是1,如果位为1,结果是0.
比如:~37
在Java中,所有数据的表示方法都是以补码的形式表示,如果没有特殊说明,Java中的数据类型默认是int,int数据类型的长度是8位,一位是四个字节,就是32字节,32bit.
8转为二进制是100101.
补码后为: 00000000 00000000 00000000 00100101
取反为: 11111111 11111111 11111111 11011010
因为高位是1,所以原码为负数,负数的补码是其绝对值的原码取反,末尾再加1。
因此,我们可将这个二进制数的补码进行还原: 首先,末尾减1得
反码:11111111 11111111 11111111 11011001 其次,将各位取反得
原码:00000000 00000000 00000000 00100110,此时二进制转原码为38
所以~37 = -38.