java从零开始系统性学习完整超全资源+笔记(下)

java从零开始系统性学习完整超全资源+笔记(下)

java从零开始系统性学习完整超全资源+笔记(上)

文章目录

  • java从零开始系统性学习完整超全资源+笔记(下)
    • 第十七章 泛型与常见数据结构
      • ArrayList
      • Collection接口的实现
      • 泛型 generics
      • 迭代器Iterator
      • foreach
      • 常见的数据结构
        • 数组
        • 链表
      • 栈和队列
      • List
      • LinkedList
      • 案例 查找元素索引及判断元素是否存在案例
      • 练习
    • 第十八章 Set与Map集合
      • Set
      • 增强for循环
      • hashSet
      • 方法重载与重写
      • hashCode方法和equals方法的优化
    • Collection
        • 定义
        • Collection和Collections有什么区别?
        • collection方法
      • Collection练习 模拟斗地主
    • Map
      • Map和Collection有什么区别?
        • map常用功能
        • map的两种遍历方式
        • Map的第二种遍历方式
        • 使用HashMap存储数据并遍历(字符串作为key)
        • 使用HashMap存储数据并遍历(自定义对象作为key)
    • 异常的处理
      • 异常的概述和体系结构.
      • JVM处理异常的方式
      • 如何处理多个异常
      • Throwable的常用方法
      • finally概述和应用场景
      • 异常的分类
      • 自定义异常
      • 递归概述和例题

第十七章 泛型与常见数据结构

ArrayList
集合的体系结构:
由于不同的数据结构(数据的组织,存储方式),所以Java为我们提供了不同的集合,
但是不同的集合他们的功能都是相似,不断的向上提取,将共性抽取出来,这就是集合体系结构形成的原因
体系结构:
怎么学习?最顶层开始学习,因为最顶层包含了所有的共性
怎么使用?使用最底层,因为最底层就是具体的实现
Collection
List

ArrayList

