目录
Lambda表达式
作用: 用于简化匿名内部类中的代码写法
函数式接口是啥?函数式接口首先是一个接口,其次它只有一个抽象类方法
再次强调一下Lambda表达式的写法:
我们只要匿名内部类中方法的()和里面的参数,然后加->,再加方法代码块中的内容
(参数,有就写,没有拉倒)->{代码块}
省略写法(要看懂)
(1)参数类型可以省略不写
(2)如果只有一个参数,参数类型可以省略不写,()也可以省略不写
(3)如果表达式只有一行代码的时候的时候:
方法引用 标志符号"::"
正则表达式
语法
public class test {
public static void main(String[] args) {
//需求: 检验QQ号码是否正确,要求全部是数字,长度是(6-20)之间,不能以0开头
// 我们自己设计程序来校验
// System.out.println(checkQQ(null));
// System.out.println(checkQQ("1584878247"));
// System.out.println("-----------------------------");
// //正则表达式
// System.out.println(checkQQ("1584878247"));
System.out.println("a".matches("[abc]")); // [abc]只能匹配a,b,c
System.out.println("e".matches("[abcd]"));
System.out.println("d".matches("[^abc]"));// [^abc]不能是a,b,c
System.out.println("a".matches("[^abc]"));
System.out.println("b".matches("[a-zA-Z]")); // [a-zA-Z]只能是a-z和A-Z
System.out.println("2".matches("[a-zA-Z]"));
System.out.println("k".matches("[a-z&&[^bc]]")); // a 到z,除了b和c
System.out.println("b".matches("[a-z&&[^bc]]"));
System.out.println("ab".matches("[a-zA-Z0-9]")); // false 上面的带[内容]的规则只能用于匹配单个字符
// 2.预定义字符(只能匹配单个字符) . /d /D /s /S /w /W
System.out.println("李".matches("."));
System.out.println("李李".matches("."));
// 在Java中,\是有特殊用途的,例如特殊字符\n \t
System.out.println("1".matches("\\d"));
System.out.println("12".matches("\\d"));
System.out.println(" ".matches("\\s")); // \s:表示一个空白字符
System.out.println("a".matches("\\s"));
System.out.println("a".matches("\\S")); // \S表示一个非空字符
System.out.println(" ".matches("\\S"));
System.out.println("a".matches("\\w"));
System.out.println("_".matches("\\w"));
System.out.println("李".matches("\\w"));
System.out.println("李".matches("\\W")); // \[^\w]不能是a-zA-Z_0-9
System.out.println("a".matches("\\W"));
System.out.println("2123".matches("\\d")); // 注意上面预定文字符都只能匹配单个字符
// 3. 数量词 ? * + {n} {n,} {n,m}
System.out.println("a".matches("\\w?")); // ?出现0次或1次
System.out.println("".matches("\\w?")); // 出现0次
System.out.println("abc12".matches("\\w*")); // *代表0次或多次
System.out.println("".matches("\\w*")); // true
System.out.println("abc12".matches("\\w*")); //false
System.out.println("abc12".matches("\\w+")); // + 表示1次或者多次
System.out.println("".matches("\\w+")); // false
System.out.println("abc12张".matches("\\w+")); // false
System.out.println("a3c".matches("\\w{3}")); // {3}表示正好是n次
System.out.println("abcd".matches("\\w{3}")); // false
System.out.println("abcd".matches("\\w{3,}")); // {3,}表示>=3次
System.out.println("ab".matches("\\w{3,}")); // false,ab出现了两次
System.out.println("abcde李".matches("\\w{3,}")); // false
System.out.println("abcd12345".matches("\\w{3,9}"));
// 其他几个常用的符号(?i)忽略大小写 或 : | 分组:()
System.out.println("abc".matches("(?i)abc")); // true
System.out.println("ABC".matches("(?i)abc")); // true
System.out.println("aBc".matches("a((?i)b)c")); // true
System.out.println("ABc".matches("a((?i)b)c")); // true
// 要么是3个小写字母 要么是3个数字
System.out.println("123".matches(("\\d{3}|[a-z]{3}")));
System.out.println("abc".matches("\\d{3}|[a-z]{3}"));
System.out.println("aAc".matches("\\d{3}|[a-z]{3}"));
System.out.println("我爱编程666666".matches("我爱(编程)+(666)+"));
}
}
案例
public class zheng {
public static void main(String[] args) {
while (true) {
System.out.println("请输入您的电话号码(手机|座机)");
Scanner sc = new Scanner(System.in);
String phone = sc.nextLine();
if(phone.matches("(1[3-9]\\d{9})|(0\\d{2,7}(-)?[1-9]\\d{4,19})")) {
System.out.println("格式正确");
break;
}
else{
System.out.println("输入不正确");
}
}
}
}
public class zheng {
public static void main(String[] args) {
while (true) {
System.out.println("请输入您的邮箱");
Scanner sc = new Scanner(System.in);
String phone = sc.nextLine();
// 如果我们想用. ,前面要加转义字符
if(phone.matches("\\w{2,}@\\w{2,10}(\\.\\w{2,9}){1,2}")) {
System.out.println("格式正确");
break;
}
else{
System.out.println("输入不正确");
}
}
}
}
public class zheng {
//爬取一段文本的信息
public static void main(String[] args) {
String data = "15234456782" +
" 159632478@qq.com" +
" 400-168-4568";
// 1.定义爬取规则
String regex = "(\\w{2,}@\\w{2,10}(\\.\\w{2,9}){1,2})|" +
" (1[3-9]\\d{9})|(0\\d{2,7}(-)?[1-9]\\d{4,19})|"+
"(400-?\\d{3,7}-?\\d{3,7})";
// 2.把正则表达式封装成一个Pattern对象
Pattern pattern = Pattern.compile(regex);
// 3.通过pattern对象去获取查找内容的匹配器对象
Matcher matcher = pattern.matcher(data);
// 4.定义一个循环开始获取信息
while (matcher.find()){
String rs = matcher.group();
System.out.println(rs);
}
}
}
正则表达式的搜索替换和分割内容
public class zheng {
public static void main(String[] args) {
String s1 = "古力娜扎1745236迪丽热巴5221李小谦";
System.out.println(s1.replaceAll("\\w+","-"));
String s2 = "我我我喜欢编编编编编程程";
System.out.println(s2.replaceAll("(.)\\1+","$1"));
String s3 = "古力娜扎1745236迪丽热巴5221李小谦";
String[] names = s3.split("\\w+");
System.out.println(names.toString());
}
}
集合进阶
集合体系结构
Collection 单列集合: 每个元素(数据)只包含一个值
Map双列集合: 每个元素包含两个值(键值对)
Collection
强调一下上面的有序: 指的是,我们向一个集合中添加元素的时候,如果取出元素的顺序和我们添加的顺序一样的时候,这个时候叫有序
public class zheng {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>(); //多态写法
// 1.添加元素 , 添加成功返回true
c.add("java1");
c.add("java2");
c.add("java1");
c.add("java3");
//2.清空集合的元素
//c.clear();
//System.out.println(c);
//3.判断集合是否为空,是空返回true
System.out.println(c.isEmpty());
// 4.返回大小
System.out.println(c.size());
//5.判断集合中是否包含某个元素
System.out.println(c.contains("java1"));
System.out.println(c.contains("java2"));
//6.删除某个元素:如果有多个重复元素默认删除前面的第一个
System.out.println(c.remove("java1"));
System.out.println(c);
// 7.把集合转换成数组
Object[] arr = c.toArray();
System.out.println(Arrays.toString(arr));
// 8.将集合按照指定类型转成对应数据类型的数组
String[] arr2 = c.toArray(new String[c.size()]);
System.out.println(Arrays.toString(arr2));
//9.把一个集合的全部数据拷贝倒入另一个集合中
Collection<String>c1 = new ArrayList<>();
c1.add("java1");
c1.add("java2");
Collection<String>c2 = new ArrayList<>();
c2.add("java3");
c2.add("java4");
c1.addAll(c2);
System.out.println(c1);//[java1, java2, java3, java4]
System.out.println(c2);//[java3, java4]
}
}
Collection的遍历方式
迭代器
public class zheng {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>(); //多态写法
// 1.添加元素 , 添加成功返回true
c.add("java1");
c.add("java2");
c.add("java1");
c.add("java3");
Iterator<String> it = c.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
}
增强for循环
可以用来遍历集合或者数组
for(元素的数据类型 变量名:数组或集合){
}
public class zheng {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>(); //多态写法
// 1.添加元素 , 添加成功返回true
c.add("java1");
c.add("java2");
c.add("java1");
c.add("java3");
for(String ele:c){
System.out.println(ele);
}
}
}
Lambda表达式遍历Collection
public class zheng {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>(); //多态写法
// 1.添加元素 , 添加成功返回true
c.add("java1");
c.add("java2");
c.add("java4");
c.add("java3");
c.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
System.out.println("***************************");
// Lambda表达式进行简化代码
c.forEach( s-> System.out.println(s));
System.out.println("****************************");
// 再进一步简化,方法引用
c.forEach( System.out::println);
}
}
集合中存贮的是元素的地址
List集合
public class zheng {
public static void main(String[] args) {
// 1.创建一个ArrayList集合对象(有序,可重复,有索引)
List<String> list = new ArrayList<>(); // 这是一种多态的写法
list.add("人上人");
list.add("孙悟空");
list.add("至尊宝");
list.add("孙悟空");
System.out.println(list);
// 2.public void add(int index,E element): 在谋个索引位置插入元素
list.add(2,"紫霞仙子");
System.out.println(list);
// 3. public E remove(int index) : 根据索引删除元素,返回插入元素
System.out.println(list.remove(2));
System.out.println(list);
// 4.public E get (int index) : 返回集合中指定位置的元素
System.out.println(list.get(3));
// public E set(int index,E element): 修改索引位置处的元素,修改成功后返回原来的元素
System.out.println(list.set(1,"牛魔王"));
}
}
List集合的遍历
public class zheng {
public static void main(String[] args) {
// 1.创建一个ArrayList集合对象(有序,可重复,有索引)
List<String> list = new ArrayList<>(); // 这是一种多态的写法
list.add("人上人");
list.add("孙悟空");
list.add("至尊宝");
list.add("孙悟空");
// (1)for循环
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
System.out.println("****************");
// (2)迭代器
Iterator<String> it = list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("*****************");
// 增强for
for (String s : list) {
System.out.println(s);
}
System.out.println("*****************");
// Lambda 表达式
list.forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
}
}
ArrayList
有序,可重复,有索引
底层基于数组
希望记住元素的添加顺序,需要存储重复元素,又要频繁的根据索引查询数据
LinkedList
有序,可重复,有索引
底层基于双链表
希望记住元素的添加顺序,且增删首位数据的情况较多
哈希值
一个int类型的数值,Java中每个对象都有一个哈希值
Java中所有对象,都可以调用Object类提供的hashCode,返回该对象自己的哈希值
public int hashCode() 返回对象的hash值
对象哈希值的特点
同一个对象多次调用hashCode()方法返回的哈希值是相同的
不同对象,它们的哈希值一般是不相同的,但也有可能会相同(哈希碰撞)
HashSet底层原理
无序,不重复,无索引(无序指的是先加的元素不一定在前面)
基于哈希表
哈希表是一种增删改查数据
Hashset集合默认不能对内容一样的两个对象去重复,如果你想要对内容一样的两个对象进行去重,要重写hashCode和equals方法
LinkedHashSet底层原理
有序,不重复,无索引(有序指的是先加的元素一定在前面)
基于哈希表实现的,多了一个双链表机制记录前后元素的位置
TreeSet
不重复,无索引,可排序
基于红黑树实现的
Tree集合储存自定义对象时,必须指定排序规则,安置下面两种方法指定比较规则
(1)让自定义的类(如学生类)实现comparable接口,重写里面的compareTo方法来指定比较规则
(2)通过调用TreeSet集合有参数构造器,可以设置Comparator对象(比较器对象,用于指定比较规则)
这里的Comparator是一个接口,我们用匿名内部类作为实现类,将接口中的方法进行重写,就可以自定义排序规则了
注意事项
并发修改异常(遍历的同时删除数据)
使用迭代器遍历集合时,又同时在删除集合中的数据,程序就会并发修改异常的错误
public class zheng {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("王麻子");
list.add("李小谦");
list.add("李浴缸");
list.add("李玉刚");
list.add("鲤鱼杠");
list.add("李於杠");
// Iterator<String> it = list.iterator();
// while(it.hasNext())
// {
// String name = it.next();
// if(name.contains("李")){
// // list.remove(it.next()); // 会出现并发修改错误
// it.remove(); // 删除迭代器当前遍历的数据,每删除一个数据后,相当于做了i--
// }
// }
// System.out.println(list);
for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
if(name.contains("李")){
list.remove(name);
i -- ;
}
}
System.out.println(list);
}
}
增强for循环和Lambda遍历的时候这个错误是不能修改的
还要注意到是,像set类的数据集合,不能取到索引是不能用for循环来遍历的,只能用迭代器来遍历集合,但是List集合可以用for循环也可以用迭代器