集合框架:★★★★★,用于存储数据的容器。
特点:
1:对象封装数据,对象多了也需要存储。集合用于存储对象。
2:对象的个数确定可以使用数组,但是不确定怎么办?可以用集合。因为集合是变长度的。
集合和数组的区别:
1:数组是固定长度的;集合可变长度的。
2:数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。
3:数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。
数据结构:就是容器中存储数据的方式。
对于集合容器,有很多种。因为每一个容器的自身特点不同,其实原理在于每个容器的内部数据结构不同。
集合容器在不断向上抽取过程中。出现了集合体系。
在使用一个体系时,原则:参阅顶层内容。建立底层对象。
Collection :单列集合的根接口,Collection 表示一组对象,这些对象也称为 collection 的元素。
List: 实现List接口的类会实现List中的所有方法。
特点: 有序的,元素可以重复。
ArrayList: 原理: 内部维护了一个Object类型的数组,默认数组大小为10.
特点: 查找比较快,增加和删除比较慢。
LinkedList:原理:采用链接列表的形式来存储数据的。
特点:查找比较慢,增加元素比较快 。
Set::实现Set接口的类会实现Set中所有方法。
特点: 无序的,元素是不可重复的。
LinkedList的特有方法:
1.常用的方法:
addFirst(E e)
addLast(E e)
descendingIterator()
element() // 获取第一个元素但是不删除
E getFirst() //获取第一个元素
getLast() // 获取最后一个元素
removeFirst() 移除并返回此列表的第一个元素。
booleanremoveFirstOccurrence(Object o) 从此列表中移除第一次出现的指定元素(从头部到尾部遍历列表时)。
E removeLast() 移除并返回此列表的最后一个元素。
booleanremoveLastOccurrence(Object o)
2.数据结构的方法:
1.栈数据结构 先进后出
push(E e) : 可以用来描述栈结构数据的存储方式。
pop()
2.队列的数据结构 先进先出
boolean offer(E e) : 可以用来描述队列结构数据的存储方式
poll()
迭代器:
descendingIterator() : 逆序打印集合中的元素
1.创建迭代器:
Iterator i =linkedList.descendingIterator();
while(i.hasNext()){
System.out.println(i.next());
}
Vector : 线程安全的ArrayList
共同点: 原理和ArrayList是一样的。
不同点:
ArrayList是线程不安全的,效率高 // jdk1.2的时候才有。
Vector 线程安全的, 效率比较低。 --->一般不会在使用了。 jdk1.0就出现了
Set: 实现接口的类会实现Set中的所有方法。
特点: 无序的,元素不可重复。
HashSet: 通过哈希值来存取数据,存取过程比较快,底层是以哈希表来存值的。 线程是不安全的。
Set集合的特有方法: 方法和Collection中一样的。
HashSet存值的原理:
会通过存放的对象调用hashCode方法,获取到一个值,通过移位运算获取到对应的地址值,存放到哈希表中。
情况1:
如果存放的位置不存在其他对象,直接将对象存放到该位置。
情况2:
如果存放的位置有了其他的对象,他会再次调用这个对象的equals方法做比较,如果返回的值是false,将这个对象直接存放到该位置,如果是true就不再存放。
无序: 指添加元素的顺序和元素在集合中存放的顺序不一定相等。
TreeSet:也是实现Set接口。
实现原理: 采用红黑树(二叉树)结构来存储数据。
特点: 如果存入的对象有自然排序的特点,那么集合中的元素会根据自然排序的规律来对象集合中的元素进行排序。
TreeSet是通过Comparator 来做比较的 调用对象的Comparator来比较的。
Comparator接口可以比较的对象类型。
①、Comparator位于包java.util下,而Comparable位于包java.lang下。
②、Comparable接口将比较代码嵌入需要进行比较的类的自身代码中,而Comparator接口在一个独立的类中实现比较。
③、如果前期类的设计没有考虑到类的Compare问题而没有实现Comparable接口,后期可以通过Comparator接口来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:升序、降序。
④、Comparable接口强制进行自然排序,而Comparator接口不强制进行自然排序,可以指定排序顺序。
TreeSet是可以对字符串进行排序的, 因为字符串已经实现了Comparable接口。
字符串的比较规则:
情况一: 对应位置有不同的字符出现, 就比较的就是对应位置不同的字符。
情况 二:对应位置上 的字符都一样,比较的就是字符串的长度。
TreeSet集合的使用注意点:
1.如果存入的对象有自然排序的特点,那么集合中的元素会根据自然排序的规律来对象集合中的元素进行排序。
2.如果没有自然排序的特点就直接报错。
3.如果元素没有自然排序特点,需要让元素所属的类来实现Comparable 接口 ,实现compareTo的方法,然后通过这个方法来做比较。
4.如果元素没有自然排序特点,也没有实现Comparable接口,需要在创建集合的时候给他指定一个比较器,集合就会根据指定比较器进行排序。
接口 Comparator<T>
类型参数:
T - 此 Comparator 可以比较的对象类型
public interface Comparator<T>
强行对某个对象 collection 进行整体排序的比较函数。可以将 Comparator 传递给 sort 方法(如Collections.sort 或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
public interface Comparable<T>
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
int compareTo(T o)
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
参数:
o - 要比较的对象。
返回:
负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
定义一个比较器的方式:就是定义一个类实现Comparator接口 提供一个compare(Objecto1, Object o2)方法作比较
equals
boolean equals(Object obj) 指示某个其他对象是否“等于”此 Comparator。此方法必须遵守 Object.equals(Object) 的常规协定。此外,仅当 指定的对象也是一个 Comparator,并且强行实施与此 Comparator 相同的排序时,此方法才返回true。因此,comp1.equals(comp2) 意味着对于每个对象引用o1 和o2 而言,都存在sgn(comp1.compare(o1, o2))==sgn(comp2.compare(o1,o2))。 注意,不 重写 Object.equals(Object) 方法总是 安全的。然而,在某些情况下,重写此方法可以允许程序确定两个不同的 Comparator 是否强行实施了相同的排序,从而提高性能。 覆盖: 类 Object 中的equals 参数: obj - 要进行比较的引用对象。 返回: 仅当指定的对象也是一个Comparator,并且强行实施与此 Comparator 相同的排序时才返回 true。
表示一个方法声明打算重写超类中的另一个方法声明。 |
toString
public String toString() 返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。 Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于: getClass().getName() + '@' + Integer.toHexString(hashCode()) 返回: 该对象的字符串表示形式。 java.lang 提供利用 Java 编程语言进行程序设计的基础类。 java.text 提供以与自然语言无关的方式来处理文本、日期、数字和消息的类和接口。 java.util 包含 collection 框架、遗留的 collection 类、事件模型、日期和时间设施、国际化和各种实用工具类(字符串标记生成器、随机数生成器和位数组)。 java.util.concurrent 在并发编程中很常用的实用工具类。
泛型:泛型是jdk1.5出现的新特性。
泛型的定义:是和方法或者类和接口一起使用的,没办法直接定义一个泛型。
定义的泛型是写在类上的 : 泛型是在创建对象的时候被确定。
格式:
<泛型的名称>
泛型的好处:
1. 将运行时出现 的问题提前至了编译时。
2. 避免了无谓强制类型转换。
泛型在集合中的好处:
获取返回的对象不需要强转。
类上定义泛型: 特点: 如果类中的方法使用的都是类上定义的泛型,那么一旦创建对象的时候指定了数据类型,方法中的泛型就都是该类型了。
注意点:
1.如果一个类上自定义了泛型,类中的方法是可以重新定义泛型
2.类上定义的泛型只能作用于非静态方法。
什么时候使用在类上定义泛型:
如果一个类中有多个方法需要使用到泛型,那么这个时候就可以考虑在类上定义泛型。
泛型的使用注意事项:
1.如果一个对象在创建时指定了泛型的类型,那么这个对象中只能存放该类型的值。
2.泛型指定的类型只能是引用数据类型 。
如果是基本数据类型,这个泛型中应该指定他的包装类型。int --> Integer
3. 左右两边的数据类型不允许不一致。
4.如果没有指定类型默认是Object类型
自定义泛型: 自定义泛型就是一个数据类型的占位符或者理解为一个数据类型的变量。
泛型方法:
修饰符 <声明自定义的泛型>返回值类型 函数名(自定义的泛型 变量名..)
泛型方法
一个基本的原则是:无论何时,只要你能做到,你就应该尽量使用泛型方法。也就是说,如果使用泛型方法可以取代将整个类泛化,那么应该有限采用泛型方法。下面来看一个简单的泛型方法的定义:
publicclassMain{
publicstatic <T> voidout(T t){
System.out.println(t);
}
publicstaticvoidmain(String[] args){
out("findingsea");
out(123);
out(11.11);
out(true);
}
}
可以看到方法的参数彻底泛化了,这个过程涉及到编译器的类型推导和自动打包,也就说原来需要我们自己对类型进行的判断和处理,现在编译器帮我们做了。这样在定义方法的时候不必考虑以后到底需要处理哪些类型的参数,大大增加了编程的灵活性。
再看一个泛型方法和可变参数的例子:
publicclassMain{
publicstatic <T> voidout(T... args){
for (T t : args) {
System.out.println(t);
}
}
publicstaticvoidmain(String[] args){
out("findingsea", 123, 11.11, true);
}
}
输出和前一段代码相同,可以看到泛型可以和可变参数非常完美的结合。
泛型方法要注意的事项:
1. 泛型方法中 的自定义泛型的具体数据类型是在调用该函数的时候传入实参时确定的。
2. 自定义泛型所用的标识符只要符合标识符 的命名规则即可。但是我们一般都习惯使用一个大写字母表示。
泛型类:
泛型类的定义格式
class 类名<声明自定义的泛型>{
}
泛型类要注意的事项:
1. 泛型类上的自定义泛型是在使用该类创建对象的时候指定具体的数据类型的。
2. 如果一个类已经自定义了泛型,使用该类创建对象的时候如果没有指定泛型的具体数据类型,那么默认为Object类型。
3. 静态的函数不能使用类上自定义的泛型,如果静态函数需要使用,必须要在函数上自定义泛型。
泛型接口:
泛型接口的定义格式:
interface 接口名<声明自定义的泛型>{
}
publicinterfaceGenerator<T> {
public Tnext();
}
然后定义一个生成器类来实现这个接口:
publicclassFruitGeneratorimplementsGenerator<String> {
privateString[] fruits =newString[]{"Apple","Banana","Pear"};
@Override
publicStringnext() {
Random rand = newRandom();
return fruits[rand.nextInt(3)];
}
}
调用:
publicclassMain {
publicstaticvoidmain(String[]args) {
FruitGenerator generator = newFruitGenerator();
System.out.println(generator.next());
System.out.println(generator.next());
System.out.println(generator.next());
System.out.println(generator.next());
}
}
泛型接口要注意事项:
1. 泛型接口上的自定义泛型是在实现该接口的时候指定具体数据类型的。
缺点: 类型就固定了
2. 如果实现接口的时候没有指定接口上 的自定义泛型的具体数据类型,那么默认为Object数据类型。
3. 如果需要在创建接口实现类对象的时候才指定接口上自定义泛型,那么需要以下格式: class<T> 类名 implements 接口<T>
泛型上下限:泛型的范围,只要应用于方法中。
泛型的下限 ? superInteger 允许是Integer数据类型或者是Integer父类类型
?表示泛型中的通配符
泛型的上限。? extedns Number 允许是Number数据类型或者是Number子类的数据类型
Map: 双列集合的根接口
----------------| HashMap
----------------| TreeMap
----------------| Hashtable
双列集合:
-------------| Map 如果是实现了Map接口的集合类,具备的特点:存储的数据都是以键值对的形式存在的,键不可重复,值可以重复。
----------------| HashMap 底层也是基于哈希表实现的。
HashMap的存储原理:
往HashMap添加元素的时候,首先会调用键的hashCode方法得到元素的哈希码值,然后经过运算就可以算出该元素在哈希表中的存储位置。
情况1: 如果算出的位置目前没有任何元素存储,那么该元素可以直接添加到哈希表中。
情况2:如果算出的位置目前已经存在其他的元素,那么还会调用该元素的equals方法与这个位置上的元素进行比较,
如果equals方法返回的是false,那么该元素允许被存储,如果equals方法返回的是true,那么该元素被视为重复元素,不允存储。
----------------| TreeMap TreeMap也是基于红黑树(二叉树)数据结构实现的, 特点:会对元素的键进行排序存储。
TreeMap 要注意的事项:
1. 往TreeMap添加元素的时候,如果元素的键具备自然顺序,那么就会按照键的自然顺序特性进行排序存储。
2. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性,那么键所属的类必须要实现Comparable接口,把键的比较规则定义在CompareTo方法上。
3. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性,而且键所属的类也没有实现Comparable接口,那么就必须在创建TreeMap对象的时候传入比较器。
在现实生活中有些数据是以映射关系存在的,也就是成对存在的,比如:
民政局 :
键 值
老公 老婆
身份证 人
一把要锁 锁
Map接口的方法:
添加:
put(K key, V value) 给指定的键添加值 : 若果没有指定的键,就会创建一个键对应指定的值,如果键存在就是修改键所对应的值。
putAll(Map<?extends K,? extends V> m)
删除
remove(Object key) // 通过指定的键来删除元素。
clear()
获取(取值):
get(Object key) // 通过指定的键来获取值
size()
判断(查看):
containsKey(Object key) // 查找有没有指定的键
containsValue(Object value) //查找是否有指定的值
isEmpty()
迭代方法:
keySet() //获取集合中所有的键
values() //获取所有的值
entrySet()
map集合的遍历方式: entrySet方法遍历。
Set<Map.Entry<String,String>> entrys = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrys.iterator();
while(it.hasNext()){
Map.Entry<String,String>entry = it.next();
System.out.println("键:"+ entry.getKey()+" 值:"+entry.getValue());
}
标识符的命名规范:
1. 只能由英文字母(大小写)a-z,A-Z,数字(0-9),下划线(_)美元符号($)
2. 首字母不能够出现数字
3. 标识符严格区分大小写 a A
4. 标识符没有长度的限制。
5. 标识符命名一般要有意义。
6.数字不可以开头。
7.不可以使用关键字。
----------------| HashMap
----------------| TreeMap
----------------| Hashtable
双列集合:
-------------| Map 如果是实现了Map接口的集合类,具备的特点:存储的数据都是以键值对的形式存在的,键不可重复,值可以重复。
----------------| HashMap 底层也是基于哈希表实现的。
HashMap的存储原理:
往HashMap添加元素的时候,首先会调用键的hashCode方法得到元素的哈希码值,然后经过运算就可以算出该元素在哈希表中的存储位置。
情况1: 如果算出的位置目前没有任何元素存储,那么该元素可以直接添加到哈希表中。
情况2:如果算出的位置目前已经存在其他的元素,那么还会调用该元素的equals方法与这个位置上的元素进行比较,
如果equals方法返回的是false,那么该元素允许被存储,如果equals方法返回的是true,那么该元素被视为重复元素,不允存储。
----------------| TreeMap TreeMap也是基于红黑树(二叉树)数据结构实现的, 特点:会对元素的键进行排序存储。
TreeMap 要注意的事项:
1. 往TreeMap添加元素的时候,如果元素的键具备自然顺序,那么就会按照键的自然顺序特性进行排序存储。
2. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性,那么键所属的类必须要实现Comparable接口,把键的比较规则定义在CompareTo方法上。
3. 往TreeMap添加元素的时候,如果元素的键不具备自然顺序特性,而且键所属的类也没有实现Comparable接口,那么就必须在创建TreeMap对象的时候传入比较器。
在现实生活中有些数据是以映射关系存在的,也就是成对存在的,比如:
民政局 :
键 值
老公 老婆
身份证 人
一把要锁 锁
Map接口的方法:
添加:
put(K key, V value) 给指定的键添加值 : 若果没有指定的键,就会创建一个键对应指定的值,如果键存在就是修改键所对应的值。
putAll(Map<?extends K,? extends V> m)
删除
remove(Object key) // 通过指定的键来删除元素。
clear()
获取(取值):
get(Object key) // 通过指定的键来获取值
size()
判断(查看):
containsKey(Object key) // 查找有没有指定的键
containsValue(Object value) //查找是否有指定的值
isEmpty()
迭代方法:
keySet() //获取集合中所有的键
values() //获取所有的值
entrySet()
map集合的遍历方式: entrySet方法遍历。
Set<Map.Entry<String,String>> entrys = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrys.iterator();
while(it.hasNext()){
Map.Entry<String,String>entry = it.next();
System.out.println("键:"+ entry.getKey()+" 值:"+entry.getValue());
}
标识符的命名规范:
1. 只能由英文字母(大小写)a-z,A-Z,数字(0-9),下划线(_)美元符号($)
2. 首字母不能够出现数字
3. 标识符严格区分大小写 a A
4. 标识符没有长度的限制。
5. 标识符命名一般要有意义。
6.数字不可以开头。
7.不可以使用关键字。
eclipse中常用的快捷键
Alt + / 提示
Ctrl + / 单行注释 / 取消
Ctrl + Shift + / 多行注释
Ctrl + Shift + \ 取消多行注释
Ctrl + 1 快速修复
Ctrl + Shift + o 导包
Alt+上下键 代码位置调换
删除:
1.Ctrl+ D 删除当前行
重置透视图:window->reset perspective
当eclipse 的Java视图变的很乱的时候,就可以重置透视图,还原为最初的界面。
大小写转换
更改为大写 Ctrl+Shift+X
更改为小写 Ctrl+Shift+Y
复制行
Ctrl+Alt+向下键
查看源代码
1、Ctrl+单击 需要查看源码的类
2、Ctrl+Shift+T
断点调试
1.给你需要调试的代码打一个断点
2.需要使用debug 来调试
3.
step into 进代码的实现
step over 跳到下一行代码
step return 返回到原来的位置
断点调试的作用: 1.帮你查找错误 2.梳理代码的逻辑。
jdk5的新特性:
泛型是jdk1.5之后才有的。
包装类型jdk1.5的新特性
静态导包 :
作用:可以省略类名来调用静态方法。
格式 : importstatic 包名+类名.方法名
注意: 静态导入的一定是类中的静态方法
import staticjava.util.Arrays.sort;
toString静态导入无效
import staticjava.util.Arrays.toString;
import static java.util.Arrays.*;
增强for循环:
除了可以遍历数组,还可以用来遍历集合。
增强for循环使用的条件: 增强for循环只能用在数组、或实现Iterable接口的集合类上。
枚举类型的使用:
调用方法的时候有些参数不是传递任意的值,而是传递的是某个范围的值。
枚举类型的定义格式:
通过关键字enum 来定义
枚举类型是一个比较特殊的类。不能直接new对象
每一个枚举值就表示一个实例对象
enum 枚举的名字 {
枚举值命名: 只能以字母,下划线或美元符号开头 一般情况枚举值是大写
每一个枚举值之间以逗号隔开
}
enum Weather{
SUN,CLOUDY,RAIN,SNOW;
}
枚举值的使用注意事项:
1.定义的每一个枚举值指的是一个实例对象
2.枚举值是可以定义属性和方法
3.它是不能直接new一个对象出来的,只能通过枚举值来表示对象
4.如果存在抽象方法就必须要实现抽象方法。
正则表达式:
正则表达式 - 语法
正则表达式(regular expression)描述了一种字符串匹配的模式,可以用来检查一个串是否含有某种子串、将匹配的子串做替换或者从某个串中取出符合某个条件的子串等。
· 列出目录时,dir *.txt或ls *.txt中的*.txt就不是一个正则表达式,因为这里 *与正则式的 *的含义是不同的。
· 构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
主要就是学习特殊符号的使用。
booleanmatches(String regex) :判断字符串是否符合指定的规则
regex : 指定的规则
预定义字符类
. 任何字符(与行结束符可能匹配也可能不匹配)
\d 数字:[0-9]
\D 非数字: [^0-9]
\s 空白字符:[ \t\n\x0B\f\r]
\S 非空白字符:[^\s]
\w 单词字符:[a-zA-Z_0-9]
\W 非单词字符:[^\w]
System.out.println("1".matches("."));//true
注意:预定义字符如果没有使用数量词的化表示的都是一个字符。
数量词
X? X,一次或一次也没有
X* X,零次或多次
X+ X,一次或多次
X{n} X,恰好 n 次
X{n,} X,至少 n 次
X{n,m} X,至少 n 次,但是不超过 m 次
System.out.println("1".matches("\\d+"));// 至少一次
System.out.println("123".matches("\\d{3}"));//字符串的长度恰好为3
System.out.println("1234".matches("\\d{3,}")); // 字符串的长度至少为3
System.out.println("12345".matches("\\d{3,5}")); //字符串的长度大于等于3 小于等于5
字符的长度在3-4之间并且只能以1开头, 5结尾"1\\d\\d?5";
取出某个字符串中以a来头的单词 a[a-z]*;
范围词:
[abc]a、b 或 c(简单类)
[^abc] 任何字符,除了 a、b 或 c(否定)
[a-zA-Z] a 到 z 或 A 到 Z,两头的字母包括在内(范围)
a 到 d 或 m 到 p:[a-dm-p](并集)
[a-z&&[def]] d、e 或 f(交集) [def]
[a-z&&[^bc]] a 到 z,除了 b 和 c:[ad-z](减去)
[a-z&&[^m-p]] a 到 z,而非 m 到 p:[a-lq-z](减去)
System.out.println("a".matches("[a-zA-Z]"));//a-z
注意: 如果没有数量词也是指的一个字符
正则表达式的应用:
1.匹配功能:
1.写一个手机号的匹配: 以1开头 第二位3,5,8,7,4 后面主要是数字 长度是11位
public class Demo11 {
public static void main(String[] args) {
1.写一个手机号的匹配: 以1开头 第二位3,5,8,7,4 后面主要是数字
长度是11位
String reg ="1[34578]\\d{9}";
System.out.println("13845496223".matches(reg));
}
}
2.切割功能:split()
//根据空格将字符串分割为一个数组
1. 明 天 要 出 去 玩
3.替换功能
替换功能 replaceFirst(String regex, String replacement)
String s = "如果有需求请联系我:13458353456如果有需求请联系我:13458353456";
//想将电话号码替换成:********
4.查找
查找功能 :Pattern 这个类来实现查找功能
正则表达式的编译表示形式。
指定为字符串的正则表达式必须首先被编译为此类的实例。然后,可将得到的模式用于创建 Matcher 对象,依照正则表达式,该对象可以与任意字符序列匹配。执行匹配所涉及的所有状态都驻留在匹配器中,所以多个匹配器可以共享同一模式。
因此,典型的调用顺序是
Pattern p = Pattern.compile("a*b");
Matcher m = p.matcher("aaaaab");
boolean b = m.matches();
Matcher中有两个方法:
find(); 返回一个boolean类型的值 如果判断的值符合表达是返回true
不符合就返回false
group(); 返回符合要求的字符串
网络爬虫来获取邮箱号:
public static void getEmali(){
Strings = "如果有需求请联系我:141374@qq.com如果有需求请联系我:141374@qq.com如果有需求请联系我:141374@qq.com如果有需求请联系我:13458353456如果有需求请联系我:如果有需求请联系我:141374@qq.com";
Pattern p =Pattern.compile("[1-9a-zA-Z_]\\w{4,17}@\\w{2,}(\\.(com|cn|net)){1,2}");
Matcherm = p.matcher(s);
while(m.find()){
System.out.println(m.group());
}
}
3常用正则表达式
规则
正则表达式语法
一个或多个汉字
^[\u0391-\uFFE5]+$
邮政编码
^[1-9]\d{5}$
QQ号码
^[1-9]\d{4,10}$
邮箱
^[a-zA-Z_]{1,}[0-9]{0,}@(([a-zA-z0-9]-*){1,}\.){1,3}[a-zA-z\-]{1,}$
用户名(字母开头 + 数字/字母/下划线)
^[A-Za-z][A-Za-z1-9_-]+$
手机号码
^1[3|4|5|8][0-9]\d{8}$
URL
^((http|https)://)?([\w-]+\.)+[\w-]+(/[\w-./?%&=]*)?$
18位身份证号
^(\d{6})(18|19|20)?(\d{2})([01]\d)([0123]\d)(\d{3})(\d|X|x)?$