集合集合体系结构CollectionCollection是一个接口在它下面有两个常用接口:List和Set,这两个接口下又有很多的实现类List:添加的元素有序、可重复、有索引ArrayList、LinkedListSet:添加的元素无序、不重复、无索引HashSet、LinkedHashSet(有序)、TreeSet(升序)Collection接口中的常用方法code:importjava.util.ArrayList;importjava.util.Collection;importjava.util.Arrays;publicclassMain{publicstaticvoidmain(String[]args){CollectionStringc=newArrayList();// 多态写法// 1. 添加元素c.add("C++");c.add("Java");// 2. 清空集合c.clear();// 3. 判断集合是否为空,若为空则返回trueSystem.out.println(c.isEmpty());// 4.判断集合中是否包含给定对象c.add("Java");System.out.println(c.contains("Java"));// 5.返回集合中元素个数System.out.println(c.size());// 6.把集合中元素,存储到数组中Objecta[]=c.toArray();System.out.println(Arrays.toString(a));// 7.删除给定元素(根据是否删除成功返回boolean)System.out.println(c.remove("Java"));}}Collection集合的遍历迭代器的行为如下:初始状态:调用c.iterator()时,迭代器指向集合的起始位置,此位置在第一个元素之前。此时,如果你调用it.hasNext(),会返回true,因为集合中确实有元素。调用it.next():当你调用it.next()时,迭代器会将指针移到第一个元素,并返回该元素。因此,迭代器在调用next()之前并不指向任何元素,但可以通过next()方法来获取第一个元素,并使指针指向下一个元素的位置。code:importjava.util.ArrayList;importjava.util.Collection;importjava.util.Arrays;importjava.util.Iterator;publicclassMain{publicstaticvoidmain(String[]args){CollectionStringc=newArrayList();// 多态写法// 1. 添加元素c.add("C++");c.add("Java");c.add("Python");//使用迭代器遍历集合//创建迭代器IteratorStringit=c.iterator();//手工遍历System.out.println(it.next());//返回集合中第一个元素,并且指针后移一位//循环遍历while(it.hasNext()){System.out.println(it.next());}}}增强for循环本质是迭代器遍历集合或者数组的简化写法code:importjava.util.ArrayList;importjava.util.Collection;importjava.util.Arrays;importjava.util.Iterator;publicclassMain{publicstaticvoidmain(String[]args){CollectionStringc=newArrayList();// 多态写法// 1. 添加元素c.add("C++");c.add("Java");c.add("Python");//增强for循环for(Strings:c){System.out.println(s);}}}Lambda表达式遍历集合code:importjava.util.ArrayList;importjava.util.Collection;importjava.util.Arrays;importjava.util.Iterator;importjava.util.function.Consumer;publicclassMain{publicstaticvoidmain(String[]args){CollectionStringc=newArrayList();// 多态写法// 1. 添加元素c.add("C++");c.add("Java");c.add("Python");//default void forEach(Consumer? super T action) :结合lambda表达式遍历集合c.forEach(newConsumerString(){@Overridepublicvoidaccept(Strings){System.out.println(s);}});}}forEach的原理:使用Lambda表达式进行简化存储对象的原理:外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传集合存储在堆内存中,再执行add方法时会将需要加入的对象的地址加入到集合之中。集合中存储的是元素的地址ListList特有方法ListStringlist=newArrayList();// 多态写法// 1. 添加元素list.add("C++");list.add("Java");list.add("Python");//在某个索引位置插入元素list.add(2,"Go");System.out.println(list);//根据索引删除元素list.remove(2);System.out.println(list);//返回集合中指定位置的元素System.out.println(list.get(2));//修改索引出的元素,修改成功的画会返回原来的数据System.out.println(list.set(2,"C"));List支持的遍历方式for循环//for循环for(inti=0;ilist.size();i++){Strings=list.get(i);System.out.println(s);}其余三种和Collection一样:迭代器、增强for循环、Lambda表达式加forEach两种List底层原理ArrayList基于数组实现特点:查询快、增删慢Mapmap体系:实际上Set集合的底层就是基于Map实现的,只是Set集合中元素只要key不要value故底层原理中Map和Set相同HashMap就是用Key得到Hashcode实现的HashSetLinkedHashMap与LinkedHashSet的不同之处在于链表中存的是Entry对象TreeMap和LinkedHashMap(Hash表+红黑树)一样用到的是红黑树TreeMap是按照键值升序,若键是自定义类型要通过自定义类继承Comparable接口,并重写compareTo方法或者使用TreeMap的有参构造器,这个有参构造起中支持创建Comparator比较器对象,从而制定比较规则。Map常用方法创建map对象:Map中常用方法:Map中的遍历方式一、键找值先用一个Set保存集合中全部键,再通过遍历键来找值publicstaticvoidmain(String[]args){MapString,Integermap=newHashMap();map.put("yesterday",20);map.put("today",21);map.put("tomorrow",22);//1.获取全部的keySetStringkeys=map.keySet();//使用加强for循环遍历key//2.循环找到每个key对应的valuefor(Stringkey:keys){intvalue=map.get(key);//System.out.println(value);}}二、键值对将"键值对"看成一个整体进行遍历关键点:使用 Map.Entry方法使用Set来保存键值对,遍历Set中的键值对键值对是一个 Map.Entry对象 类型:Map.EntryString,Integerpublicstaticvoidmain(String[]args){MapString,Integermap=newHashMap();map.put("yesterday",20);map.put("today",21);map.put("tomorrow",22);//将Map中的键值对存入Set中SetMap.EntryString,Integerentries=map.entrySet();//遍历Set中的键值对for(Map.EntryString,Integerentry:entries){System.out.println(entry.getKey());System.out.println(entry.getValue());}}三、Lambda+Map中的forEach方法Lambda 表达式的形式是 (参数1, 参数2) - { 逻辑代码 },在这里,k 是键,v 是值。BiConsumer 是 Java 8 中引入的一个功能性接口,属于 java.util.function 包。它表示接受两个输入参数并且不返回任何结果的操作。这个接口常用于需要处理两个输入并对其进行某种操作而不必返回值的场景。示例:// 创建一个 BiConsumer,接受两个字符串并打印它们的连接BiConsumerString, String biConsumer = (firstName, lastName) - {System.out.println("Full Name: " + firstName + " " + lastName);};publicstaticvoidmain(String[]args){MapString,Integermap=newHashMap();map.put("yesterday",20);map.put("today",21);map.put("tomorrow",22);//使用Lambda+forEachmap.forEach((k,v)-{System.out.println(k+" "+v);});}forEach方法接受一个 BiConsumer 接口作为参数,意味着它希望一个接受两个参数(键和对应的值)而没有返回值的函数。在完整的代码中时以BiConsumer 接口作为匿名内部类,作为传入forEach的参数 ,并重写其中抽象方法accept在forEach的源码中传入的参数是BiConsumer类型的action,在判断action不会空后,使用第二种方法调用map(通过this.entrySet()得到map.entrySet()),得到键值对后,调用action.accept(),将键值对传入到accept方法中案例:代码:publicstaticvoidmain(String[]args){ListStringdata=newArrayList();String[]select={"A","B","C","D"};Randomr=newRandom();//用Set储存四个景点的投票for(inti=0;i80;i++){//随机获取一个数,使得景点投票数随机+1intindex=r.nextInt(4);data.add(select[index]);}//使用Map统计四个景点的投票数MapString,Integerresult=newHashMap();//开始遍历80个景点数据for(Strings:data){//这个景点若不是第一次存入map 则该景点投票数+1if(result.containsKey(s)){result.put(s,result.get(s)+1);}//若这个景点第一次存入则设初值为1else{result.put(s,1);}}System.out.println(result);}集合的嵌套在Map集合对象中可以嵌套使用Set集合对象黑马点评1.短信登录1.1 发送验证码UserController/** * 发送手机验证码 */@PostMapping("code")publicResultsendCode(@RequestParam("phone")Stringphone,HttpSessionsession){// 发送短信验证码并保存验证码returnuserService.sendCode(phone,session);}UserServiceImpl@OverridepublicResultsendCode(Stringphone,HttpSessionsession){// 1.校验手机号if(RegexUtils.isPhoneInvalid(phone)){// 2.如果不符合,返回错误信息returnResult.fail("手机号格式错误!");}// 3.符合,生成验证码Stringcode=RandomUtil.randomNumbers(6);// 4.保存验证码到 sessionsession.setAttribute("code",code);// 5.发送验证码log.debug("发送短信验证码成功,验证码:{}",code);// 返回okreturnResult.ok();}session = 服务器给当前用户开辟的【临时私人储物柜】一次浏览器打开 → 服务器自动分配 一个专属 session不同用户、不同浏览器 → session 互不干扰可以把它理解成:浏览器和服务器之间的 “临时对话记录本”其中RegexUtils是自定义的类,其中检查手机号的方法类似于:privatestaticfinalPatternPHONE_PATTERN=Pattern.compile("^1[3-9]\\d{9}$");在JAVA中\是特殊字符,要想输出一个 \,必须写 \1.2 实现短信验证码登录和注册功能用户将验证码和手机号进行输入,后台从session中拿到当前验证码,然后和用户输入的验证码进行校验,如果不一致,则无法通过校验;如果一致,则后台根据手机号查询用户,如果用户不存在,则为用户创建账号信息,保存到数据库,无论是否存在,都会将用户信息保存到session中,方便后续获得当前登录信息。UserServiceImpl@OverridepublicResultlogin(LoginFormDTOloginForm,HttpSessionsession){// 1.校验手机号Stringphone=loginForm.getPhone();if(RegexUtils.isPhoneInvalid(phone)){// 2.如果不符合,返回错误信息returnResult.fail("手机号格式错误!");}//3.校验验证码ObjectCacheCode=session.getAttribute("code");Stringcode=loginForm.getCode();if(CacheCode==null!CacheCode.