数组
一、初始化:
1、静态初始化
2、动态初始化
特性:1、长度一旦定义无法改变
3、数组的声明和初始化应按从高维到低维的顺序进行,如:
方法(1);
int a[][] = new int[3][];
a[0] = new int[2];
a[1] = new int[4];
a[2] = new int[3];//正确
int t[][] = new int[][4];//非法
二、关于数组的方法:
1、排序Arrays.sort(数组);
2、数组拷贝System.arraycopy(源数组,0,目标数组,0,源数组长度)
内存解析
例:Product p = new Product();
变量p存在于栈,对象实际存储地址new Product()在堆里。
栈存储的是堆中的实际存储地址,sout(p)输出哈希码
- JVM:java虚拟机
内存空间:Product p = new Product();
栈(STACK每个线程都有自己的独立栈区):引用类型:存储的是内存地址p=哈希码,基本类型:存储的是值
堆(HEAP共享区域):new Product()位于HEAP,只要是创建对象new就存储于堆里面
线程计数器(确定独立栈个数):
方法区:字符串常量值,方法,常量(static)
二、==比较符
1、引用类型比较的是哈希码,如果哈希码相等两对象相等。
2、字符串类型调用==有几种不同的处理:
a).String s1 = “字符串”;
String s2 = “字符串”;
s1 == s2----true比较的是字符串常量池里面的值。
b). String s1 = new String(“字符串”);
String s2 = new String(“字符串”);
s1 == s2----false比较的是哈希码
c).toString
String s1 = new String("test");
String s2 = new String("test");
s1 = s1.toString();
s2 = s2.toString();
s1 == s2 ----false因为String.toString()返回的是this
- 栈(stack):先进后出。每一个独立线程栈区,栈个数由计数器决定
- 计数器:统计线程数
- 堆(heap):
- 方法区:字符串常量池存在于方法区,
- ==和equal的区别,==比较基本类型时默认比较值,基本类型存储于栈区域内。
如果要equals来判断引用类型是否相等,则要重写equals()方法和hashCode()方法,可自动生成。Object类中的hashCode()方法是根据对象内存求得哈希值。
hashcode的一些规定:
两个对象相等,hashcode一定相等
两个对象不等,hashcode不一定不等
hashcode相等,两个对象不一定相等
hashcode不等,两个对象一定不等
重写equals()方法时同时需要重写hashCode()方法,因为如果两个对象相等但内存不等时,则默认hashCode()方法是根据内存求出哈希值,则两个哈希值不一定相等与规定矛盾。所以重写equals()方法时需要重写hashCode()方法、。
- 值传递
- 多态
父类引用指向子类对象(Object obj = new Student(); Object instanceof Student返回值为true。向上转型,父类不能调用子类对象)
- 继承
- 构造器执行不代表对象创建;
- 子类可以使用父类中非私有的属性以及方法;
- 如果父类有带参数的构造器,
- 则必须重写无参构造,因为子类构造器会默认调用父类无参构造进行一些初始化操作。
- 可以在子类构造器里面调用父类的有参构造,super(有参数),此时父类可以不用重写无参构造。
4、Son s = new Son();
s.Driver();
Father f = new Son();
f.Driver();
子类重写了父类的Driver方法,new哪个类就调用哪个类的方法,就算是在父类里面调用Driver方法,实际调用的还是子类的Driver,除非new Father(),在会掉父类的Driver,要想调用父类的Driver方法,可以使用super.Driver()关键字
static,final关键字,与对象无关,与类直接相关,类加载的时候,所有的static元素都会被初始化,static可以用于修饰属性,方法,类(静态内部类,不可修饰外部类)
静态块static{
//只执行一次,最先执行,一般用于资源的开启以及释放,创建数据库的驱动。
}
游离块 {
//在对象构造器之前执行,创建一次执行一次,
}
执行顺序:静态快>游离块>构造器
Final:用于修饰属性(赋值后不能修改)、类(不能被继承)、方法(不能重写)
final成员变量可以不赋初始值,但必须在构造器里面赋值(最先被默认调用的构造器),并且赋值后不能修改。
被final修饰的变量,不可变的是变量的引用,而不是变量的内容
内部类:作用—
1、有同样的方法可以写到内部类里
2、可以用内部类实现同时继承两个类
- 普通内部类:不能定义静态属性、方法。与普通方法声明在同一级别;new Outter().new Inner();
- 静态内部类:可以定义静态属性、静态方法和普通属性,普通方法。与静态方法声明在同一级别;Outter.new Inner()
- 局部内部类:不允许有静态方法、属性。在局部内部类中如果需要使用外部类的局部变量,则外部方法的局部变量必须声明为final(延长局部变量生命周期)。具备内部类的方法中不能修改内部类所在方法的局部变量i,但可以访问。因为方法和内部类的生命周期不一致,所以当要使用局部变量i时最好加上final修饰,延长i的生命周期。局部内部类可以修改外部类的全局变量。
4.匿名内部类:
应用:
回调函数1:监听器方法给一个接口对象,并调用接口里面的方法,所以当调用监听器方法的时候,因为参数是接口对象,且click未实现,则必须在创建的时候实现这个click函数,这样的方法称为钩子方法或者回调函数
回调函数2:用一个类去继承这个内部接口,然后实现click方法,监听器方法参数就可以是this了,因为this是本身对象,而自己所属类有继承了接口,所以直接用this。
简要概述如何使用:一个button类,类内部存在一个未实现的接口,接口内方法未实现;类内部有一个为按钮设置监听的方法,参数是接口对象,监听方法内部调用接口的方法。所以在使用btn对象并调用监听方法的时候就要创建匿名内部类。
异常
一、错误与异常
- 错误(ERROR):JVM系统内部错误,或者资源耗尽等一些严重情况(程序员无法解决,也不需要解决)
- 异常(EXCEPTION):由于编程的问题,比如被0除,空指针,数组下标越界导致的一些异常(可以解决,也需要解决)
a).运行时异常(RuntimeExcepttion):只有当程序运行是时出现,不需要捕获,始终会报错(抛出无效,仍然报错)
ClassCastException:类型转换异常,
Object i = new Integer("1"); //向下转型
System.out.println((String) i);// String是Object的子类,但不是Integer的子类 转换失败
ArithmeticException:算数异常,10/0
IndexOutOfBoundsException:数组下标越界
NullPointerException:空指针异常,null.func()
InputMismatchException:输入类型异常
IllegalArgumentsException:非法参数异常
NumberFormaterException:数字格式化异常Integer.parseInt(“10a”)
NoSuchElementException:没有找到元素异常à迭代器next()方法
b).检查时异常(CheckException):一般异常,在编译时就提醒程序员需要解决,需要抛出或捕获,否则无法通过。
ClassNotFoundException:类未找到异常class.forName(“com.servlet.Demo1”);
IOException
FileNotFoundException:文件未找到异常new FileInputStream(new File(“”));
EOFException
二、异常相关问题
1、e.printStackTrace();//打印错误堆栈信息
2、子类重写父类方法,如果父类方法没有抛出异常,子类方法不能抛出检查型异常只能捕获,但是子类可以抛出运行时异常。
3、子类抛出的异常必须比父类小(子类或当前异常类)。
4、捕获多种异常时必须按照继承关系依次添加(先子异常,后父异常)
5、无论是否异常,finally语句块始终会执行。
6、a)正常return 30
b)异常return 30
c)不异常return20
常用类
byte-Byte
short-Short
int-Integer:(int)强转向下取整
范围Integer.MIN_VALUE----Integer.MAX_VALUE
基本数据类型自动拆箱:int i = = new Integer(“10”);
基本数据类型自动装箱:Integer j = 10;
二进制取反:Integer.reverse(1)//-2147483648
转double类型:doubleValue()
转String类型:String.valueOf(i)-----Integer.toString(100)-----i+””
转16进制Integer.toHexString(10);
long-Long
float-Float
double-Double
double存在精度问题,建议用String,double d1=0.1,d2=0.09;d1-d2=0.010000000009
char-Character
Character.isLetter(char c)判断指定字符是否为字母,isLetterOrDigit(char c)
转小写:toLowerCase(char ch) 转大写:toUpperCase(int codePoint)—Unicode
char(‘A’ + 32)àA
Boolean-Boolean
BigDecimal
不使用double作为构造器参数,结果精度丢失大,作为金额类型,subtract减
加法 add
减法 subtract
乘法 multiply
除法 divide
四舍五入,保留两位小数:stockCurrents.setScale(2,BigDecimal.ROUND_HALF_UP)
DecimalFormat:数字格式化
使用方法:1. DecimalFormat format = new DecimalFormat(“##,###.##”);
2.double d = 123456789.987654321;
3.String s = format.format(d);à123.456.789.99
New DecimalFormat(“.##”);à百分号
String:定长字符串(字符序列CharSequence)
存储在方法区常量池,一旦定义无法改变,只能改变引用的指向,指向不同的地址。String s = “11”; s += “11”;会创建新地址存储。做少量更改操作效率较高,做大量拼接操作效率较低。
String.charAt(int i):返回char,可以将String看作一个char[],i是数组下标
String.endsWith(“aaa”):返回boolean,是否以.”aaa”开始
String.endsWith(“.txt”):返回boolean,是否以.”txt”结尾
String.equalsIgnoreCase(String):忽略大小写比较
String.getBytes():获得byte数组
String.indexOf(char)、indexOf(String):指定字符或字符串第一次出现的下标
String.lastIndexOf(char)、lastIndexOf(String):指定字符或字符串最后一次出现的下标
String.replace(String i, String j):将出现的所有字符串i替换为字符串j
String.replaceAll(String regex, String str):根据正则表达式替换
String.substring(int i):从i截到末尾
String.substring(int i, int j):从i下标截到j下标
String.toUpperCase():变大写
String.toLowerCase():变小写
String.trim():去前后空格
String.valueOf(char[]):返回值String
StringBuffer:可变长度的字符序列
内部包含一个字符串缓冲区,所以在进行字符串拼接时效率高。由于线程同步性,在多线程环境下使用时效率下降
StringBuffer的replace方法不能替换所有,只能替换固定下标的字符串,这里可以通过buff.toString().replace()来替代
indexOf (","):返回第一次出现的下标(从左往右)
lastIndexOf (","):返回最后一次出现的下标(从右往左)
replace(int start, int end, String s):从下标开始位置开始替换,end-start为替换长度
append(String ):拼接字符串
StringBuilder:跟StringBuffer共享API
在单线程环境下使用效率与StringBuffer一致。由于线程不同步,多线程环境下使用效率比StringBuffer高,可能由于线程并发导致结果不一致
Math:数学类
Math.PI:π
Math.abs(int ):绝对值
Math.cbrt(int ):立方根—三次方根
Math.ceil(int ):向上取整,大
Math.floor(int ):向下取整,小
Math.round(int ):四舍五入
Math.log(int ):自然对数,底数是eà Math.log (Math.E)=1
Math.floor(int ):
Math.max(int,int):求大的数
Math.pow (int 2,int 4):2的4次方
Math.random ()://获取大于等于0.0小于1.0之间的伪随机double值
(int)(Math.random() * 49)://向下取整,获取0-48的所有int数
Math.ceil(Math.random() * 49)://向上 获取1.0-49.0的所有double,包括 1.0和49.0
Random:随机数类
Random.nextInt():在整数范围内随机取整
Random.nextInt(49):获取大于等于0小于49的随机int数
System:
System.arraycopy(数组1, 开始拷贝下标, 数组2, 复制下标, 拷贝长度);
long time = System.currentTimeMillis():获取从1970年1月1日00:00:00到当前时间的毫秒数
Properties props = System.getProperties():获取系统运行环境的属性信息
Props.get(“java.version”):jdk版本
Runtime:运行环境对象,单例模式Runtime.getRuntime()
rt.exec("F:\\Program Files (x86)\\Tencent\\QQ\\Bin\\QQScLauncher.exe");//运行程序
rt.totalMemory():返回Java虚拟机中的内存量
rt.maxMemory():返回Java虚拟机试图使用的最大内存量,单位byte-/1024/1024(兆)
File:文件操作类(Linux(redhat,unbantu,centos,android)Mac Windows
File.pathSeparator:获取一个与操作系统相关路径分隔符,windows是 ;分号,例如环境变量里面用分号分割
File.separator:与系统有关的默认名称分隔符windows(\\或/) linux(/)
New File(“d:/temp”, “log.txt”);初始化 dir路径,文件名
canExecute():是否是可执行文件
canRead():是否可读
canWriter():是否可写
delete():删除
exists():判断文件是否存在
isDirectory():是否是目录 、false 为文件
getName():获取文件名
listFile():目录下所有文件
listFile(new FilenameFilter、、、new FileFilter):目录下过滤文件
createNewFile():创建文件,如果路径不存在不能创建
mkdir():创建一级子目录,不能创建文件
mkdirs():创建多级子目录,不能创建文件
getParentFile():获得父文件
createTempFile(“filename”, “.后缀名”):创建临时文件,文件名filename1231不会删除
File.createTempFile("wan",".txt",new File("d:/"));:创建临时文件
getAbsolutePath():获得文件路径+文件名
delete():删除文件,如果当前文件夹有子文件,则无法删除
length():获取文件大小 单位:byte,目录大小为0
long time = lastModified():最后修改时间
File[] files = File.listRoots():获取可用磁盘数组{C:\、D:\、E:\、F:\}
renameTo():重命名
Date:日期类
new Date():获取当前时间
new Date(long time):指定时间创建Date类
long time = getTime():获取毫秒数
SimpDateFormate():时间格式化 2018-12-24 22:21:20 269
Date->String format(Date )
String->Date parse(String )
注:如果使用三个参数的构造器 1900年开始算。
枚举:enum
调用:(SortType sorType)
泛型:jdk1.5以后 T相当于占位符,不用做类型转换
2、加了泛型后编译不通过,避免类型转换异常
菱形
参数可以多个泛型
集合
一、Collection(序列):
是jdk1.2之后新增的一个集合框架的上层接口,所有存储单个元素的集合都是从Collection接口继承
(1)、List:有序集合(允许重复元素)
(2)、ArrayList:动态数组,存储类型可变,不同步。
容量不足时自动增长之前长度的一半。查快改慢
(3)、Vector:动态数组,存储类型可变,同步。
容量不足时自动增长之前长度的一倍
(4)、LinkedList:基于链表的实现,元素存储不是连续结构。
通过元素首尾指针链接,改快查慢
(5)、Set:无序集合,没有下标只能通过foreach或迭代
HashSet:不允许重复元素(内存地址)(否则覆盖),元素顺序不按照添加(add)顺序存储
TreeSet:根据自然顺序排序(实现了Cmparable),存储的类型必须实现Comparable接口。或者给构造器传入一个比较器
TreeSet ts = new TreeSet(new Comparator<IteratorDemo>() {
@Override
public int compare(IteratorDemo i1, IteratorDemo i2) {
return 0;
}
});
二、Queue:队列,先进先出。
(1)、PriorityQueue:根据自然顺序排序(实现了Cmparable)
poll():获取并删除,出队列
peek():获取不删除
(2)、ArrayDeque:双端队列,按加入顺序排序
三、Map:以键值对结构存储元素(Map不是Collection子接口)ContainsKey()用来检验对象是否已经存在
遍历map
/*方法1 推荐使用 键值都需要且容量较大时*/
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
/*方法2 迭代器 适用于需要删除元素时*/
Iterator<Map.Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
System.out.println("Key = " + entry.getKey() + ", Value = " + entry.getValue());
}
/*方法3 只取value*/
for (String value : map.values()) {
System.out.println("Value = " + value);
}
/*方法4 效率低*/
for (String key : map.keySet()) {
System.out.println("key= " + key + " and value= " + map.get(key));
}
(1)、HashMap:键值都可以是任意类型(不可以是基础类型),存入元素无序
基于Hash表的顺序只对于映射关系中的键(key)排序,不允许重复的键,可以存储重复的值。可以存放null键
(2)、TreeMap:不允许键为null,NullPointException。存入元素有序
根据键的自然顺序排序(comparable),或者提供一个comparator进行排序。new TreeMap(传入一个比较器)
Map<String,String> map = new TreeMap<User,User>(new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
return 0;
}
});
1、存放顺序:HashMap通过hashcode对其内容进行快速查找,而 TreeMap中所有的元素都保持着某种固定的顺序,如果你需要得到一个有序的结果你就应该使用TreeMap(HashMap中元素的排列顺序是不固定的)。
2、AbstractMap抽象类和SortedMap接口
AbstractMap抽象类:(HashMap继承AbstractMap)覆盖了equals()和hashCode()方法以确保两个相等映射返回相同的哈希码。如果两个映射大小相等、包含同样的键且每个键在这两个映射中对应的值都相同,则这两个映射相等。映射的哈希码是映射元素哈希码的总和,其中每个元素是Map.Entry接口的一个实现。因此,不论映射内部顺序如何,两个相等映射会报告相同的哈希码。
SortedMap接口:(TreeMap继承自SortedMap)它用来保持键的有序顺序。SortedMap接口为映像的视图(子集),包括两个端点提供了访问方法。除了排序是作用于映射的键以外,处理SortedMap和处理SortedSet一样。添加到SortedMap实现类的元素必须实现Comparable接口,否则您必须给它的构造函数提供一个Comparator接口的实现。TreeMap类是它的唯一一份实现。
3、两种常规Map实现
HashMap:基于哈希表实现。使用HashMap要求添加的键类明确定义了hashCode()和equals()[可以重写hashCode()和equals()],为了优化HashMap空间的使用,您可以调优初始容量和负载因子。
(1)HashMap(): 构建一个空的哈希映像
(2)HashMap(Map m): 构建一个哈希映像,并且添加映像m的所有映射
(3)HashMap(int initialCapacity): 构建一个拥有特定容量的空的哈希映像
(4)HashMap(int initialCapacity, float loadFactor): 构建一个拥有特定容量和加载因子的空的哈希映像
TreeMap:基于红黑树实现。TreeMap没有调优选项,因为该树总处于平衡状态。
(1)TreeMap():构建一个空的映像树
(2)TreeMap(Map m): 构建一个映像树,并且添加映像m中所有元素
(3)TreeMap(Comparator c): 构建一个映像树,并且使用特定的比较器对关键字进行排序
(4)TreeMap(SortedMap s): 构建一个映像树,添加映像树s中所有映射,并且使用与有序映像s相同的比较器排序
4、两种常规Map性能
HashMap:适用于在Map中插入、删除和定位元素。
Treemap:适用于按自然顺序或自定义顺序遍历键(key)。
(3)、Hashtable:键和值都不允许为null,存入元素无序,线程同步
(4)、Properties:继承于Hashtable
Properties props = System.getProperties();//系统信息
for (Map.Entry<Object, Object> entry : props.entrySet()) {
System.out.println("key= " + entry.getKey() + " || value= " + entry.getValue());
}
(5)、Collections:工具类
sort():List排序
(6)、Comparator:compare(Object o1, Object o2);Comparable:compareTo(Object o)
(7)、Collator:可用于中文排序(繁体字和多音字有问题)
(8)、pinyin4j插件解决中文排序
问题:Collection、Collections、Connection区别?
Iterator:迭代器(遍历删除元素建议用迭代器,不用集合本身)
hasNext():判断有没有下一个
next():返回迭代的下一个(迭代的时候必须调用)
remove():从迭代器指向的collection中移除迭代器返回的最后一个元素
迭代器的使用
遍历删除:
逆向迭代:ListIterator li = list. listIterator()
hasPrevious():是否有前一个元素(注:要将指针知道最后)
previous():返回前一个元素