4、集合

数组:
1、只能存储同一类型的数据(注意Object类型的数组能存储任意类型的数据)
2、初始化之后长度固定
3、数组中元素之间的内存地址连续
 
集合:存储数据对象的容器
优势:
1、可以存储任意类型对象的数据
2、集合的长度可变
 

一、单列集合

导包的时候是util包
-------| Collection  单例集合的根接口
-----------| List  子接口,实现了的类有序、可重复
-----------| Set  子接口,实现了的类无序、不可重复

1、Collection中的方法:

(1)增加
add(E e);
addAll(Collection<? extends E> c);

(2)删除

clear();
remove(Object o);
removeAll(Collection<?> c);  // 删除交集元素
retainAll(Collection<?> c);  // 保留交集元素,删除其余元素
(3)查看
size()

(4)判断

contains(Object o);   //   contains内部依赖于equals方法进行比较,调用的是实参的equals方法,一般也重写hashcode()
containsAll(Collection<?> c);
equals(Object o);
hashCode();
isEmpty();

java规范:一般重写了equals方法也需要重写hashCode方法

(5)迭代

iterator();  // 抓取集合中的元素
toArray();  // 返回集合元素组成的数组 Object[] arr = c.toArray();  Arrays.toString(arr )
Object[] arr = c.toArray();  // 从object数组中取出的元素只能使用object声明变量接收,需要其他的类型则需要强转