package com.demo01;import java.util.ArrayList;/**  ArrayList*  集合的体系结构:*  	由于不同的数据结构(数据的组织,存储方式),所以Java为我们提供了不同的集合,*  	但是不同的集合他们的功能都是相似,不断的向上提取,将共性抽取出来,这就是集合体系结构形成的原因*  *  体系结构:*  		怎么学习?最顶层开始学习,因为最顶层包含了所有的共性*  		怎么使用?使用最底层,因为最底层就是具体的实现*  *  Collection*  List*  ArrayList*/
public class CollectionDemo {public static void main(String[] args) {		//创建集合对象ArrayList al = new ArrayList();//添加元素al.add("hello");al.add("world");al.add("java");//遍历集合for(int x = 0;x < al.size();x++) {System.out.println(al.get(x));}}
}

Collection接口的实现

Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接 实现:**它提供更具体的子接口(如 Set 和 List)**实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。

/** 	Collection接口的实现* 			boolean add(E e) 确保此 collection 包含指定的元素(可选操作)。* 			void clear() 移除此 collection 中的所有元素(可选操作)。* 			boolean contains(Object o) 如果此 collection 包含指定的元素,则返回 true。* 			boolean isEmpty() 如果此 collection 不包含元素,则返回 true。* 			boolean remove(Object o) 从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。* 			int size() 返回此 collection 中的元素数。* 			Object[] toArray()  返回包含此 collection 中所有元素的数组。* 		如果此 collection 包含指定的元素,则返回 true。更确切地讲,当且仅当此 collection 至少包含一个满足 (o==null ? e==null : o.equals(e)) 的元素 e 时,返回 true。*/
package CollectionDemo;import java.util.ArrayList;
import java.util.Objects;public class ArrayListDemo2 {public static void main(String[] args) {ArrayList a = new ArrayList();
//        1.boolean add(E e)a.add("hello1");    //add的时候运行没有东西,必须打印出来才有a.add("hello2");
//        2.void clear()
//        a.clear();for(int i = 0;i<a.size();i++){System.out.println(a.get(i));}
//      3.boolean contains(Object o)boolean flag = a.contains("hello1");    //包含就返回trueSystem.out.println(flag);System.out.println(a);
//        boolean isEmpty()boolean flag1 = false;if(a!=null&&a.isEmpty()){flag1 = true;System.out.println(flag);}
//        boolean remove(Object o)boolean f = a.remove("hello1");System.out.println(f);System.out.println(a);int size = a.size();System.out.println(size);
//        Object[] toArray()Object[] objects = a.toArray();for(int i = 0;i< objects.length;i++){System.out.println(objects[i]);}}
}

泛型 generics

使用集合存储自定义对象并遍历* 由于集合可以存储任意类型的对象,当我们存储了不同类型的对象,就有可能在转换的时候出现类型转换异常,* 所以java为了解决这个问题,给我们提供了一种机制,叫做泛型* * 泛型:是一种广泛的类型,把明确数据类型的工作提前到了编译时期,借鉴了数组的特点* 泛型好处:* 			避免了类型转换的问题* 			可以减少黄色警告线* 			可以简化我们代码的书写 不用强制类型转换* * 什么时候可以使用泛型?* 		问API,当我们看到<E>,就可以使用泛型了List ArrayList Collection 等都可以用泛型使用泛型的缺点
虽然泛型在很多情况下能够提供强类型检查和代码重用的好处,但它们也有一些缺点,包括以下几点:**增加代码复杂性**:泛型代码通常比非泛型代码更复杂,因为它需要在类型安全的同时支持多种数据类型。这可能导致代码更难理解和维护。**增加编译时间**:泛型代码通常需要更多的编译时间,因为编译器必须在编译时生成并检查泛型类型的代码。这可能会导致较长的编译时间,特别是在使用大量泛型的大型项目中。受限于类型擦除:在 Java 中,泛型类型信息在编译时被擦除,这意味着在运行时无法访问泛型类型的信息。这可以导致一些类型转换和类型安全问题,尤其是在处理复杂的泛型类型时。需要额外的学习和使用成本:泛型是一种相对较新的编程技术,因此需要额外的学习成本。此外,对于一些简单的应用程序,使用泛型可能是过度设计,这可能会增加使用成本和复杂性。综上所述,泛型的使用虽然有很多好处,但也需要仔细考虑其使用场景和实际需求,以平衡其优点和缺点。

例如
在这里插入图片描述

package CollectionDemo;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/*泛型概述
使用集合可以存储任意类型的对象,由于存储了不同类型的对象,有可能在转换的时候
出现类型转换异常。所以java为了解决这个问题,提供了一种机制generic泛型
泛型:是一种广泛的类型,把明确数据类型的工作提前到了编译时期,借鉴了数组的特点
泛型的好处:避免类型转换的问题可以减少黄色警告线简化代码书写 不用强制类型转换
什么时候用泛型?问API,当我们看到就可以使用泛型List ArrayList Collection等都可以用泛型*/
public class GenericDemo {public static void main(String[] args) {
/*
//        不知道集合里面的类型是什么,所以用泛型解决这个问题
//        Iterator 是一个接口,用于遍历集合(如 List、Set、Map 等)中的元素Collection c = new ArrayList();c.add("hello");Iterator iterator = c.iterator();int i = (int) iterator.next();System.out.println(i);
//出现异常 java.lang.String cannot be cast to java.lang.Integer
*///        创建集合对象Collection<Student> c = new ArrayList<Student>();
//        创建元素对象Student s1 = new Student("zhangsan1",13);Student s2 = new Student("zhangsan2",16);
//         添加元素对象c.add(s1);c.add(s2);
//        遍历元素对象Iterator<Student> it = c.iterator();while (it.hasNext()){Student stu = it.next();System.out.println(stu.name);}}static class Student{String name;int age;public Student(String name,int age){this.name = name;this.age = age;}}
}
package com.demo03;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;/** 使用集合存储自定义对象并遍历* 由于集合可以存储任意类型的对象,当我们存储了不同类型的对象,就有可能在转换的时候出现类型转换异常,* 所以java为了解决这个问题,给我们提供了一种机制,叫做泛型* * 泛型:是一种广泛的类型,把明确数据类型的工作提前到了编译时期,借鉴了数组的特点* 泛型好处:* 			避免了类型转换的问题* 			可以减少黄色警告线* 			可以简化我们代码的书写 不用强制类型转换* * 什么时候可以使用泛型?* 		问API,当我们看到,就可以使用泛型了List ArrayList都可以用泛型* 			*/
public class GenericDemo {public static void main(String[] args) {/*	Collection c = new ArrayList();c.add("Hello");Iterator iterator = c.iterator();int i = (int) iterator.next();System.out.println(i);*///String[] s =new String[3];//创建集合对象Collection<Student> c = new ArrayList<Student>();//创建元素对象Student s = new Student("zhangsan",18);Student s2 = new Student("lisi",19);//添加元素对象c.add(s);c.add(s2);//遍历集合对象Iterator<Student> it = c.iterator();while(it.hasNext()) {Student stu = it.next();System.out.println(stu.name);}}
}class Student {String name;int age;public Student(String name,int age) {this.name = name;this.age = age;}
}

迭代器Iterator

chatGPT回答
在 Java 中,Iterator 是一个接口,用于**遍历集合(如 List、Set、Map 等)中的元素**。Iterator 接口定义了访问和移除集合中元素的方法,可以帮助开发者逐个访问集合中的元素,而不需要暴露底层数据结构的实现细节。Iterator 接口包含以下几个方法:hasNext():返回集合中是否还有下一个元素。
next():返回下一个元素。
remove():从集合中移除上一次返回的元素(可选操作)。
使用 Iterator 遍历集合的基本流程是:首先通过集合对象的 iterator() 方法获得 Iterator 实例,然后通过调用 hasNext() 和 next() 方法逐个访问集合中的元素,最后使用 remove() 方法删除元素(如果需要)。Iterator 接口的出现使得遍历集合变得更加方便和灵活,同时也提高了代码的可读性和可维护性。

在使用迭代器进行遍历的时候使用迭代器来进行修改
在这里插入图片描述
iterator() 可以返回一个迭代器对象,我们可以通过迭代器对象来迭代集合

  • Iterator:可用于遍历集合
  • E next()返回下一个元素
  • boolean hasNext():判断元素是否可以获取
package CollectionDemo;import java.util.ArrayList;
import java.util.Collection;
import java.util.Objects;/*
* 集合的遍历方式
*   1.toArray() 可以将集合转化成数组,然后遍历数组即可
*   2.iterator() 可以返回一个迭代器对象,我们可以通过迭代器对象来迭代集合
* Iterator:可用于遍历集合
* E next()返回下一个元素
* boolean hasNext():判断元素是否可以获取
* 注意:Exception in thread "main" java.util.NoSuchElementException
* 使用next方法获取下一个元素,如果没有元素可以获取,则出现NoSuchElementException
* */
public class IteratorDemo1 {public static void main(String[] args) {
//        创建集合对象Collection c = new ArrayList();
//        添加元素c.add("hello1");c.add("hello2");
//        获取数组Object[] objs = c.toArray();
//        遍历数组for (int i = 0; i < objs.length; i++) {System.out.println(objs[i]);}}
}
/*运行结果
hello1
hello2
*/
package CollectionDemo;import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;public class IteratorDemo2 {public static void main(String[] args) {//创建集合对象Collection c = new ArrayList();//添加元素c.add("hello1");c.add("hello2");
//        获取迭代器对象Iterator it = c.iterator();
//        Object next():返回下一个元素/* System.out.println(it.next());System.out.println(it.next());
//        输出hello1,hello2*///        boolean hasNext():判断是否有元素可以获取/* if(it.hasNext()){System.out.println(it.next());}   //输出hello1*/while (it.hasNext()){System.out.println(it.next());}   //输出 hello1 hello2}
}
package CollectionDemo;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;/*需求:判断集合中是否包含元素java,如果有则添加元素android
Exception in thread "main" java.util.ConcurrentModificationException:并发修改异常
迭代器是依赖集合的,相当于集合的一个副本,当迭代器在操作的时候如果发现和迭代器不一样就抛出异常
解决方案:别使用迭代器在使用迭代器进行遍历的时候使用迭代器来进行修改
* */
public class IteratorDemo3 {public static void main(S,,,,,,,,,,,,,,,tring[] args) {
//        创建集合对象List c = new ArrayList();
//        添加元素c.add("hello1");c.add("hello2");c.add("java");System.out.println(c);
//        通过遍历集合中的每一个元素来比较判断是否包含java/* Iterator it = c.iterator();while (it.hasNext()){String s = (String) it.next();if(s.equals("java")){c.add("android");}}System.out.println(c);Exception in thread "main" java.util.ConcurrentModificationException:并发修改异常
迭代器是依赖集合的,相当于集合的一个副本,当迭代器在操作的时候如果发现和迭代器不一样就抛出异常*/ListIterator lit = c.listIterator();while (lit.hasNext()){String s =(String)lit.next();if(s.equals("java")){lit.add("android"); //  在使用迭代器进行遍历的时候使用迭代器来进行修改}}System.out.println(c);}
}

foreach

foreach:增强for循环,一般用于遍历集合或者数组
格式:
for(元素的类型 变量 : 集合或者数组对象) {
可以直接使用变量;
}
注意:在增强for循环中不能修改集合,否则会出现并发修改异常,不能进行增减。

public interface Iterable
实现这个接口允许对象成为 "foreach" 语句的目标。
package com.demo04;import java.util.ArrayList;
import java.util.Collection;/** foreach:增强for循环,一般用于遍历集合或者数组* 格式:* 		for(元素的类型 变量 : 集合或者数组对象) {* 			可以直接使用变量;* 		}注意:在增强for循环中不能修改集合,否则会出现并发修改异常,不能进行增减。public interface Iterable实现这个接口允许对象成为 "foreach" 语句的目标。*/
public class ForEachDemo {public static void main(String[] args) {/* //创建集合对象Collection c = new ArrayList();//添加元素c.add("hello");c.add("world");c.add("java");//增强for循环遍历集合for(Object obj : c) {System.out.println(obj);}for(String s : c) {s = s.toUpperCase()+"其他的内容";System.out.println(s);}for(String s : c) {System.out.println(s);}*//*for (String string : c) {c.add("android");System.out.println(string);}*/Collection<Student> c = new ArrayList<Student>();c.add(new Student("张三",20));c.add(new Student("李四",18));for(Student student:c) {System.out.println("name:"+student.name+"  age:"+student.age);}/* for(Student student:c) { 用foreach对集合修改就出现异常  ConcurrentModificationException:并发修改异常System.out.println("name:"+student.name+"  age:"+student.age);student.name = student.name+"xx";c.add(new Student("王五",22));}*/}}class Student {String name;int age;public Student(String name, int age) {super();this.name = name;this.age = age;}}
结果name:张三  age:20
name:李四  age:18

常见的数据结构

数组

数据结构图
在这里插入图片描述

特点:1.长度一旦定义就不能被改变;2.数组中的元素都有整数索引;3.数组只能存储同一数据类型的元素;4.数组既可以存储基本数据类型,也可以存储引用数据类型。
优点:检索快,因为可以通过索引获取数组元素
缺点:增加和删除数据慢,因为需要创建新的数据,效率低。
如何插入新的元素?如[1,2,3,4]3后面插入8。
首先创建一个新的数组,长度是原来的数组长度+1;接着遍历原来的数组并存储到新的数组中,遇到3的时候在它后面添加8,最后将剩下的元素添加到8后面即可。

链表

获取结点:
在这里插入图片描述
添加结点:
在这里插入图片描述
特点:由链子链接起来的一堆结点,有头结点和尾结点
优点:增加和删除元素快
缺点:查询慢,只能遍历列表一个个看
在这里插入图片描述

栈和队列

在这里插入图片描述
特点:栈:先进后出(子弹出夹);队列:先进先出。(买火车票进站)
优点:
缺点:

List

定义:List 组件为用户提供了一个可滚动的文本项列表。可设置此 list,使其允许用户进行单项或多项选择。

 * List:* 		有序的(存储和读取的顺序是一致的)* 		有整数索引* 		允许重复的** List的特有功能:* 			void add(int index, E element) 在列表的指定位置插入指定元素* 			E get(int index) 根据索引返回元素* 			E remove(int index) 删除指定元素并返回*  		E set(int index, E element) 将指定索引位置的元素替换为指定元素,并将原先的元素返回
package CollectionDemo;import java.util.ArrayList;
import java.util.List;/** List:* 		有序的(存储和读取的顺序是一致的)* 		有整数索引* 		允许重复的** List的特有功能:* 			void add(int index, E element)* 			E get(int index)* 			E remove(int index) 删除指定元素并返回*  		E set(int index, E element)**   增删改查*/
public class ListDemo {public static void main(String[] args) {List list =new ArrayList();
//        //void add(int index, E element)  : 在列表的指定位置插入指定元素list.add(0,"hello");list.add(0,"c++");list.add(1,"java");System.out.println(list);
//       E get(int index)  :根据索引返回元素/*System.out.println(list.get(0));System.out.println(list.get(1));System.out.println(list.get(2));*/for (int i= 0;i<list.size();i++){System.out.println(list.get(i));}
//       E remove(int index)  : 删除指定元素并返回System.out.println(list.remove(1));System.out.println(list);
//    输出    [c++, hello]
//    E set(int index, E element) : 将指定索引位置的元素替换为指定元素,并将原先的元素返回System.out.println(list.set(0,"and"));System.out.println(list);
//     输出   [and, hello]}
}

LinkedList

在这里插入图片描述
List的常用子类
ArrayList 底层是数组 增删慢,查询快
LinkedList 底层是链表 增删快,查询慢

如何选择使用不同的集合?
如果查询多,增删少,则使用ArrayList
如果查询少,增删多,则使用LinkedList
如果你不知道使用什么,则使用ArrayList
LinkedList的特有功能:
void addFirst(E e)
void addLast(E e)
E getFirst()
E getLast()
E removeFirst()
E removeLast()

package com.demo06;import java.util.LinkedList;*/
public class LinkedListDemo {public static void main(String[] args) {LinkedList<String> list = new LinkedList<String>();list.add("hello");list.add("world");//void addFirst(E e)  :将元素添加到索引为0的位置//void addLast(E e) :将元素添加到索引为size()-1的位置//list.addFirst("java");//list.addLast("android");//E getFirst()  :获取索引为0的元素//E getLast()  :获取索引为size()-1的元素//System.out.println(list.getFirst());//System.out.println(list.getLast());System.out.println(list);//E removeFirst() :删除索引为0的元素并返回//E removeLast() :删除索引为size()-1的元素并返回//System.out.println(list.removeFirst());System.out.println(list.removeLast());System.out.println(list);}
}
package CollectionDemo;import java.util.LinkedList;/*
List的常用子类
ArrayList 底层是数组 增删慢,查询快
LinkedList 底层是链表 增删快,查询慢
如何选择使用不同的集合?如果查询多,增删少,则使用ArrayList如果查询少,增删多,则使用LinkedList如果你不知道使用什么,则使用ArrayListLinkedList的特有功能:void addFirst(E e)void addLast(E e)E getFirst()E getLast()E removeFirst()E removeLast()
*/
public class ListedListDemo {public static void main(String[] args) {LinkedList<String> list = new LinkedList<String>();list.add("hello");list.add("ho");list.addFirst("h");list.addLast("yy");System.out.println(list);
//      运行结果  [h, hello, ho, yy]System.out.println(list.getFirst());    //hSystem.out.println(list.getLast());     //yySystem.out.println(list.removeFirst()); // h删除索引为0的元素并返回System.out.println(list.removeLast());  //yySystem.out.println(list);   //输出[hello, ho]}
}

案例 查找元素索引及判断元素是否存在案例

package com.demo07;import java.util.ArrayList;
import java.util.List;/** 需求:定义一个方法,返回指定列表中指定元素的索引位置* * 判断元素是否存在* */
public class ListTest {public static void main(String[] args) {List list = new ArrayList();list.add("hello");list.add("world");list.add("java");int index = index(list,"python");System.out.println(index);boolean flag = contains(list, "world");System.out.println(flag);	//输出 1boolean flag1 = list.contains("java");System.out.println(flag1);	// 输出true}public static int index(List list,Object other) {for(int x = 0;x < list.size();x++) {//获取列表中的元素Object obj = list.get(x);//使用列表中的元素和指定的元素进行比较if(obj.equals(other)) {return x;}}//查找不到指定的元素return -1;}public static boolean contains(List list,Object other) {//获取指定元素在指定列表中的索引位置int index = index(list,other);//如果索引位置大于等于0,则认为元素存在,否则不存在if(index >= 0) {return true;} else {return false;}}}

练习

1、
分析以下需求,并用代码实现
(1)生成10个1至100之间的随机整数(不能重复),存入一个List集合
(2)然后利用迭代器和增强for循环分别遍历集合元素并输出
(3)如:15 18 20 40 46 60 65 70 75 91
需求分析:
随机生成10个1至100之间的不重复整数,可以通过使用Java的Random类,生成随机数,再判断是否已经存在于集合中,如果存在则重新生成。
存储生成的随机数可以使用Java的List集合,因为它能够按照插入顺序存储元素。
遍历集合元素可以使用Java的迭代器和增强for循环。迭代器是遍历集合的标准方法,它能够对集合中的元素进行读取、删除和修改操作。增强for循环是一种简化版的迭代器,它可以遍历集合中的元素,但不能进行修改和删除操作。
输出集合元素可以使用Java的System.out.println方法,将每个元素输出到控制台。

import java.util.*;public class RandomNumbers {public static void main(String[] args) {List<Integer> numbers = new ArrayList<>();Random rand = new Random();// 生成10个1至100之间的不重复整数while (numbers.size() < 10) {int n = rand.nextInt(100) + 1;if (!numbers.contains(n)) {numbers.add(n);}}// 使用迭代器遍历集合并输出System.out.print("使用迭代器遍历集合:");Iterator<Integer> iterator = numbers.iterator();while (iterator.hasNext()) {int n = iterator.next();System.out.print(n + " ");}System.out.println();// 使用增强for循环遍历集合并输出System.out.print("使用增强for循环遍历集合:");for (int n : numbers) {System.out.print(n + " ");}System.out.println();}
}利用迭代器遍历集合并输出
63 82 15 69 9 87 52 92 93 40 
利用for增强遍历集合并输出
63 82 15 69 9 87 52 92 93 40 

2、
分析以下需求,并用代码实现
(1)定义List集合,存入多个字符串
(2)删除集合元素字符串中包含0-9数字的字符串(只要字符串中包含0-9中的任意一个数字就需要删除此整个字符串)
(3)然后利用迭代器遍历集合元素并输出

package CollectionDemo.Test;import java.util.*;
import java.util.List;
/*分析以下需求,并用代码实现(1)定义List集合,存入多个字符串(2)删除集合元素字符串中包含0-9数字的字符串(只要字符串中包含0-9中的任意一个数字就需要删除此整个字符串)(3)然后利用迭代器遍历集合元素并输出*/
public class Test2 {public static void main(String[] args) {
//        定义List集合,存入多个字符串List<String> list = new ArrayList<>();list.add("abc");list.add("efg");Iterator<String> iterator = list.iterator();while (iterator.hasNext()){String s = iterator.next();
//      (2)删除集合元素字符串中包含0-9数字的字符串(只要字符串中包含0-9中的任意一个数字就需要删除此整个字符串)if (s.matches(".*[0-9].*")){iterator.remove();}}
//        (3)然后利用迭代器遍历集合元素并输出for (String s:list) {System.out.println(s);}}
}
abc
efg

分析以下需求,并用代码实现
(1)定义Person类包含姓名:String name、年龄:int age、成绩:int score,生成空参、有参构造、set和get方法、toString方法
(2)定义Student类继承Person,属性与Person类相同
(3)查看API中ArrayList集合中的以下方法:
(a)boolean add(E e) 方法
(b) T[] toArray(T[] a)方法
(c)boolean addAll(Collection c)方法
(4)通过查看API对以上方法的学习,完成以下功能
a. ArrayList集合中存入5个Student对象,将ArrayList集合转成对应的数组Studentp[],并遍历打印数组中的元素
b. 定义一个存储Person对象的ArrayList集合对象list1,并出入2个Person对象,定义一个存储Student对象的ArrayList集合对象list2,并出入2个Student对象,
调用addAll方法将list2的全部内容添加到list1中,遍历打印list1中的内容

package CollectionDemo.Test;import java.util.ArrayList;/*分析以下需求,并用代码实现(1)定义Person类包含姓名:String name、年龄:int age、成绩:int score,生成空参、有参构造、set和get方法、toString方法(2)定义Student类继承Person,属性与Person类相同(3)查看API中ArrayList集合中的以下方法:(a)boolean add(E e) 方法(b) T[] toArray(T[] a)方法(c)boolean addAll(Collection c)方法(4)通过查看API对以上方法的学习,完成以下功能a. ArrayList集合中存入5个Student对象,将ArrayList集合转成对应的数组Studentp[],并遍历打印数组中的元素b. 定义一个存储Person对象的ArrayList集合对象list1,并出入2个Person对象,定义一个存储Student对象的ArrayList集合对象list2,并出入2个Student对象,调用addAll方法将list2的全部内容添加到list1中,遍历打印list1中的内容*/
public class Test3 {public static void main(String[] args) {// a. ArrayList集合中存入5个Student对象,将ArrayList集合转成对应的数组Studentp[],并遍历打印数组中的元素ArrayList<Person.Student> arrayList = new ArrayList<Person.Student>();arrayList.add(new Person.Student("小结",16,79));arrayList.add(new Person.Student("小结2",13,45));//b. 定义一个存储Person对象的ArrayList集合对象list1,并出入2个Person对象,定义一个存储Student对象的ArrayList集合对象  Person.Student[] stu = arrayList.toArray(new Person.Student[arrayList.size()]);for (Person.Student st:stu) {System.out.println(st);}}
}
//(1)定义Person类包含姓名:String name、年龄:int age、成绩:int score,生成空参、有参构造、set和get方法、toString方法
class Person{String name;int age;int score;
//    空参构造public Person() {}//    有参构造public Person(String name, int age, int score) {this.name = name;this.age = age;this.score = score;}
//set和get方法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 int getScore() {return score;}public void setScore(int score) {this.score = score;}public String toString(){return "Person{"+"name="+name+'\''+",age="+age+",score="+score+"}";}//    (2)定义Student类继承Person,属性与Person类相同static class Student extends Person{public Student(String name, int age, int score) {super(name, age, score);}
}
}

4.现在已知Cloth ,衣物都有颜色,价格,牌子;
已知裤子是衣物的一种,裤子有裤袋;
已知袜子也是一种,袜子有个洞;
已知衬衣也是衣服的一种,衬衣有扣子;
已知鞋子也是衣物,鞋子有鞋带
已知人这个类, 人类有姓名,性别, 可以穿衣服;

要求: 定义一个衣柜(衣柜不用创建对象, 里面放置一套衣服);
创建人对象,然后实现穿一套衣服的过程;

package CollectionDemo.Test;
/*现在已知Cloth ,衣物都有颜色,价格,牌子;已知裤子是衣物的一种,裤子有裤袋;已知袜子也是一种,袜子有个洞;已知衬衣也是衣服的一种,衬衣有扣子;已知鞋子也是衣物,鞋子有鞋带已知人这个类, 人类有姓名,性别, 可以穿衣服;要求: 定义一个衣柜(衣柜不用创建对象, 里面放置一套衣服);创建人对象,然后实现穿一套衣服的过程;*/
public class Test4 {public static void main(String[] args) {Person1 person1 = new Person1();person1.name="Mary";person1.gender = "female";Wardrobe wardrobe = new Wardrobe();person1.wear(wardrobe.pants);person1.wear(wardrobe.socks);person1.wear(wardrobe.shirt);person1.wear(wardrobe.shoes);}
}
class Cloth{String color;double price;String brand;
}
class Pants extends Cloth{boolean hasPocket;  //有口袋
}
class Socks extends Cloth{boolean hasHole;
}
class Shirt extends Cloth{boolean hasButton;
}
class Shoes extends Cloth{boolean hasLaces;
}
class Person1 {String name;String gender;void wear(Cloth cloth) {System.out.println(name + " is wearing " + cloth.brand + " " + cloth.getClass().getSimpleName() + ".");}
}
class Wardrobe{Pants pants = new Pants();Socks socks = new Socks();Shirt shirt =new Shirt();Shoes shoes = new Shoes();Wardrobe(){pants.color="blue";pants.price=36.88;pants.brand="LOV";pants.hasPocket=true;socks.color = "white";socks.price = 4.99;socks.brand = "Hanes";socks.hasHole = true;shirt.color = "pink";shirt.price = 39.99;shirt.brand = "Ralph Lauren";shirt.hasButton = true;shoes.color = "black";shoes.price = 79.99;shoes.brand = "Nike";shoes.hasLaces = true;}
}
Mary is wearing LOV Pants.
Mary is wearing Hanes Socks.
Mary is wearing Ralph Lauren Shirt.
Mary is wearing Nike Shoes.

键盘录入若干个字符串,将字符串存入泛型为String的集合当中, 知道输入quit的时候不用输入;
1.集合中含有字符a的元素有多少个
2.将集合中第三个元素中"a"全部替换成"b";
3.删掉长度为3的元素;
4.遍历集合;

package CollectionDemo.Test;import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;/*键盘录入若干个字符串,将字符串存入泛型为String的集合当中, 直到输入quit的时候不用输入;1.集合中含有字符a的元素有多少个2.将集合中第三个元素中"a"全部替换成"b";3.删掉长度为3的元素;4.遍历集合;*/
public class Test5 {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);ArrayList<String> stringList = new ArrayList<>(); // 创建泛型为String的ArrayListSystem.out.println("请输入字符串(输入quit结束输入):");// 用循环读取用户输入的字符串并存入ArrayList,直到输入"quit"为止while (true) {String input = scanner.nextLine();if (input.equals("quit")) {break;} else {stringList.add(input);}}// 打印集合中含有字符a的元素数量int count = 0;for (String str : stringList) {if (str.contains("a")) {count++;}}System.out.println("集合中含有字符a的元素数量为:" + count);// 将集合中第三个元素中"a"全部替换成"b"if (stringList.size() >= 3) { // 确保集合中至少有3个元素String thirdElement = stringList.get(2);stringList.set(2, thirdElement.replace("a", "b"));}// 删除长度为3的元素stringList.removeIf(str -> str.length() == 3);// 遍历集合并打印每个元素System.out.println("遍历集合:");for (String str : stringList) {System.out.println(str);}}
}请输入字符串(输入quit结束输入):
sdha 
jkhg
ghsa
quit
集合中含有字符a的元素数量为:2
遍历集合:
sdha 
jkhg
ghsb

第十八章 Set与Map集合

Set

  • 定义
    在Java中,Set是一种集合类型,它继承自Collection接口,用于存储不重复的元素。Set接口的定义如下:
public interface Set<E> extends Collection<E> {// 声明Set特有的方法
}

常用的Set实现类有HashSet、TreeSet和LinkedHashSet。
需要注意的是,Set接口是一个抽象接口,不能直接实例化。需要使用Set接口的实现类来创建Set对象。

  • 特点
    • 无序
    • 不重复
    • 没有整数索引
      在这里插入图片描述
  • 方法
    add() toArray()
    在这里插入图片描述

增强for循环

增强for循环语法(也称为for-each循环)是Java中用于遍历数组或集合的简化循环语法。其语法形式如下:

for (elementType element : collection) {// 循环体
}

其中:
elementType 是集合中元素的类型,也可以是数组的元素类型。
element 是循环变量,用于在每次循环迭代中代表集合中的一个元素。
collection 是要遍历的集合或数组。
增强for循环的工作原理是自动迭代集合或数组,并将每个元素依次赋值给循环变量,然后执行循环体中的代码。循环将在集合或数组中的每个元素上执行一次,直到所有元素都被遍历完为止。
需要注意的是,增强for循环只能用于遍历集合或数组,无法用于遍历其他数据结构或自定义对象。
使用HashSet存储字符串并遍历

package mySet;import java.util.HashSet;
import java.util.Set;/*使用HashSet存储字符串并遍历**	Set的特点:*			 无序(存储和读取的顺序可能不一样)*			不允许重复*			没有整数索引*/
public class hashSetDemo1 {public static void main(String[] args) {
//        创建集合Set<String> set = new HashSet<>();    //必须要是泛型的
//        添加元素set.add("hello");set.add("world");set.add(null);System.out.println(set.add("java"));System.out.println(set.add("java"));    //不允许有重复的元素,所以值输出一个java
//        遍历元素for(String s : set){System.out.println(s);}}
}
输出
true
false
null
world
java
hello

为啥输出了true和false?
这段代码输出了"true"和"false",以及集合中的元素。

首先,让我们逐行分析代码的执行:

创建HashSet对象并将其赋值给set变量:Set set = new HashSet<>();

创建一个名为set的HashSet集合,其中存储的元素类型为String。
添加元素到集合中:

set.add(“hello”);:向集合中添加字符串"hello"。
set.add(“world”);:向集合中添加字符串"world"。
set.add(null);:向集合中添加一个null元素。
System.out.println(set.add(“java”));:向集合中添加字符串"java",并输出add方法的返回值。因为集合中原本没有"java"这个元素,所以添加成功,返回true,因此输出为"true"。
System.out.println(set.add(“java”));:再次向集合中添加字符串"java",并输出add方法的返回值。因为集合中已经存在"java"这个元素,添加失败,返回false,因此输出为"false"。

遍历集合中的元素:

使用增强for循环遍历集合中的元素。
for(String s : set){…}:对于集合中的每个元素,将其赋值给变量s,并执行循环体中的代码。
循环体中的代码System.out.println(s);将每个元素打印到控制台。

hashSet

  • 定义
    HashSet实现了Set接口,并且还继承了AbstractSet类,同时也实现了Cloneable接口和Serializable接口。它使用哈希表来存储元素,并且允许存储null元素(只能存储一个)。
    在这里插入图片描述

  • 特点

    • 不允许重复元素:HashSet中不会包含重复的元素。当向HashSet中添加元素时,会先通过元素的hashCode()方法计算哈希值,然后根据哈希值确定元素在内部存储结构中的位置。如果发现该位置已经存在元素,则进行比较,如果元素已经存在,则不会添加;如果元素不存在,则将其添加到该位置。
    • 无序性:HashSet中的元素没有特定的顺序。HashSet不会保持元素的插入顺序,也不会按照元素的排序顺序存储。
    • 高效的查找和插入操作:HashSet基于哈希表实现,因此查找和插入操作的性能非常高效,具有常数时间复杂度O(1)。
      可以存储null元素:HashSet可以存储一个null元素,但不能存储多个null元素,因为HashSet要求元素唯一。
    • 不是线程安全的:HashSet不是线程安全的,如果多个线程同时访问一个HashSet并且至少有一个线程修改了集合,则必须进行外部同步。
      遍历性能较好:由于HashSet使用哈希表实现,遍历HashSet的性能较好。
      注意:由于HashSet使用哈希表实现,元素的顺序是根据哈希值决定的,因此无法保证HashSet的元素顺序是固定的。如果需要有序的集合,可以使用LinkedHashSet,它在HashSet的基础上使用了链表来维护元素的插入顺序。
  • add()
    HashSet的add()方法,首先会使用当前集合中的每一个元素和新添加的元素进行hash值比较,
    如果hash值不一样,则直接添加新的元素
    如果hash值一样,比较地址值或者使用equals方法进行比较
    比较结果一样,则认为是重复不添加
    所有的比较结果都不一样则添加

  • 方法
    在这里插入图片描述

方法重载与重写

方法重写与方法重载区别
方法重写@override 在子类当中,子类和父类的方法完全一样,子类覆盖了父类的方法,重写之后,使用子类对象调用的就是子类的方法。
方法重载@overload 在一个类中有多个重名方法,但是方法参数不同(参数类型、数目,顺序),和返回值无关。

使用HashSet存储自定义对象并遍历

package mySet;import java.util.HashSet;/**	使用HashSet存储自定义对象并遍历**	HashSet的add()方法,首先会使用当前集合中的每一个元素和新添加的元素进行hash值比较,*	如果hash值不一样,则直接添加新的元素*	如果hash值一样,比较地址值或者使用equals方法进行比较*	比较结果一样,则认为是重复不添加*	所有的比较结果都不一样则添加*/
public class hashSetDemo2 {public static void main(String[] args) {
//    创建集合对象HashSet<Student> hashSet = new HashSet<Student>();
//        创建元素对象Student s = new Student("张三",18);Student s2 = new Student("lisi",18);Student s3 = new Student("lisi",18);
//        添加元素hashSet.add(s);hashSet.add(s2);hashSet.add(s3);
//        遍历集合对象 自定义的类for (Student student:hashSet) {System.out.println(student);}}
}class Student {String name;int age;public Student(String name,int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}@Overridepublic boolean equals(Object obj) {System.out.println("-------------------");Student s = (Student)obj;//向下转型,可以获取子类特有成员//比较年龄是否相等,如果不等则返回falseif(this.age != s.age) {return false;}//比较姓名是否相等,如果不等则返回falseif(!this.name.equals(s.name)) {return false;}//默认返回true,说明两个学生是相等的return true;}@Overridepublic int hashCode() {return 1;}
}

hashCode方法和equals方法的优化

我们发现当hashCode方法永远返回整数1时,所有对象的hash值都是一样的, 有一些对象的成员变量完全不同,但是它们还需要进行hash和equals方法的比较,如果我们可以让成员变量不同的对象,它们的hash值也不同,这就可以减少一部分equals方法的比较从而可以提高我们程序的效率

	  可以尝试着让hashCode方法的返回值和对象的成员变量有关可以让hashCode方法返回所有成员变量之和,让基本数据类型直接相加,然后引用数据类型获取hashCode方法返回值后再相加(boolean不可以参与运算)

package mySet;import java.util.HashSet;public class HashSetDemo3 {public static void main(String[] args) {//创建集合对象HashSet<Person> hs = new HashSet<Person>();//创建元素对象Person p = new Person("zhangsan",18);Person p2 = new Person("lisi",21);Person p3 = new Person("lisi",20);//添加元素对象hs.add(p);hs.add(p2);hs.add(p3);//遍历集合对象for (Person person : hs) {System.out.println(person);}}
}

Person.java

package com.demo02;public class Person {String name;int age;public Person(String name,int age) {this.name = name;this.age = age;}
//自动生成的方法重写@Overridepublic String toString() {return "Person [name=" + name + ", age=" + age + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Person other = (Person) obj;if (age != other.age)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}/*	自己写的@Overridepublic int hashCode() {	 //return age;return age + name.hashCode();}@Overridepublic boolean equals(Object obj) {System.out.println("-------------");//提高效率if(this == obj) {return true;}//提高健壮性if(this.getClass() != obj.getClass()) {return false;}//向下转型Person p = (Person)obj;if(!this.name.equals(p.name)) {return false;}if(this.age != p.age) {return false;}return true;}*/}

Collection

定义

Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为 collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何直接 实现:它提供更具体的子接口(如 Set 和 List)实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。
Collections:

Collection和Collections有什么区别?

面试题:Collection和Collections有什么区别?

Collection是集合体系的最顶层,包含了集合体系的共性
Collections是一个工具类,方法都是用于操作Collection
在这里插入图片描述

  • Collection
    在这里插入图片描述

collection方法

在这里插入图片描述

  • static void swap(List list, int i, int j) :将指定列表中的两个索引进行位置互换
  • static int binarySearch(List list, Object key) 使用二分查找法查找指定元素在指定列表的索引位置 1 2 3 4 5 6 7
  • static void copy(List dest, List src) :是把源列表中的数据覆盖到目标列表
    注意:目标列表的长度至少等于源列表的长度
  • static void fill(List list, Object obj) :使用指定的对象填充指定列表的所有元素
  • static void reverse(List list) :反转
  • static void sort(List list) :按照列表中元素的自然顺序进行排序
public class CollectionsDemo {public static void main(String[] args) {method7();}private static void method7() {//static void swap(List list, int i, int j) :将指定列表中的两个索引进行位置互换List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(7);list.add(0);list.add(-1);System.out.println(list);Collections.swap(list, 2, 5);System.out.println(list);}private static void method() {//static int  binarySearch(List list, Object key) 使用二分查找法查找指定元素在指定列表的索引位置 1 2 3 4 5 6 7List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);list.add(4);list.add(5);list.add(6);list.add(7);int index = Collections.binarySearch(list, 4);System.out.println(index);}private static void method2() {//static void copy(List dest, List src) :是把源列表中的数据覆盖到目标列表//注意:目标列表的长度至少等于源列表的长度//创建源列表List<String> src = new ArrayList<String>();src.add("hello");src.add("world");src.add("java");//创建目标列表List<String> dest = new ArrayList<String>();dest.add("java");dest.add("java");//dest.add("java");//dest.add("java");Collections.copy(dest, src);System.out.println(dest);}private static void method3() {//static void fill(List list, Object obj) :使用指定的对象填充指定列表的所有元素List<String> list = new ArrayList<String>();list.add("hello");list.add("world");list.add("java");System.out.println(list);Collections.fill(list, "android");System.out.println(list);}private static void method4() {//static void reverse(List list)  :反转List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);list.add(4);System.out.println(list);Collections.reverse(list);System.out.println(list);}private static void method5() {//static void shuffle(List list):傻否,随机置换  List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);list.add(4);System.out.println(list);Collections.shuffle(list);System.out.println(list);}private static void method6() {//static void  sort(List list) :按照列表中元素的自然顺序进行排序List<Integer> list = new ArrayList<Integer>();list.add(1);list.add(4);list.add(3);list.add(2);System.out.println(list);Collections.sort(list);System.out.println(list);}	
}
输出:
[1, 2, 3, 4, 7, 0, -1]
[1, 2, 0, 4, 7, 3, -1]

Collection练习 模拟斗地主

package com.demo03;import java.util.ArrayList;
import java.util.Collections;/**	模拟斗地主发牌 买牌洗牌发牌*/
public class CollectionsTest {public static void main(String[] args) {//String[] box0 = {"黑桃A","黑桃2"...}//买牌String[] arr = { "黑桃", "红桃", "方片", "梅花" };String[] arr2 = { "A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K" };ArrayList<String> box = new ArrayList<String>();//添加每张牌for (int i = 0; i < arr.length; i++) {//获取每一个花色for (int j = 0; j < arr2.length; j++) {//获取每一个数box.add(arr[i] + arr2[j]);}}box.add("大王");box.add("小王");System.out.println(box.size());System.out.println(box);//洗牌Collections.shuffle(box);System.out.println(box);//发牌ArrayList<String> 林志玲 = new ArrayList<String>();ArrayList<String> 林心如 = new ArrayList<String>();ArrayList<String> 舒淇 = new ArrayList<String>();//留三张底牌给地主for (int i = 0; i < box.size() - 3; i++) {/*	   i = 0;i % 3 = 0;i = 1;i % 3 = 1;i = 2;i % 3 = 2;i = 3;i % 3 = 0;i = 4;i % 4 = 1;i = 5;i % 5 = 2;*/if(i % 3 == 0) {林志玲.add(box.get(i));}else if(i % 3 == 1) {林心如.add(box.get(i));}else if(i % 3 == 2) {舒淇.add(box.get(i));}}System.out.println("林志玲:" + 林志玲);System.out.println("林心如:" + 林心如);System.out.println("舒淇:" + 舒淇);System.out.println("底牌:");/*System.out.println(box.get(box.size() - 1));System.out.println(box.get(box.size() - 2));System.out.println(box.get(box.size() - 3));*/for (int i = box.size() - 3; i < box.size(); i++) {System.out.println(box.get(i));}}}
54
[黑桃A, 黑桃2, 黑桃3, 黑桃4, 黑桃5, 黑桃6, 黑桃7, 黑桃8, 黑桃9, 黑桃10, 黑桃J, 黑桃Q, 黑桃K, 方块A, 方块2, 方块3, 方块4, 方块5, 方块6, 方块7, 方块8, 方块9, 方块10, 方块J, 方块Q, 方块K, 红桃A, 红桃2, 红桃3, 红桃4, 红桃5, 红桃6, 红桃7, 红桃8, 红桃9, 红桃10, 红桃J, 红桃Q, 红桃K, 梅花A, 梅花2, 梅花3, 梅花4, 梅花5, 梅花6, 梅花7, 梅花8, 梅花9, 梅花10, 梅花J, 梅花Q, 梅花K, 大王, 小王]
[红桃7, 梅花J, 梅花4, 黑桃4, 大王, 方块2, 梅花2, 黑桃6, 方块7, 方块3, 方块Q, 黑桃A, 黑桃3, 梅花8, 红桃8, 红桃10, 梅花10, 黑桃10, 红桃A, 红桃K, 黑桃9, 方块A, 梅花Q, 梅花5, 红桃6, 黑桃7, 梅花A, 红桃5, 红桃4, 红桃2, 方块4, 方块10, 方块8, 方块K, 黑桃5, 方块6, 方块J, 红桃Q, 梅花6, 红桃J, 黑桃J, 红桃3, 方块9, 梅花7, 方块5, 黑桃K, 梅花K, 红桃9, 小王, 黑桃Q, 黑桃8, 黑桃2, 梅花9, 梅花3]
林志玲[红桃7, 黑桃4, 梅花2, 方块3, 黑桃3, 红桃10, 红桃A, 方块A, 红桃6, 红桃5, 方块4, 方块K, 方块J, 红桃J, 方块9, 黑桃K, 小王]
林心如[梅花J, 大王, 黑桃6, 方块Q, 梅花8, 梅花10, 红桃K, 梅花Q, 黑桃7, 红桃4, 方块10, 黑桃5, 红桃Q, 黑桃J, 梅花7, 梅花K, 黑桃Q]
舒淇[梅花4, 方块2, 方块7, 黑桃A, 红桃8, 黑桃10, 黑桃9, 梅花5, 梅花A, 红桃2, 方块8, 方块6, 梅花6, 红桃3, 方块5, 红桃9, 黑桃8]
底牌:
黑桃2
梅花9
梅花3

Map

需求:实现学号和姓名这样有对应关系的数据存储

  • 为了体现这种有对应关系的数据,我们使用以前所学的内容是可以实现的,但是略有不便,所以java又给我们提供了一种专门用于存储对应关系的集合。
    Map:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值

Map和Collection有什么区别?

Map:是一个双列集合,常用语处理有对应关系的数据,key是不可以重复的,我们也称之为是夫妻对集合
Collection:是单列集合,Collection有不同的子体系,有的允许重复有索引有序,有的不允许重复而且无序,那么我们也称之为单身汉集合
一对一:一个学号对应一个姓名。
定义:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。

map常用功能

映射功能:
V put(K key, V value)
获取功能:
V get(Object key)
int size()
判断功能:
boolean containsKey(Object key)
boolean containsValue(Object value)
boolean isEmpty()
删除功能:
void clear()
V remove(Object key)
遍历功能:
Set> entrySet()

  •  	Set keySet()  
    
  •  	Collection values()  
    
public class MapDemo2 {public static void main(String[] args) {//创建Map对象Map<String,String> map = new HashMap<String,String>();//V put(K key, V value) :就是将key映射到value,如果key存在,则覆盖value,并将原来的value返回System.out.println(map);System.out.println(map.put("s001", "张三"));System.out.println(map.put("s002", "李四"));System.out.println(map.put("s001", "王五"));//System.out.println(map.put("s001", null));System.out.println(map);//V get(Object key) : 根据指定的key返回对应的value//System.out.println(map.get("s002"));//System.out.println(map.get("s002sdf"));//int size() : 返回对应关系的个数//System.out.println(map.size());//boolean containsKey(Object key) : 判断指定key是否存在//System.out.println(map.containsKey("s003"));//System.out.println(map.containsKey("s002"));//boolean containsValue(Object value):判断指定的value是否存在//System.out.println(map.containsValue("王五"));//System.out.println(map.containsValue("王"));//void clear() : 清空所有的对应关系  //map.clear();//System.out.println(map);//V remove(Object key) :根据指定的key删除对应关系,并返回key所对应的值,如果没有删除成功则返回nullSystem.out.println(map.remove("s005"));System.out.println(map.remove("s002"));System.out.println(map);//boolean isEmpty() : 判断是否有对应关系System.out.println(map.isEmpty());map.clear();System.out.println(map);System.out.println(map.isEmpty());}
}

Set keySet() 获取map的键,Collection values() 获取map的值

/** 	Set keySet()  * 	Collection values() */
public class MapDemo3 {public static void main(String[] args) {//创建Map对象Map<String,String> map = new HashMap<String,String>();//添加映射关系map.put("s001", "张三");map.put("s002", "李四");map.put("s005", "李四");//Set keySet() : 以Set的形式获返回所有的keySet<String> keys = map.keySet();for (String key : keys) {System.out.println(key);}System.out.println("-----------");//Collection values() :Collection<String> values = map.values();for (String value : values) {System.out.println(value);}}
}s005
s002
s001
-----------
李四
李四
张三

map的两种遍历方式

  • map的第一种遍历方式
    首先召集所有的键(丈夫):
Set<String> keys = map.keySet();

遍历所有的键(丈夫):

for (String key : keys) {//让每个丈夫去找他自己的媳妇就可以了String value = map.get(key);System.out.println("丈夫:" + key + "---" + "媳妇:" + value);
}			

获取每一个键(丈夫)
让每一个键(丈夫)去找他自己的值(媳妇)

/** 	Map的第一种遍历方式:* 			首先召集所有的丈夫* 			遍历所有的丈夫* 			获取每一个丈夫* 			让每一个丈夫去找他自己的媳妇*/
public class MapDemo4 {public static void main(String[] args) {//创建Map对象Map<String,String> map = new HashMap<String,String>();//添加映射关系map.put("谢婷疯", "张箔纸");map.put("陈关西", "钟欣桶");map.put("李亚碰", "王飞");//遍历Map对象//首先召集所有的丈夫Set<String> keys = map.keySet();//遍历所有的丈夫for (String key : keys) {//让每个丈夫去找他自己的媳妇就可以了String value = map.get(key);System.out.println("丈夫:" + key + "---" + "媳妇:" + value);}}
}

Map的第二种遍历方式

通过结婚证对象来获取丈夫和媳妇

for (Map.Entry<String, String> entry : entrys) {//获取每个单独的结婚证对象//通过结婚证对象获取丈夫和媳妇String key = entry.getKey();String value = entry.getValue();	System.out.println("丈夫:" + key + "---" + "媳妇:" + value);}
 Set<Map.Entry<K,V>> entrySet()  
/** 	Map的第二种遍历方式:* 		通过结婚证对象来获取丈夫和媳妇*  Set> entrySet()  * */
public class MapDemo5 {public static void main(String[] args) {//创建Map对象Map<String,String> map = new HashMap<String,String>();//添加映射关系map.put("尹志平", "小龙女");map.put("令狐冲", "东方姑娘");map.put("玄慈", "叶二娘");//获取所有的结婚证对象Set<Map.Entry<String,String>> entrys = map.entrySet();//遍历包含了结婚证对象的集合for (Map.Entry<String, String> entry : entrys) {//获取每个单独的结婚证对象//通过结婚证对象获取丈夫和媳妇String key = entry.getKey();String value = entry.getValue();System.out.println("丈夫:" + key + "---" + "媳妇:" + value);}}
}

使用HashMap存储数据并遍历(字符串作为key)

package com.demo02;import java.util.HashMap;
import java.util.Map;
import java.util.Set;/** * 使用HashMap存储数据并遍历(字符串作为key)* */
public class HashMapDemo {public static void main(String[] args) {//创建Map对象HashMap<String,String> hm = new HashMap<String,String>();//添加映射关系hm.put("s001", "张三");hm.put("s002", "李四");hm.put("s003", "王五");hm.put("s003", "赵六");//遍历Map对象//方式1 获取所有的key,通过key来获取valueSet<String> keys = hm.keySet();for (String key : keys) {String value = hm.get(key);System.out.println(key + "=" + value);}System.out.println("------------------");//方式2:获取所有的结婚证对象,然后通过结婚证对象获取丈夫和媳妇Set<Map.Entry<String, String>> entrys = hm.entrySet();for (Map.Entry<String, String> entry : entrys) {String key = entry.getKey();String value = entry.getValue();System.out.println(key + "=" + value);}}
}

使用HashMap存储数据并遍历(自定义对象作为key)

package com.demo02;import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;/** * 使用HashMap存储数据并遍历(自定义对象作为key)* */
public class HashMapDemo2 {public static void main(String[] args) {//创建Map对象HashMap<Student,String> hm = new HashMap<Student,String>();//创建key对象Student s = new Student("zhangsan",18);Student s2 = new Student("lisi",20);Student s3 = new Student("lisi",20);//添加映射关系hm.put(s, "s001");hm.put(s2, "s002");hm.put(s3, "s002");//遍历Map对象//方式1: 获取所有的key,通过key来获取valueSet<Student> keys = hm.keySet();for (Student key : keys) {String value = hm.get(key);System.out.println(key + "=" + value);}System.out.println("-----");//方式2:获取所有结婚证对象,通过结婚证对象获取丈夫和媳妇Set<Map.Entry<Student, String>> entrys = hm.entrySet();for (Entry<Student, String> entry : entrys) {Student key = entry.getKey();String value = entry.getValue();System.out.println(key + "=" + value);}}
}

Student类

package com.demo02;public class Student {String name;int age;public Student(String name,int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student [name=" + name + ", age=" + age + "]";}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + age;result = prime * result + ((name == null) ? 0 : name.hashCode());return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Student other = (Student) obj;if (age != other.age)return false;if (name == null) {if (other.name != null)return false;} else if (!name.equals(other.name))return false;return true;}	
}

异常的处理

异常的概述和体系结构.

  • Exception in thread “main” java.lang.ArithmeticException: / by zero
    at com.demo01.ExceptionDemo.main(ExceptionDemo.java:5)
    我们在写代码的时候,经常的出现一些小问题,那么为了方便我们处理这些问题,java为我们提供了异常机制
    异常包含了错误的类型、原因以及位置

    异常:不正常,我们在代码的时候出现的编译或者运行时的错误

    异常的体系结构:
    Throwable(最顶层)
    Error:出现的不能够处理的严重问题
    Exception:可以处理的问题

    电脑坏了:
    系统中毒:重装系统就可以了 这是Exception
    主板坏了:买一台新的 这是Error

什么是异常?举例子:

public class exceptionDemo {public static void main(String[] args) {int a = 10 / 0;System.out.println(a);}
}

输出:出现异常
Exception in thread “main” java.lang.ArithmeticException: / by zero
at ExceptionDemo.exceptionDemo.main(exceptionDemo.java:5)
在这里插入图片描述
Throwable
在这里插入图片描述

JVM处理异常的方式

1.捕获处理
try…catch语句

try…catch的执行顺序:
首先执行try语句如果发现异常,异常下面的代码不再执行,直接跳入catch语句中,catch语句结束后,整个try…catch结束
如果没有发现异常,try语句执行结束后,try…catch直接结束, 不再执行catch语句

 try{有可能出现问题的代码;}catch(ArithmeticException ae){处理异常;}

2.抛出去
当我们不想处理异常,或者没有能力处理的时候,我们可以选择抛出异常,谁调用方法谁处理异常
使用关键字throws在方法的声明出抛出异常

jvm处理异常的方式:
如果出现异常我们没有处理,jvm会帮我们进行处理,它会把异常的类型,原因还有位置显示在命令行,并且还终止了程序,异常后面的代码将不在执行。

public class ExceptionDemo2 {public static void main(String[] args) throws Exception {/*try {System.out.println("执行前");int a = 10 / 2;System.out.println("执行后");System.out.println(a);}catch(ArithmeticException e) {System.out.println("不能除0");}System.out.println("执行完问题语句后");*/try {readFile();}catch(FileNotFoundException e) {System.out.println("没有发现文件");}}public static void readFile() throws FileNotFoundException {FileReader fr = new FileReader("d:\\a.txt");}
}

如何处理多个异常

可以使用多个try…catch语句
使用一个try和多个catch
多个catch之间的顺序:
多个catch之间可以有子父类
平级之间没有顺序关系
如果有子父类,父类异常必须放在后面

public class ExceptionDemo3 {public static void main(String[] args) {try {String s = "1";System.out.println(s.length());int[] arr = new int[5];System.out.println(arr[4]);int i = 10;System.out.println(i/0);} catch (ArrayIndexOutOfBoundsException e) {System.out.println("数组越界异常");} catch (NullPointerException e) {System.out.println("空指针异常");} catch (Exception e) {System.out.println("异常");}}}

Throwable的常用方法

Throwable的常用方法:

  • String getMessage() 原因
  • String toString() 类型和原因
  • void printStackTrace() 类型原因和位置
public class exceptionDemo2 {public static void main(String[] args) {try{System.out.println(2 / 0);}catch (ArithmeticException e){
//            String getMessage():原因System.out.println(e.getMessage());
//          String toString()类型和原因System.out.println(e.toString());
//            void printStackTrace():类型原因和位置e.printStackTrace();}}
}

在这里插入图片描述

finally概述和应用场景

finally:组合try…catch使用,用于释放资源等收尾工作,无论try…catch语句如何执行,finally的代码一定会执行。

try{有可能出现问题的代码;
}catch(异常对象){处理异常;
}finally{释放资源;清理垃圾;
}
package ExceptionDemo;import java.io.FileWriter;
import java.io.IOException;public class finallyDemo {public static void main(String[] args) {FileWriter fileWriter = null;try{fileWriter = new FileWriter("a.txt");fileWriter.write("你好");System.out.println(2/0);fileWriter.write("我在学java");} catch (IOException e) {e.printStackTrace();}finally {try{fileWriter.close();}catch (IOException e){e.printStackTrace();}}}
}

输出:Exception in thread “main” java.lang.ArithmeticException: / by zero
at ExceptionDemo.finallyDemo.main(finallyDemo.java:12)

异常的分类

异常的分类:
运行时期异常:RuntimeException的子类就是运行时期异常,在编译时期可以自由选择处理或者不处理。RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。例如:ArithmeticException(当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。 )
编译时期异常:是Exception的子类,非RuntimeExcpetion的子类,在编译时期必须处理
在这里插入图片描述
举例子:

public class exceptionClassification {public static void main(String[] args) throws IOException {/* System.out.println(2 / 0);String s = null;System.out.println(s.length());运行时异常 输出 ArithmeticException*/FileWriter fw = new FileWriter("a.txt");    //编译异常,在编译的时候必须处理,处理方式就是抛出异常}
}

自定义异常

自定义异常的方法:写一个类去继承Exception或者RuntimeException,然后实现多个构造即可
1.先自定义异常:写一个类去继承Exception或者RuntimeException

package ExceptionDemo;public class MyException extends RuntimeException{private static final long serialVersionUID = 1L;public MyException(){super();}public MyException(String s){super(s);System.out.println("自定义异常");}
}

2.实现多个构造

package ExceptionDemo;public class exceptionDemo3 {public static void main(String[] args) {checkScore(110);}public static void checkScore(int score) throws MyException{if(score < 0 || score > 0){throw new MyException("考试不符合要求");}System.out.println("符合要求");}
}

输出:
自定义异常
Exception in thread “main” ExceptionDemo.MyException: 考试不符合要求
at ExceptionDemo.exceptionDemo3.checkScore(exceptionDemo3.java:9)
at ExceptionDemo.exceptionDemo3.main(exceptionDemo3.java:5)

递归概述和例题

递归:把大问题拆成很多小问题,然后再把小问题拆成更多的小问题,
当我们把更多小问题解决了,小问题也解决了
随着小问题的解决,大问题也随之解决了
在方法本身不断的调用方法自己

递归注意事项:==递归一定要有出口,内存溢出====递归次数不宜过多,内存溢出==
package Recurrence;
/** 需求:求5的阶乘* 5! = 5 * 4 * 3 * 2 * 1;  //120* 5! = 5 * 4!;					//120* 		4! = 4 * 3!;			//24* 			3! = 3 * 2!;		//6* 				2! = 2 * 1!;	//2* 					1! = 1;     //1n! = n * (n - 1)!*/
public class recurrenceDemo1 {public static void main(String[] args) {int n = method(5);System.out.println(n);}public static int method(int n){if(n == 0){ //出口return 1;}else{return n * method(n-1);}}
}

斐波那契数列:

package Recurrence;
/** 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,* 		     小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,*  	     问第二十个月的兔子对数为多少?*  1*  1*  2*  3*  5*  8*  13*  规律:除了第一个月和第二月以外,其余每个月都是前两个月之和*  斐波那契列数**/
public class recurrentDemo2 {public static void main(String[] args) {int m = method(20);System.out.println(m);}public static int method(int n){if(n == 1){return 1;}else if(n==2){return 1;}else{return method(n-1)+method(n-2);}}
}

练习:手动实现FileWriter的try catch异常处理形式的完整模式

package ExceptionDemo;import java.io.FileWriter;
import java.io.IOException;/*手动实现FileWriter的try catch异常处理形式的完整模式*/
public class exceptionTest {public static void main(String[] args) throws IOException {demo();}private static void demo(){FileWriter fileWriter = null;try{fileWriter = new FileWriter("E://a.txt");fileWriter.write("小猫");fileWriter.write("小狗");}catch(Exception e){System.out.println("出现异常");e.printStackTrace();}finally {try {if(fileWriter!=null){fileWriter.close();}}catch(IOException el){el.printStackTrace();}}}public static int get(){try{return 520;}finally {System.out.println("发生异常");}}
}


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部