DAY11
一、正则表达式:
案例展示
package cn.edu360;
import java.util.Scanner;
public class ClassDemo {
public static void main(String[] args) throws Exception {
/*
* 校验QQ号码:
* 1:要求必须是5~15的数字
* 2:不能以数字0开头
*/
Scanner sc = new Scanner(System.in);
System.out.println("请输入QQ号码:");
String qq = sc.nextLine();
//调用一个方法专门来校验QQ的合法
boolean result = CheckQQ(qq);
System.out.println(result);
}
private static boolean CheckQQ(String qq) {
if(!qq.startsWith("0")){
if(qq.length() >= 5 && qq.length() <= 15){
for (int i = 0; i < qq.length(); i++) {
char c = qq.charAt(i);
if(!Character.isDigit(c)){
return false;
}
}
return true;
}
}
return false;
}
}
正则表达式:
是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。其实就是一种规则,有自己特殊的应用
- 判断功能
public boolean matches(String regex)
告知此字符串是否匹配给定的正则表达式 - 分割功能
public String[] split(String regex)
根据给定的正则表达式的匹配拆分此字符串
注意:常用的正则表达式可以查阅百度(最常用的15个前端表单验证JS正则表达式)
二、集合
1、Collection
Collection接口是集合层次的根接口,因为Collection是一个接口,所以里面的方法无法直接使用,所以需要找它的实现类,咱们就以ArrayList这个实现类为例来演示一下Collection里面的方法 - boolean add(E e)
将指定的元素添加到此列表的尾部,添加成功返回true - boolean remove(Object o)
移除此列表中首次出现的指定元素,移除成功返回true - void clear()
清空集合 - boolean contains(Object o)
判断参数对象在此集合中是否存在 - int size()
返回集合中的元素个数
代码实现:
package cn.edu360;
import java.util.ArrayList;
import java.util.Collection;
public class ClassDemo {
public static void main(String[] args) throws Exception {
Collection c = new ArrayList();
c.add("javaee");
c.add("javase");
c.add("hadoop");
System.out.println(c);//[javaee, javase, hadoop]
c.remove("hadoop");
System.out.println(c);//[javaee, javase]
//c.clear();
System.out.println(c);//[]
System.out.println(c.contains("javase"));//true
System.out.println(c.size());//2
}
}
- 第一种遍历方式
是将集合转换成数组,然后对数组进行遍历
Object[] toArray()返回包含此collection中所有元素的数组
代码实现:
package cn.edu360;
import java.util.ArrayList;
import java.util.Collection;
public class ClassDemo {
public static void main(String[] args) throws Exception {
Collection c = new ArrayList();
c.add("javaee");
c.add("javase");
c.add("hadoop");
c.add(123);
Object[] array = c.toArray();
for (int i = 0; i < array.length; i++) {
Object val = array[i];
if(val.equals("hadoop")){
c.remove(val);
continue;
}
System.out.println(val);
}
System.out.println(c);//[javaee, javase, 123]
}
}
- 第二种遍历方式
通过Iterator迭代器进行迭代遍历 - Iterator iterator()返回在此collection的元素上进行迭代的迭代器
- boolean hasNext()如果仍有元素可以迭代,则返回true
- E next()返回迭代的下一个元素
注意事项:在使用迭代器进行遍历的时候,如果直接使用集合的引用修改元素,会报并发的修改异常,如果一定要修改元素的话,只能迭代器修改 - void remove()删除当前迭代的元素
代码实现:
package cn.edu360;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class ClassDemo {
public static void main(String[] args) throws Exception {
Collection c = new ArrayList();
c.add("javaee");
c.add("javase");
c.add("hadoop");
c.add(123);
Iterator iterator = c.iterator();
while(iterator.hasNext()){
Object val = iterator.next();
if(val.equals("javase")){
//c.remove(val);//报错为:java.util.ConcurrentModificationException
iterator.remove();
continue;
}
System.out.println(val);
}
}
}
- List集合它可以根据索引的位置插入数据和取出数据
- List集合它的元素可以重复,并且存入的顺序和取出的顺序保持一致
- Set集合它的元素都是不能重复的,HashSet它不能保证存入和取出的顺序一致,LinkedHashSet它可以保证存入和取出的顺序一致
- List成员方法
- void add(int index,E element)将元素插入到指定索引位置
- E remove(int index)删除指定索引对应的元素
- E get(int index)获取当前指定索引对应的元素
- E set(int index,E element)替换指定索引对应的元素
代码实现:
package cn.edu360;
import java.util.ArrayList;
import java.util.List;
public class ClassDemo {
public static void main(String[] args) throws Exception {
List c = new ArrayList();
c.add("javaee");
c.add("javase");
System.out.println(c);//[javaee, javase]
c.add(1, "helloWorld");
System.out.println(c);//[javaee, helloWorld, javase]
c.remove(1);
System.out.println(c);//[javaee, javase]
System.out.println(c.get(1));//javase
c.set(1, "Spark");
System.out.println(c);//[javaee, Spark]
}
}
数组和链表的区别:
List接口两个子类比较常用:
- ArrayList:底层是数组结构的,查询比较快,增删比较慢
- LinkedList:底层是链表结构的,查询比较慢,增删比较慢
代码实现:
package cn.edu360;
import java.util.ArrayList;
import java.util.Iterator;
public class ClassDemo {
public static void main(String[] args) throws Exception {
//遍历字符串
//test();
//遍历自定义数组
test2();
}
private static void test2() {
ArrayList list = new ArrayList();
list.add(new Person("张三", 18, "西安市"));
list.add(new Person("李四", 18, "天津市"));
list.add(new Person("王五", 18, "天水市"));
list.add(new Person("赵六", 18, "武汉市"));
System.out.println(list);
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
private static void test() {
ArrayList c = new ArrayList();
c.add("javaee");
c.add("javase");
c.add("hadoop");
Iterator iterator = c.iterator();
while (iterator.hasNext()) {
System.out.print(iterator.next()+" ");
}
}
}
相应的类:
package cn.edu360;
public class Person {
private String name;
private int age;
private String address;
public Person() {
}
public Person(String name, int age, String address) {
super();
this.name = name;
this.age = age;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address
+ "]";
}
}
注意事项:LinkedList和ArrayList相同,在此不加赘述
三、泛型
- 泛型的好处
- 提高了安全性
- 省去类型强转可能发生的错误
- 将运行时期的错误提前到了编译时期
- 泛型的特点
- 泛型只存在编译时期,当编译或字节码文件的时候,泛型会消失
注意事项:
(1)泛型定义在类上面,如果创建类的时候不指定确定的类型,那么默认就是Object类型,如果指定了明确的类型,那么这个泛型在整个类就是这个指定的类型
(2)用于类型强转的泛型方法,方法上面的泛型作用域是整个方法
(3)带泛型的接口的子类
A:如果不指定接口的泛型,那么子类也需要泛型下去,而且名字要一模一样
B:指定父接口的泛型类型,这时候可以定义自己的泛型,也可以不定义自己的泛型
四、增强for循环和注意事项:
- 格式说明
代码实现:
package cn.edu360;
import java.util.ArrayList;
public class ClassDemo {
public static void main(String[] args) throws Exception {
ArrayList<String> list = new ArrayList<String>();
list.add("hadoop");
list.add("小花猫");
list.add("javaee");
for(String value: list){
System.out.print(value+", ");
}
}
}
注意事项:
- 增强for循环在遍历集合时,内部使用的是迭代器
- 迭代器在进行迭代元素的时候不能直接使用集合来修改元素
五、可变参数:
就是当不知道方法的参数定义几个的时候,可以使用可变参数
格式如下:
代码实现:
package cn.edu360;
import java.util.Arrays;
public class ClassDemo {
public static void main(String[] args) throws Exception {
test(1,2);
}
private static void test(int... i) {
System.out.println(Arrays.toString(i));
}
}
注意事项:
- 可变参数本质上是一个数组
- 如果参数列表有多个参数时且存在可变参数时,可变参数永远放在最后一个位置
- 将数组转换成集合
public static List asList(T…a)
将一个数组转换成集合 - 将集合转换成数组
Object[] toArray()
返回按适当顺序包含列表中的所有元素的数组(从第一个元素到最后一个元素)
代码实现:
package cn.edu360;
import java.util.Arrays;
import java.util.List;
public class ClassDemo {
public static void main(String[] args) throws Exception {
//将数组转换成集合
Integer[] arr = {1, 2, 3, 4, 5};
List<Integer> list = Arrays.asList(arr);
//将集合转换成数组
Object[] array = list.toArray();
}
}
注意事项:
- 如果一个数组想转换成集合,那么数组中的所有元素都必须是引用类型
六、HashSet集合:
里面不能有重复的元素,而且存入的顺序和取出的顺序并不保持一致 - HashSet是哈希表结构,内部依靠元素对象的hashCode和equals方法去重的。首先会判断两个对象的哈希值是否相同,如果哈希值相同的话再去判断equals方法
- Set集合去重的原理是根据元素的hashCode方法和equals方法,自定义的对象需要重写这两个方法
七、LinkedHashSet集合:
链表+哈希表 - 它是有链表保证元素的存入顺序和取出顺序一致
- 由哈希表结构保证元素的唯一性
八、Map集合: - Map集合与Collection集合的区别
- Map集合是双列的,Collection集合是单列的
- Map集合只保证键的唯一
- Map存储的是以键值对的方式:key—value
- Map可以有重复值,不能有重复的键
- Collection集合中的List集合允许有重复的值
- Collection集合中的Set集合不允许有重复的值
- Map集合通过哈希表结构保证键的唯一
- Map集合介绍
Map集合是接口,里面的方法不能直接使用,所以使用它的子类HashMap,基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。(除了非同步和允许使用null之外,HashMap类与HashTable大致相同),此类不保证映射的顺序,也别是它不保证顺序恒久不变。 - 相应的方法
- V put (K key, V value)将指定的值与此映射中的指定键关联,返回的是以前与key关联的值
- V remove(Object key)移除此键对应的值,返回的是移除的值
- void clear()清空map集合
- boolean containsKey(Object key)判断是否包含指定的键
- boolean containsValue(Object value)判断是否包含指定的值
- boolean isEmpty()判断集合是否为空
- int size()返回map集合中键值对个数
代码实现:
package cn.edu360;
import java.util.HashMap;
import java.util.Map;
public class ClassDemo {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(110, "报警电话");
map.put(120, "急救电话");
map.put(119, "火警电话");
System.out.println(map);//{119=火警电话, 120=急救电话, 110=报警电话}
map.remove(110);
System.out.println(map);//{119=火警电话, 120=急救电话}
System.out.println(map.containsKey(120));//true
System.out.println(map.containsValue("哈哈"));//false
System.out.println(map.isEmpty());//false
System.out.println(map.size());//2
}
}
- 两种遍历方式
- V get (Object key)指定键所映射的值,如果此映射不包含该键的映射关系,则返回null
- Set keySet()获取键集
- Collection values()获取值集
- Set<Map, Entry<K, V>>entrySet()获取键值对映射关系集
(1)第一种遍历方式
获取所有键,然后遍历所有的键,然后通过键取值
代码实现:
package cn.edu360;
import java.util.Collection;
import java.util.HashMap;
import java.util.Set;
public class ClassDemo {
public static void main(String[] args) {
HashMap<Integer,String> map = new HashMap<Integer, String>();
map.put(1, "哈哈");
map.put(1, "呵呵");
map.put(2, "嘻嘻");
map.put(3, "哈哈");
map.put(4, "嘻嘻");
map.put(5, "呵呵");
//System.out.println(map);
Set<Integer> keys = map.keySet();
//System.out.println(keys);
Collection<String> values = map.values();
//System.out.println(values);
for(Integer key: keys){
String value = map.get(key);
System.out.println(key+"="+value);
}
}
}
(2)第二种遍历方式
获取键值对对象集合,然后遍历键值对集合,然后通过键值对对象获取键和值
代码实现:
package cn.edu360;
import java.util.HashMap;
import java.util.Map.Entry;
public class ClassDemo {
public static void main(String[] args) {
HashMap<Integer,String> map = new HashMap<Integer, String>();
map.put(1, "哈哈");
map.put(1, "呵呵");
map.put(2, "嘻嘻");
map.put(3, "哈哈");
map.put(4, "嘻嘻");
map.put(5, "呵呵");
// Set<Entry<Integer,String>> entrySet = map.entrySet();
// for(Entry<Integer,String> entry : entrySet){
// Integer key = entry.getKey();
// String value = entry.getValue();
// System.out.println(key+"="+value);
// }
//上述代码的变体,开发中常用下面这种形式
for(Entry<Integer, String> entry : map.entrySet()){
System.out.println(entry.getKey()+"="+entry.getValue());
}
}
}
注意事项:
- HashMap保证键的唯一,通过键对象的hashCode和equals方法,HahMap不保证存入的顺序和取出的顺序一致
- LinkedHashMap也能保证键的唯一,也是通过键对象的hashCode方法和equals方法,LinkedHashMap保证存入的顺序和取出的顺序一致
案例展示:
- Map集合嵌套List集合
package cn.edu360;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
/**
* * @author Zhang
*要求输出结果:
* 三国演义
* 吕布
* 周瑜
* 笑傲江湖
* 令狐冲
* 林平之
* 神雕侠侣
* 郭靖
* 杨过
*/
public class ClassDemo {
public static void main(String[] args) {
HashMap<String,ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
ArrayList<String> list = new ArrayList<String>();
list.add("吕布");
list.add("周瑜");
map.put("三国演义", list);
ArrayList<String> list2 = new ArrayList<String>();
list2.add("令狐冲");
list2.add("林平之");
map.put("笑傲江湖", list2);
ArrayList<String> list3 = new ArrayList<String>();
list3.add("郭靖");
list3.add("杨过");
map.put("神雕侠侣", list3);
for(Map.Entry<String, ArrayList<String>> entry : map.entrySet()){
String key = entry.getKey();
System.out.println(key);
ArrayList<String> value = entry.getValue();
for(String val : value){
System.out.println("\t"+val);
}
}
}
}
- Map集合嵌套Map集合
package cn.edu360;
import java.util.HashMap;
import java.util.Scanner;
/**
* @author Zhang
* 要求:有一个锦囊设置了三层防护,每一层都必须通过密码来获取,请想怎么设计这个程序
*/
public class ClassDemo {
public static void main(String[] args) {
//1、创建第一层防护
HashMap<Integer,String> map = new HashMap<Integer, String>();
map.put(110, "让孙夫人摆平东吴的追兵,她是孙权妹妹,东吴将领惧她三分");
//2、创建第二层防护
HashMap<Integer,HashMap<Integer,String>> map2 = new HashMap<Integer,HashMap<Integer, String>>();
map2.put(120, map);
//3、创建第三层防护
HashMap<Integer,HashMap<Integer,HashMap<Integer,String>>> map3 = new HashMap<Integer, HashMap<Integer,HashMap<Integer,String>>>();
map3.put(119, map2);
//4、拆解锦囊
Scanner sc = new Scanner(System.in);
while(true){
System.out.println("请输入最外层密码:");
int pwd = sc.nextInt();
HashMap<Integer,HashMap<Integer,String>> map4 = map3.get(pwd);
if(null != map4){
//解开第二层的防护
while(true){
System.out.println("请输入第二层密码:");
int pwd2 = sc.nextInt();
HashMap<Integer,String> map5 = map2.get(pwd2);
if(null != map5){
//解开第三层防护
System.out.println("请输入最后一层密码:");
int pwd3 = sc.nextInt();
String result = map.get(pwd3);
if(null != result){
//如果代码进入这里,说明最后一层防护已经被破解
System.out.println(result);
break;
}
//第二层防护已经进来,要结束掉本层循环
break;
}
System.out.println("第二层密码输入错误,请重新输入");
}
//密码输入正确,就要结束掉这层循环
break;
}
System.out.println("密码输入错误,请重新输入");
}
}
}
注意事项:上述代码可以应用到省市区的联动中