2、迭代器(常用,适用于各种集合的遍历

Iterator迭代器的作用:用于遍历集合中的元素
迭代器的方法:
1、hasNext():是否有元素可以遍历
2、next():取出下一个元素
3、remove():移除最后一次返回的元素
 
Iterator i = c .iterator();  // 能够用Iterator 接口接受对象,是多态,c .iterator()返回的是Iterator 接口的实现类对象,故i可以调用方法,若是返回值写死为接口实现类对象而不是接口,非常不灵活,当返回值是其实现类时无法实现

4、集合

4、集合

3、List 

特有方法特点:操作方法都具备索引值,无排序方法。
(1)添加
add(int index, E element);
addAll(int index, Collection<? extends E> c)  // 把集合添加到另一结合的末尾

(2)获取

get(int index);  // 根据索引值获取元素,可用于遍历集合的元素
indexOf(Object o);  // 指定元素第一次出现在集合中的索引值
lastIndexOf(Object o);  // 指定元素最后一次出现在集合中的索引值
subList(int fromIndex, int toIndex);  // 截取集合中的元素

(3)修改

set(int index, E element); // 替换指定索引的元素

(4)迭代

listIterator(int index);

  ListIterator特有的方法

hasPrevious();  // 是否有上一个元素
previous();  // 当前指针向上移动一个单位,再取出当前指针指向的元素;next是先取出元素,然后再移动指针
add(E e);  // 插入到当前指针指向的位置上
set(E e);  // 替代迭代器最后一次返回的元素
注意
在迭代器遍历集合的过程中(从创建到结束使用),不允许使用集合对象改变集合中元素的个数,只能用迭代器进行操作(否则ConcurrentModification异常;迭代器add元素时会加一跳过当前元素)
 

3.1、ArrayList (--> List)

ArrayList底层维护了一个Object数组,使用无参构造函数,数组默认长度是10,长度不够时, 自动增加0.5倍
特点:查询速度快(元素之间内存地址连续),增删速度慢(增加时每次检查数组长度,不够时要把旧数组复制到新数组中;删除时后面元素要往前挪)
查询多,增删少的时候用ArrayList(图书馆)
 

3.2、LinkedList (--> List)

使用链表数据结构,查询慢(元素之间内存地址不连续),增删快
特有方法(用得少)
(1)方法
addFirst(E e);
addLast(E e);  // 和add一样
getFirst();
getLast();
removeFirst();
removeLast();

(2)数据结构

1.栈(1.6):用LinkedList 实现堆栈数据结构的存储方式
push(E e);  // 插入列表开始
pop();

2.队列:用LinkedList模拟队列数据结构的存储方式

offer(E e); // 添加到队尾
poll();  // 删除队首

3.返回逆序的迭代器对象

descendingIterator();  // 逆序遍历集合

3.3、Vector (--> List)

底层维护了一个Object数组,实现与ArrayList一样,但是线程安全,操作效率低,被ArrayList取代
 
ArrayList与Vector的区别:
相同点:
          都是底层维护了一个Object数组
不同点:
          1、ArrayList线程是不同步的,操作效率高;Vector是线程同步的,操作效率低
          2、ArrayList是JDK1.2出现的额;Vector是JDK1.0出现的
 
 

4、Set

无序:添加元素的顺序和元素出来的顺序不一致,无索引出来的顺序随机
遍历只能使用迭代器iterator
 
HashSet --> Set
特点:底层使用了哈希表来支持,存取速度快
可用于存储用户名和密码
实现原理:
               往HashSet中添加元素时,会调用元素的hashCode方法得到元素的hash值,然后通过元素的哈希值(相当于内存地址)等经过移位等运算,就可以计算出元素在哈希表中的位置。
               情况一:如果算出元素存储的位置上没有元素,那么该元素直接存储;
               情况二:如果算出该元素的存储位置上已经有其他的元素了,那么就会再调用equals方法与该位置的元素再比较一次,如果equals方法返回true,那么就不允许添加(hashCode() --> equals ()
 
哈希表是桶式结构
 
HashCode默认情况下是内存地址,但String类已经重写了Object的hashCode方法了(将字符串放入字符数组,遍历字符数组通过元素算出 )
 
TreeSet --> Set
如果元素具备具备自然顺序的特性,就按元素的自然顺序的特性进行排序存储
注意事项:(1、元素所属类实现Comparable接口 和compareTo 方法;2、创建TreeSet 传入Comparator 接口的实现类作为实参
1、添加元素时,如果元素本身具备自然顺序就按自然顺序排序
2、添加元素时,不具备自然顺序,该元素的所属的类必须实现Comparable接口,把比较规则定义在compareTo方法上
3、compareTo 返回的是0则是重复元素,不允许添加
4、添加元素时,不具备自然特性且没有实现Comparable接口,那么创建TreeSet时必须传入一个Comparator比较器参数
5、元素所属的类实现了Comparable接口, 且在创建TreeSet对象的时候也传入了比较器,比较器优先
实现原理:底层是用红黑树(二叉树)的数据结构显示,左小右大,当连续三个只有一侧节点时,二叉树会自动调整节点
 
自定义比较器类:实现Comparator接口,把元素的比较方法定义在compare方法中即可
推荐使用Comparator,提高复用性
 
String实现了Comparable接口,可以排序
字符串比较规则:
     1、对应位置上有不同的字符出现,比较对应位置上的字符
     2、对应位置上都一样,比较字符串长度
 
Set无get方法,List才有,遍历TreeSet的时候要使用迭代器
 
 

 二、双列集合

----------| Map 如果实现了Map接口的集合类,具备的特点:存储的数据以键值对的形式存在,键不可重复,值可以重复
----------------| HashMap 底层依赖哈希表实现
----------------| TreeMap  底层依赖红黑树(二叉树)实现,会对键进行排序
----------------| HashTable 底层依赖哈希表实现,线程安全,操作效率低,JDK1.0
 

 1、Map接口方法

 (1)添加
put(K key, V value);  // 存在该键,就返回对应的值,不存在就返回空

(2)获取

get(Object key);
size();  // 获取集合中的键值对个数

(3)判断

containsKey(Object key);
containsValue(Object value);
isEmpty();

(4)删除

remove(Object key);  // 根据键删除map中的数据,返回该键对应的值
clear();

(5)迭代

keySet();  // 把Map集合中的所有键都保存到一个set集合对象并返回
values();  // 把所有的值存储到一个Collection集合中返回
entrySet();  // 把键值对保存到set中返回

4、集合

2.1、HashMap --> Map

存储原理:
     往HashMap中添加元素的时候,首先会调用键的hashCode方法得到元素的哈希值,然后经过运算就可以算出还元素在哈希表中的存储位置
     情况一:如果该位置上还没有元素,就可以直接添加到哈希表中
     情况二:要是有元素,会调用equals方法与这个位置上的元素进行比较,返回false允许添加,返回true不能添加
 

 2.2、TreeMap --> Map

基于红黑树(二叉树)实现,必须排序
1、添加元素时,键具备自然顺序就按自然顺序排序
2、不具备自然顺序,键所属的类必须实现Comparable接口,把键的比较规则定义在CompareTo方法上
3、不具备自然顺序,且没有实现Comparable接口,在创建TreeMap对象的时候传入比较器
4、两个元素键一样,值覆盖
 
 

三、集合工具类(Collections )

Collection和Collections的区别:
Collection是单列集合的根接口,Collections是集合工具类
 

1、Collections集合工具类常用方法:

(1)对list集合进行排序
 sort(list);  // 具备自然顺序的元素
 sort(list, comparator);  // 不具备自然顺序的元素

(2)对list进行二分查找,前提是该集合一定有序

 int binarySearch(list, key);
 int binarySearch(list, key, comparator);

(3)对集合取最大或者最小值

max(Collection);
max(Collection, comparator);

(4)对list进行反转

 reverse(list);

(5)可以将不同的集合变成同步的集合

Set synchronizedSet(Set<T> s);
Map synchornizedMap(Map<K, V> m);
List synchronizedList(List<T> list);

四、数组工具类(Arrays)

 
(1)将数组变为字符串
toString(int[]);

(2)赋值数组

copyOf();

(3)赋值部分数组

copyOfRange();

(4)比较两个数组对应位置的元素是否相同

equals(int[], int[]);

(5)将数组变为集合

List asList(T[]);

五、正则表达式

操作字符串的规则
网络爬虫
 

1、预定义字符

任何预定义字符没有加上数量词之前都只能匹配一个字符
.:任意字符(与行结束符可能匹配也可能不匹配),要匹配.字符,用\.
d:数字[0-9],
D:非数字:[^0-9]
w:单词字符:[a-z A-Z _ 0-9]
W:非单词字符:[^w]
s:空白字符:[ x 0B f ]
S:非空白字符:[^s]
 

2、数量词

X?:一次或者一次都没有
X*:零次或者多次
X+:至少出现一次
X{n}:恰好出现n此
X{n, }:至少n次
X{n, m}:至少出现,次,不超过m次
 

3、范围词

没有数量词,只能匹配一个
[abc]: a、b、c其中一个
[^abc]:任何字符,除a、b、c
[a-z A-Z]:a-z或A-Z两头都算
[a-d[m-p]]:a到d或m-p,并集
[a-z&&[def]]:d、e、f,交集
 
操作字符串的应用:
匹配:matches()
切割:spilt(),按字符内容切割,切割完的内容要放入数组中
替换:replaceAll(),要在正则的外部引用组的内容,用“$组号”
 
查找:需要使用的对象Pattern(正则对象),Matcher(匹配器对象) 
4、集合
Pattern是正则表达式的编译表示形式
匹配器使用的方法
     1、find() 通知匹配器匹配字符串,查找符合规则的子串
     2、group() 获取符合规则的子串,使用之前要用find先查找
 
正则需要复用,需要对正则进行分组,分组的目的就是提高正则的复用性,组号不能指定,从1开始
(.)\1
1:引用第一组匹配的内容
 
单词边界匹配器
单词边界器只是代表了单词的开始或者结束部分,不匹配任何字符 hello\b world
 
有事联系我  1234567@163.com 有事联系我  1234567@qq.com.cn  --> 
[a-zA-Z1-9]\w{5,17}@[a-zA-Z0-9]{2,}(\.(com|cn|net)){1,2}
 
 

 六、JDK1.5的新特性

1、静态导入

作用:简化书写
import static 包名.类名.静态的成员
import static java.util.Collections.sort;  // 简化Collections.sort()为sort())
import static java.lang.System. out;   // 简化为out

静态导入可以作用于一个类的所有静态成员

import static java.util.Collections.* // 整体导入
注意事项:
     1、静态导入的成员与本类的成员存在同名的情况下,默认使用本类的静态成员,如果指定使用静态导入的成员,需要在静态成员之前加上类名
 

2、增强for循环

作用:简化迭代器的书写格式,底层还是用迭代器(出错还是迭代器的java.util.ConcurrentModificationException)
适用范围:实现了Iterable接口的对象或是数组对象
格式:for(数据类型 变量名:遍历的目标)
注意事项:
     1、底层使用迭代器,有JVM完成,遍历元素的过程中不能操作集合对个数进行修改
     2、迭代器遍历元素时可以删除集合元素,增强for循环遍历集合元素时不能调用迭代器增删元素
     3、普通for循环可以没有遍历的目标,增强for循环一定要有遍历的目标
增强for循环不能直接遍历map(没有实现Iterable接口),要通过entrySet方式将Entry存入set之后,通过遍历set实现
4、集合
自定义类要想使用增强for循环,必须实现Iterable接口
实现hasNext和next方法,,参考ArrayList

3、可变参数(JDK1.5)

int main(数据类型... 变量名)
注意事项:
1、形参用了可变参数,调用方法时,可以传参,也可以不传
2、可变参数是一个数组
3、可变参数必须位于形参中的最后一个,一个方法只能有一个可变参数
 

4、自动装箱、拆箱

包装类型对应8种基本类型
byte       --> Byte         ----------->    1
short      --> Short       ----------->    2 
int          --> Interger   ----------->    4
long       --> Byte         ----------->    8
float       --> Float        ----------->    4
double   --> Double     ----------->    8
char       --> Character ----------->    2(可以存储一个中文汉字)
1个字节等于8位
 
好处:
 4、集合

自动装箱:自动把java基本类型数据转换成对象类型数据

Integer类内部维护了缓冲区(IntegerCache),缓冲区存储的-128~127范围的数据在数组中,如果在此范围中,直接从缓冲区中获取
Integer a1 =12;
Integer a2 = 12;
a1==a2  // true,比较地址
 

 5、枚举(JDK1.5)

某些方法接收的数据必须是在固定范围内的,解决方法之一就是自定义一个类,私有化构造函数,在自定义类中创建本类的对象
4、集合

4、集合

JDK1.5之后,它需要的数据不是任意的,必须在一定范围之内的值,可以用枚举来解决(方向、性别、星期、月份、季节......)

enum 类名 {
}

反编译: 4、集合

1、枚举值是一个特殊的类
2、默认public static final修饰
3、枚举值的数据类型是枚举值所属类的的数据类型,枚举值指向了本类的数据对象
4、枚举类的构造方法默认是private的
5、枚举类能自定义自己的成员变量和成员方法
6、枚举类可以自定义构造函数,但是构造函数的修饰符必须是private,要是有参的构造函数,必须在开始传入参数4、集合

4、集合

8、枚举值必须放在最第一句

4、集合

switch适用的数据类型
byte/char/short/int/string/枚举
case之后跟的枚举值只需要枚举值,不需要枚举值是哪个枚举类的(在switch条件中已经确定了枚举类型,case中防止乱传别的枚举值)

 4、集合