Java核心类库学习笔记上:
一、包装类
(1)包装类的概念
通常情况下基本数据类型的变量不是对象,为了满足对象的理念就需要对基本数据类型的变
量进行打包封装处理变成对象,而负责将这些变量声明为成员变量进行对象化处理的相关类,叫做包装类。
如:
Animal p = new Animal ();
int num = 10;
p是对象,num从语法层面上看不是对象,如果要把num变成对象应该打包到一个类中:
public class ObjectInt{
private int num = 10;
}
java官方提供的八个包装类:
1 、integer类内部实际上就是被int类型包装,所谓得包装就是拿int类型的变量作为这个类得成员变量,只要new这个类的变量都会得到这个类的成员变量,这样就相当于包装。
2、intValue这个方法没有static修饰,需要引用点调用该方法,这个方法得到的是一个int类型的数字,所有需要使用int类型保存该数据,当然如果使用字符串与之拼接得到的数据是string类型
(2)装箱和拆箱的概念
装箱:可以实现从int类型到integer类型的转换,integer类实际上是int类的包装类,我们把这种从int类型到integer类型的转换过程,我们把他叫做装箱。什么叫做装箱?装箱的概念就是把箱子。我要想把int类型变成integer类型实际上就需要把箱子打开,integer打开把int类变成integer类的成员变量,这样相当于打包好了,实际上这个过程就叫做装箱。
拆箱:所有把integer打开,把里面的数据拿出来这个过程叫做拆箱。
(3)自动装箱池
自动装箱池:就是java把该装的数据装在一个水池中,所以调用这个自动装箱池的数据地址是一样的,我们使用装箱池中的数据在范围内比较自然就是true。
二、String简介
1.1、String(字符串常量)概述
String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。
1.2 常用方法
boolean equals(Object obj):比较字符串的内容是否相同
boolean equalsIgnoreCase(String str): 比较字符串的内容是否相同,忽略大小写
boolean startsWith(String str): 判断字符串对象是否以指定的str开头
boolean endsWith(String str): 判断字符串对象是否以指定的str结尾
因为字符串在实际开发时使用太多频繁,为了执行效率,把字符串放到方法区的字符串常量池中
1.3 不可变的好处
因为String太过常用,JAVA类库的设计者在实现时做了个小小的变化,即采用了享元模式,每当生成一个新内容的字符串时,他们都被添加到一个共享池中,当第二次再次生成同样内容的字符串实例时,就共享此对象,而不是创建一个新对象,但是这样的做法仅仅适合于通过=符号进行的初始化。 需要说明一点的是,在object中,equals()是用来比较内存地址的,但是String重写了equals()方法,用来比较内容的,即使是不同地址,只要内容一致,也会返回true,这也就是为什么a.equals©返回true的原因了。
可以实现多个变量引用堆内存中的同一个字符串实例,避免创建的开销。
我们的程序中大量使用了String字符串,有可能是出于安全性考虑。
大家都知道HashMap中key为String类型,如果可变将变的多么可怕。
当我们在传参的时候,使用不可变类不需要去考虑谁可能会修改其内部的值,如果使用可变类的话,可能需要每次记得重新拷贝出里面的值,性能会有一定的损失
三、正则表达式
正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。
常用正则表达式元字符
元字符 描述
\ 将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配\n。“\n”匹配换行符。序列“\”匹配“\”而“(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。
^ 匹配输入字行首。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入行尾。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
- 匹配前面的子表达式任意次。例如,zo*能匹配“z”,也能匹配“zo”以及“zoo”。*等价于{0,}。
- 匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。
(?:pattern) 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern) 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
(?<=pattern) 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。*python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等
(?<!pattern) 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。*python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等
x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”(此处请谨慎)。“[z|f]ood”则匹配“zood”或“food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”任一字符。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身.
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\b 匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”;“\b1_”可以匹配“1_23”中的“1_”,但不能匹配“21_3”中的“1_”。
\B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
\d 匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持
\D 匹配一个非数字字符。等价于[^0-9]。grep要加上-P,perl正则支持
\f 匹配一个换页符。等价于\x0c和\cL。
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
四、集合类库
Java的集合类库很是丰富,囊括了大部分的常见数据结构形式,让我们可以有目的性的选择适合当前业务场景和功能场景的集合类。合适的集合框架可以最大程度的提升执行速度和效率。
Java集合类库中所有的集合类都始于Collection接口和Map接口,前者表示单值集合,后者表示映射集合(双值集合)。
Java集合框架中的Abstract开头的抽象类,其实是JDK开发者定义出来用于实现具体集合类的,是面向JDK开发人员的,而不是面向JDK的使用人员。在这些抽象类中一般会将同一类型的集合的一些公共的方法进行实现,避免在具体的集合类中重复的实现,比如contains方法。
-
Iterable接口
这是一个简单的接口,实现了该接口的类都可以使用foreach循环迭代,其实foreach底层原理还是Iterator迭代器循环。从上面的接口可以看出,只有单值集合可以使用这种迭代方式。 -
Collection接口
Collection接口是单值集合的根接口,其中为这一类型的集合提供了基本的方法定义:
这里列出了Collection接口中定义的所有方法,共有15个:
第一个方法:size()方法用于返回当前集合中元素的数量
第二个方法:isEmpty()用于验证集合中是否包含元素,若包含元素则返回false,若不包含元素则返回true
第三种方法:contains(Object o)验证集合中是否包含指定的元素,若包含则返回true,否则返回false
第四个方法:iterator()用于返回基于当前集合的迭代器Iterator
第五个方法:toArray()用于获取包含当前集合中所有元素的数组,如果集合指定的顺序,那么数组的元素将按照这种顺序排列,并且这个数组将不再与集合有任何的联系,任何针对数组的修改都不会影响到集合。
第六个方法:toArray(T[] a)用于获取包含当前集合中所有元素的数组,与上面的方法不同之处在于,此方法给定一个数组用于存放集合中的元素,若数组足够大能放得下所有的集合元素,则将数组剩余的位置置null,若数组位数不足以保存所有的集合元素,则重新创建一个数组(这个数组与给定的数组的类型一致)来存放集合元素,第二种情况与上面的第五个方法情况相同。由于此方法给定了一个数组用来存放集合元素,因此效率比上面的略高。
第七个方法:add(E e)用于在集合中添加新的元素,如果集合不允许重复元素且已存在该元素,则返回false,如果集合结构发生了变化则返回true(表示添加到集合中了)
第八个方法:remove(Object o)用于移除集合中的某个元素,集合中删除元素会带来集合结构的部分变动。如果集合中包含该元素则返回true
第九个方法:containsAll(Collection<?> c)验证当前集合中是否包含给定集合中的所有元素,如果包含则返回true,否则返回false
第十个方法:addAll(Collection<? extends E> c)用于将指定集合中的所有元素全部添加到当前集合中去,如果指定集合在添加过程中发生的变化则结果将变得不确定。
第十一个方法:removeAll(Collection<?> c)用于移除当前集合中包含的指定集合中的所有元素,如果当前集合发生的改变则返回true
第十二个方法:retainAll(Collection<?> c)用于保留当前集合中同样在指定集合中存在的元素,移除所有不包含在指定集合中的元素,若集合发生的变化则返回true
第十三个方法:clear()用于移除当前集合中的所有元素,之后元素为empty
第十四个方法:equals(Object o)用于比较两个集合对象是否相同
第十五个方法:hashCode()用于返回当前集合对象的hash值
-
List接口
List是一种有序集,又称序列。拥有下标,允许重复的值。 -
Set接口
查看源码可知Set接口与Collection接口中定义的方法完全一致,Set集合表示的是无序的集合,其中不能有重复的元素。
5.Queue接口
Queue是队列接口,用于保存即将进行处理的元素,除了基本的Collection定义的方法之外,队列还提供了其他的插入、提取和移除操作。每个方法都存在两种形式:一种抛出异常(操作出错时),一种返回一个特殊值(null或者false),后面的这种操作是专门为拥有容量限制的Queue为设计的。
6. Map接口
Map是一种键值对集合,用于一对一的键值存储,键不能重复,值可以重复,一个键最多只能找到一个值。
Map拥有三种集合视图:键集合(Set),值集合(Collection)、键值映射集合(Set)。
Map集合的顺序被定义为其值集(Collection)的迭代器返回的顺序。
Map集合的键一般使用不可变值,但是值可以使用易变值。因为可变的key可能会影响equals比较。
所有的Map集合的实现类都应该提供两个构造器:一个是无参构造器用于创建一个空的Map集合,一个是带Map集合参数的构造器,用于创建一个与给定集合一一对应的新的Map集合。
五、泛型的定义以及存在意义
泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
使用泛型的意义在于
1.适用于多种数据类型执行相同的代码(代码复用)
2. 泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)。
六、使用难点:
Map遍历
第一种遍历map的方式是通过map.keySet()的方式遍历的,这种方式主要是获取key,然后根据key获取value的值
第二种方法是基于迭代器的方式遍历的,使用map.entrySet()方法牟其中可以直接遍历到entry的key和value的值
第三种方式是直接使用Map.entrySet()遍历出key和value,这种遍历是性能较高的方法,针对map值较大的时候都有很不错的效率
数组长度改变遍历
用迭代器遍历并且判断长度
sort方法使用
实现comprable 接口