1.标识符命名规则
包名:域名反过来写,全部字母小写。
类或接口:每个单词都首字母大写,其余字母小写。(大驼峰)
方法和变量:第一个单词首字母小写,后续单词首字母大写。(小驼峰)
常量:所有字母都大写。
2.进制转换
二进制:0b开头 八进制:0开头 十进制:就是整数 十六进制:0~9,a,b,c,d,e,f以0x开头
其它进制转十进制:每一位上的数*(进制^(从右往左数第几个,从零开始)) 再将结果相加。
十进制转其它进制:十进制除以其他进制,将商继续做被除数,余数记录下来,直至商为0,将余数从下往上组合,产生的新数就是转换出来的进制数。
3.原码,反码,补码
一个数在计算机中二进制的表现形式就是机器数,一般是8位,首位是符号位,0是正数,1是负数。其余是数值位。
正数的原码=反码=补码
负数的反码=原码的符号位不变,其余各位取反;补码=反码的符号位不变,+1。
4.基本数据类型与引用数据类型
基本数据类型:
1.整形
byte:字节 占1个字节 8位(-128~127) int:整形 占4个字节 (-2^31~2^31) short:短整形 占两个字节 (前者的31换成15次方) long:长整形 占8个字节 (将前者的15换成63次方)
2.浮点型
float:占4个字节 单精度 double:占8个字节 双精度
单精度可以自动转换为双精度(float-->double) 反之则不行,需要强制转换,因为会产生精度缺失。
3.布尔型
Boolean (理论上占八分之一字节) 只有两个值true或者false。
4.字符型
char(占两个字节) 只能存放一个字母,数字,符号(可以存放中文汉字)。 要用单引号括起来。
在进行混合运算时,byte,short,char不会相互转换,都会转换成int型,其他混合运算小的数据类型会转换成大的数据类型。
其他数据类型与String相"+"时,结果还为字符串。
5.逻辑运算符的基本用法
&&和&(逻辑与):两个表达式只有有一个为false,则结果则为false.
不同之处:&&具有短路效果,只要前一个表达式为false,则不用计算后面的表达式,结果就为false.
&不管前面的表达式为不为false,也要计算后面的表达式,就效率而言前者更好。
||与|(逻辑或)也类同,只不过它的条件只要有一个为true,则整个结果都为true.
^(逻辑异或):两者相同则为false,两者不同则为true.
6.位运算符的基本用法
<<左移,左边最高位丢弃,右边补0,向左移动几位就乘以2的几次幂。
>>右移,做高位为1,左边就补1,最高位为0,右边就补0。向右移动了几位就除以2的几次幂。
>>>无符号右移,无论最高位是0还是1,左边都补齐为0。
7.键盘录入数据
主要用到了Scanner这个类,创建键盘录入对象,Scanner src=new Scanner(System.in);
通过键盘获取数据:int x=src.nextInt();
nextLine()是键盘录入字符串。
8.Switch语句
switch(){
case x:
执行语句;
break;
其中x的取值类型有byte,short,char,int型,在JDK1.5版本出现了枚举类型(enum),在JDK1.7版本新加了String字符串类型。
case后面只能跟常量,不能跟变量。
9.栈与堆
栈中存放的是局部变量,堆中存放的是new出来的对象。
10.Java中的参数传递:基本数据类型的值,不改变原值;引用数据类型的值,改变原值,可以通过地址继续访问。
Java中到底传值还是传地址?
Java中只传值,因为地址值也是值。
11.成员变量与局部变量,静态变量的区别
成员变量:在类中的方法外定义,存放在内存中的堆内存中,随着对象的创建而创建,随着对象的消亡而消亡,有默认的初始化值。
局部变量:在方法中定义,存放在内存中的栈内存中,随着方法的调用而创建,调用完则消亡,没有默认的初始化值,必须定义,赋值才能使用。
静态变量:它是属于类的,存放在方法区的静态区,随着类的加载而加载,随着类的消亡而消亡,可以直接用类名来调用,也可以使用对象名来调用。
静态方法只能访问静态成员。
12.继承的注意事项
1.子类只能继承父类的非私有的成员(成员方法和成员变量)
2.子类不能继承父类的构造方法,但是可以通过super来进行调用。
13.override(重写)与overload(重载)的区别是什么?
重写就是子类的方法与父类的方法名,返回值类型,参数类型,参数个数都一致。
重载就是方法名,参数类型和参数个数不一致,返回值类型也可以不一致。
子类对象调用方法时:先找子类本身,再找父类(就近原则)。
14.final关键词修饰类,方法,以及变量
final修饰类,类不能被继承。
final修饰方法,该方法不能被重写。
final修饰变量,该变量变为常量,且只能赋值一次。
15.多态
前提:1.要有继承关系
2.要有方法的重写
3.要有父类引用指向子类对象,比如Father f=new Son();
第三条中生成的对象访问成员变量和成员方法的区别:
成员变量(无论是否静态):编译看左边,运行也看左边,如果父类和子类都有一个属性int num,那么f.num访问的是父类中的num属性。
成员方法:编译看左边,运行看右边。子类Son重写了Father的方法。此时f.show()方法,调用的是子类的show()方法,属于动态绑定。
静态方法:编译看左边,运行也看左边。相当于类名.方法名,成员方法才会动态绑定,成员变量,静态方法不会动态绑定。
16.abstract抽象类(不能用private修饰)
abstract修饰一个类,会将这个类变为抽象类,此时这个类不能生成实例对象,只做对象变量的声明。当用abstract修饰方法时,这个方法变成了抽象方法,只有声明不用实现,需要子类继承实现。
一个子类继承了抽象类,这个子类必须全部继承实现父类的抽象方法,此时这个子类才能创建对象实例,否则子类也是抽象类。
有抽象方法的类是抽象类,抽象类不一定有抽象方法。
17.interface接口
接口是一个极度抽象的类型,可以包含变量和方法,变量会被隐式的指定为public static final类型,方法会被隐式的指定为public abstract方法,关键词是interface。
18.内部类
在Java中,将一个类定义到另一个类的内部,那这个类就是内部类。
内部类可以无条件的访问外部类的成员变量和成员方法。不过当外部类和内部类具有相同的成员变量和成员方法时,会发生隐藏,此时默认的调用的是内部类中的成员,如果要访问外部的成员时,需要写成以下格式:
外部类名.this.成员变量(方法)
在外部类中,外部类访问内部类的成员时,需要创建一个内部类的对象来进行访问。
成员内部类是依赖外部类而存在的,如果要创建一个内部类对象,需要先创建一个外部类对象。
public class Test {
public static void main(String[] args) {
//第一种方式:
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建
//第二种方式:
Outter.Inner inner1 = outter.getInnerInstance();
}
}
class Outter {
private Inner inner = null;
public Outter() {
}
public Inner getInnerInstance() {
if(inner == null)
inner = new Inner();
return inner;
}
class Inner {
public Inner() {
}
}
}
创建格式:外部类名.内部类名 对象名=外部类对象.内部类对象(Outer.Inner inner=new Outer().new Inner())
匿名内部类:就是没有名字的内部类,只能使用一次。使用匿名内部类有一个前提条件:必须继承一个父类或者一个接口,但最多只能继承一个类,或一个接口。
构造方式:person p=new person(){
//代码块
}
与一般的对象创建,区别在于匿名内部类后面是代码块,而创建对象是后面是“;”号。
19.==与equals()的区别:
==对于基本数据类型来说比较的是两者的值,引用数据类型比较的是两者的地址值。equals()比较的是两者的地址值,因为equals()是父类object类中的方法,但有些类会对此方法进行重写,可以比较两者的值。
20.String中的方法
(1) .length() 求字符串的长度
(2) .charAt(x) 获得下标为x的字符
(3)a .getchars(0,5,b,0) 截取多个字符并由其他字符串接受
将a字符串的下标0到5的字符,并赋值给b字符串,0是b接受字符串的开始位置。
(4).getBytes()将字符串转化为byte数组
转化为byte[]数组 String str = "罗长"; byte[] sb = str.getBytes();
将byte数组转换成字符 String str= new String (b);
(5).toCharArray()将字符串变成一个字符数组
(6)a.equals(b)与a.equalslgnoreCase(b) 两者都是比较字符串a与b是否相等的,不过前者区分大小写,后者不区分。
(7)a.startsWith(x) 判断字符串a是否以x这个特定字符开始的 b.endsWith(y) 判断字符串b是否以y这个特定字符结尾的
(8)a.toUpperCase()将字符串转化为大写 b.toLowerCase()将字符串转化为小写
(9)a.concat(b) 连接两个字符串 a的后面拼接b字符串
(10).trim() 去掉字符串起始和结束的空格(不过不去除字符串中间的空格)
(11).substring() 截取字符串
a.substring(0,5) 从开始位置0的字符,截取到末尾位置下标为5的字符(但不包括第5个字符)
b.substring(6) 从开始位置下标为6的位置截取到最后
(12).indexOf()与lastIndexOf() 前者是查找字符或者字符串第一次出现的位置,后者是查找字符或者字符串最后一次出现的地方。
(13).compareTo()和compareToIgnoreCase()按字典顺序比较两个字符串的大小,前者区分大小写,后者不区分
String a = "Hello Word";
String b = "hello word";
System.out.println(a.compareTo(b));
System.out.println(a.compareToIgnoreCase(b));
输出的结果第一条为-32,第二条为0,两个字符串在字典顺序中大小相同,返回0。
(14)a.replace(b) 将a字符串替换成b字符串。
21.StringBuffer的功能
StringBuffer字符缓冲区,当new的时候是在堆内存中创建一个对象,底层是一个长度为16的字符数组,当调用添加方法的时候,不会创建新的对象,在不断向缓冲区中添加字符。
append()是添加功能,在原字符串的最后添加字符串,形成新的字符串。
insert(int i,string s)是插入功能,在原字符串的i位置插入字符串s,形成新的字符串,其中原来的索引位置数据会往后移。
deleteCharAt(int index)删除指定位置的字符,并返回本身。
delete(int start,int end)删除从指定区间之间的字符,并返回它自身(删除的时候包含头,不包含尾)
StringBuffer的替换功能 public StringBuffer replace(int start,int end,String str): 从start开始到end用str替换
StringBuffer的反转功能 public StringBuffer reverse(): 字符串反转
StringBuffer的截取功能
注意:返回值类型不再是StringBuffer本身 public String substring(int start): 从指定位置截取到末尾
public String substring(int start,int end): 截取从指定位置开始到结束位置,包括开始位置,不包括结束位置
22.String,StringBuffer,StringBuilder三者的区别
String是一个不可变(长度不可变)的对象,每一次对它进行操作都会生成新的String对象,每次生成新的对象都会对系统性能产生影响,而后两者是可变的,对他俩的操作都是在对象本身进行操作,而后两者的区别在于,StringBuffer()是jdk1.0版本的,是线程安全的(同步就是安全的,有synchronized修饰符),效率低,StringBuffer()是jdk1.5版本的,是线程不安全的,效率高。
23.String与int类型互转
int转为String:String s=String.valueOf(i) String s = Integer.toString(i);
String转为int:int i=Integer.parseInt(s)
24.JDK5的新特性自动装箱和拆箱(jdk1.5版本)
- 自动装箱:把基本类型转换为包装类类型
- 自动拆箱:把包装类类型转换为基本类型
int x = 100;
Integer i1 = new Integer(x); //将基本数据类型包装成对象,装箱
int y = i1.intValue(); //将对象转换为基本数据类型,拆箱
System.out.println("JDK1.5之后的做法:");
Integer i2 = 100; //自动装箱,把基本数据类型转换成对象
int z = i2 + 200; //自动拆箱,把对象转换为基本数据类型
System.out.println(z);
25.正则表达式
正则表达式是一个用来描述或者匹配一系列符合语法规则的字符串的单个字符。
A.字符类
[abc] a,b,c 其实[ ]代表的是单个字符
[^abc]除了a,b,c的任何字符
[a-z A-Z]a到z A到Z,两端的字母都包含在里面
[0-9]0到9的字符都包括
B.预定义字符类
. 任何单个字符
\d 数字:[0-9]
\w 匹配字母,数字,下划线.
C.其他
. 表示匹配除换行符(\n)之外的任意字符
* 匹配前面的子表达式零次或多次
可以通过正则表达式来分割字符串 .split(String regex)//通过正则表达式切割字符串
把一个字符串中的手机号码提取出来
String s = "我的手机是18988888888,我曾用过18987654321,还用过18812345678";
String regex = "1[3578]\\d{9}";
//1表示第一位是1,[3578]表示第二位只能是3,5,7,8中的任意一个,\\d{9}表示其余位是数字
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(s);
boolean b1 = m.find();
System.out.println(b1);
//必须调find()方法来找才可以调用group
System.out.println(m.group());//18988888888
//进行找的时候,找到一个并会再次调用的时候,
//便会从之前找到的位置继续向下找,一直到最后
boolean b2 = m.find();
System.out.println(b2);
//必须调find()方法来找才可以调用group
System.out.println(m.group());//18987654321
while(m.find())
System.out.println(m.group());
与之相关的类:Pattern(获取正则表达式)和Matcher(获取匹配器)
Pattern p = Pattern.compile("a*b"); //获取到正则表达式
Matcher m = p.matcher("aaaaab"); //获取匹配器
boolean b = m.matches(); //看是否能匹配,匹配就返回true
System.out.println(b);
System.out.println("aaaaab".matches("a*b")); //与上面的结果一样
26.BigDecimal类的概述和用法
在运算的时候,float和double会丢失精度,为了能精确的表示,引入了BigDecimal这个类。
其中 BigInteger 类是针对大整数的处理类,而 BigDecimal 类则是针对大小数的处理类.
BigDecimal类创建的是对象,不能使用传统的+、-、*、/等算术运算符直接对其进行数学运算,而必须调用其对应的方法.方法的参数也必须是BigDecimal类型的对象.
成员方法:public BigDecimal add(BigDecimal augend) //加
public BigDecimal subtract(BigDecimal subtrahend) //减
public BigDecimal multiply(BigDecimal multiplicand) //乘
public BigDecimal divide(BigDecimal divisor) //除
构造方法: BigDecimal bd3 = new BigDecimal("2.0"); //BigDeciamal BigDeciamal(String s)
BigDecimal bd5 = BigDecimal.valueOf(2.0);
27.Date类的概述和方法的使用
Date类是表示日期和时间的。
构造方法:public Date();表示系统的当前时间 public Date(long date)//如果参数为0的话表示时间为1970年1月1日
成员方法:public long getTime()//相当于System.currentTimeMillis() public void setTime(long time)
SimpleDateFormat类可以实现字符串与日期的相互转化
成员方法:
将日期转化为字符串:public final String format(Date date)
将字符串转化为日期:public Date parse(String sourse)
String str="2000年08月08日 08:08:08";
SimpleDateFormat sdf=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date d=sdf.parse(str);//这个方法就是将字符串转化为日期
System.out.println(d);
其实parse()方法返回的是日期格式的数据,而format()方法返回的是字符串格式的数据。
28.集合(list集合,set集合)
数组的长度是固定的,当需要增添数据时,增添的元素个数大于数组的长度时,则需要重新定义数组。集合能存储任意大小以及长度的数据,它的长度是可变的。
数组可以存储基本数据类型,又能存储引用数据类型(引用数据类型存放的是地址),集合只能存储引用数据类型,他也可以存储基本数据类型,但是会自动装箱变成对象。
List集合:有序,可重复。ArrayList,数组结构,查询修改快,增删慢,线程不安全的。 Vector,数组结构,查询修改快,增删慢,线程安全的。
因为它是线程安全的,所以他的效率略慢于前者。 LinkedList:链表结构,查询修改慢,增删快,线程不安全的。
在开发中,查改多用的ArrayList,增删多用的LinkedList.
29.三种迭代能否删除集合中的元素
1.普通的for循环
可以删除,但是索引要-1(即i-) 如果不减1的话,被删除的元素的后一个元素的索引位置会前移一位,而i++,此时会漏掉那个元素,而减1后,等运算完成之后,i因为减一了,所以再i++,还是原来的索引位置。
ArraryList<String> list=new ArraryList<>();
list.add("a");
list.add("b");
list.add("c");
for(i=0;i<list.size();i++)
{
if(("b".equals(list.get(i)){
list.remove(i-);
}
}
2.迭代器Iterator
可以删除,但是必须用迭代器自身的remove()方法。
ArraryList<String> list=new ArraryList<>();
Iterator<String> it=list.iterator();
while(it.hasNext()){
if("b".equals(it.next())){
it.remove();
}
}
list.iterator();迭代器只有移除的方法;如果还需要增加方法,需要用到list.listIterator();(这种迭代器增加删除方法都有)
增强型for循环不能删除。
30.数组与集合List的之间的转化
1.数组转化为集合:Arrays工具类的使用,其中asList()方法。
String[] arr={"a","b","c"};
List<String> list=Arrays.asList(arr); //将数组转化为集合
其中数组要转化为集合的话,数组必须是引用数据类型的。
2.将集合转化为数组 其中toArrays方法。
ArrayList<String> list=new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
String[] arr=list.toArray(new String[10]);//将集合转化数组
31.HashSet保证元素唯一性原则
Set集合是不可重复,无序的集合。当我们调用集合的add()方法时,它会调用hashcode()方法生成一个hash值,如果集合中没有这个hash值就存储,有这个hash值的话,再调用equals()方法来逐属性比较,属性有不同的可以添加,属性完全相同的视为同一对象,无法添加。
32.TreeSet的原理
TreeSet是用来对对象元素进行排序的,同时也保证了元素唯一性的原则。其中存储的时候,如果对象不知道如何去按序存储,则可以继承Comparable接口,重写comparaTo()方法。
使用方式:comparable(自然顺序) comparator(比较器顺序)
总结:List集合:普通for循环,用get(i)来获取元素
迭代器Iterator,hasnext(),next()方法。
只要能使用迭代器,就可以使用增强型for循环。
Set集合:迭代器Iterator,hasnext(),next()方法。
只要能使用迭代器,就可以使用增强型for循环。
33.Map集合的常用方法
Map集合是基于Java中的核心类-----java.util中的,Map中存放的时key-value键值对,通过key映射到它的value.
map.size() 计算map集合的大小 返回值是int整型
map.values() 获取map集合中的所有值(value) 返回值是Collection类型
map.keySet() 获取所有的key值 返回值为Set集合类型 可以使用迭代器,再利用map.get(String key) 来得到value值
map.remove(key) 移去map中的元素,包括key和对应的value
map.clear() 清空map中的所有元素
Entry是Map集合中的一个内部接口,用于封装Map中的一组键值对<key,value>
在JDK1.5之前写法是Map.Entry<k,v> 在Jdk1.5之后写法直接是Entry
Entry entry;
Map map=new HashMap();
map.put("1","苹果");
map.put("2","香蕉");
Set set=map.entrySet();
//Set<Map.Entry<String, Integer>> entrySet = map.entrySet();
Iterator iterator=set.iterator();
while(iterator.hasnext()){
entry=(Map.Entry)iterator.next(); //此处就是用entry内部接口来封装一组键值
String key=(String)entry.getKey();
String value=(String)entry.getValue();
}
34.HashMap与Hashtable的区别与联系
1.产生时间:Hashtable产生于JDK1.1版本 HashMap产生于JDK1.2版本
2.继承的类,对外接口不同:HashMap继承的是AbstractMap,而HashTable继承的是Dictionary.其中Dictionary是一个已经废弃的类,Hashtable比HashMap多了两个公开的方法,分别是elements,contains.
3.Hashmap的键值可以为null值,而Hashtable的键值不能是null值。
4.HashMap是非线程安全的,而Hashtable是线程安全的,(最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap),所以前者比后者的开发效率高一些。
5.HashMap的初始容量是16,Hashtable的初始容量是11,两者的填充因子都是0.75。
6.扩容:HashMap扩容是当前容量翻倍,Hashtable是当前容量翻倍再加一。
35.Collections工具类(操作集合)
Collections.sort(list1) 对list集合进行排序
Collections.reverse(list1); 对集合list1进行反转
Collections.shuffle(list1); 将集合list1中的元素随机置换,打乱顺序。
HashMap map1=new HashMap();
Collections.synchronizedMap(map1); //HashMap是非线程安全的,此方法为外部提供的加安全锁方法。
int j=Collections.binarySearch(poker,"红桃5"); 利用二分查找找key值
int i=Integer.valueOf(Collections.max(li1).toString()); 根据默认排序结果获取集合中的最大值
36.集合总结
1.List(存取有序,有索引,可以重复)
ArrayList:底层是数组实现,是线程不安全的,查找和修改快,增删比较慢。
LinkedList:底层是链表实现的,是线程不安全的,增删快,查找和修改慢。
vector:底层是数组实现的,是线程安全的,增删改查都慢。
查找,修改多的用ArrayList;增加和删除多的,用LinkedList;都多的用ArrayList.
2.Set(无序,无索引,不可以重复)
HashSet:底层是hash算法实现
LinkedHashSet:底层是链表实现,和HashSet的原理一样,但他可以保证元素的顺序与你添加进set集合中的元素顺序相同
(元素唯一,存取有序)
TreeSet,底层是二叉树算法,会对存储的元素进行排序。
3.map(键值对集合)
HashMap:底层是哈希算法; LinkedHashMap:底层是链表; TreeMap:底层是二叉树算法。
37.异常处理
1. try...catch...finally
try:用来检测异常 catch:用来捕获异常 finally:释放资源
例:
int a=10;
int b=0;
try{
System.out.println(a/b);
}catch (Exception e){
e.printStackTrace();
}
Throwable的常用方法:e.printStackTrace(),可以获得异常类名和异常信息,异常在程序中的位置,返回值为void.jvm默认用此 方式处理异常。
2.throws与throw的区别
a.throws跟在方法声明后面,后面跟异常类名;可以跟多个异常类名,用逗号隔开;表示抛出异常,由该方法的调用者来处理
b.throw用在方法体内,跟的是异常对象名;只能抛出一个异常对象名;抛出的异常由方法体内的语句处理。
3.final,finally,finalize的区别
final修饰的类不能被继承,修饰的方法不能被重写,修饰的变量只能赋值一次。
finally是try中的一个语句块,不能单独使用,是用来释放资源的(程序中必须执行的部分)
finalize是一个方法,主要用在垃圾回收之中。
4.catch中有return语句,finally代码还是会执行的,return语句相当于方法的最后一口气,finally中执行了之后就会彻底返回。
finally中是为了释放资源的,其中不要写return语句。
38.File类
File更应该叫一个路径,绝对路径(C:\Users\Lenovo\Downloads),相对路径(在Users下路径则为Lenovo\Downloads)。
构造方法:1.File(String pathname):根据一个路径得到File对象。
2.File(String parent,String child):根据一个父目录,和一个子目录(相对路径)得到File对象。
功能:创建,file.creatNewFile(); 删除,file.delete().
获取:1.得到绝对路径 public String getAbsolutePath()
2.获取名称 public String getName()
3.public long length():获取长度。字节数
4.public long lastModified():获取最后一次的修改时间,毫秒值(一般结合SimpleDateFormat跟Date使用)
5.获取指定目录下所有文件和文件夹的名称(数组形式,仅获得名称) public String[] list()
6.和上一个类似,不过获取的是File对象数组(通过对象进而获得各个文件的路径) public File[] listFiles()
String path="E:\\workspace\\comvertx";
File file=new File(path);
File[] names=file.listFiles();
for(int i=0;i<names.length;i++){
System.out.println(names[i].getAbsolutePath());
}
运行结果:
判断:1.public boolean exists(): 判断文件是否存在
2.public boolean isDirectory():判断是否是目录
39.IO流概述及其分类
流按流向分为:输入流,输出流;
流按操作类型分:字节流,可以操作任何数据,计算机中的数据都是以字节形式存储的。
字符流,只能操作纯字符的数据。
IO流的常用父类:1.字节流的抽象父类:InputStream,OutputStream(创建字节输出流对象,没有就自动创建一个)。
2.字符流的抽象父类:Reader,Writer