java基础11【异常、集合、迭代器、泛型、Map、断言】

    xiaoxiao2022-06-30  101

    文章目录

    异常集合set集合排序迭代器泛型Map

    java基础11

    异常

    如果在主函数上抛出异常,表示将这个异常抛给了Java虚拟机,JVM默认打印异常的栈轨迹异常对方法的重载没有影响在try执行完前,无论出现了异常与否,finally都会执行一次。在try-catch出现的情况下,JVM在编译的时候认为try不一定能够执行成功,就意味着try中不一定能够正 常返回结果异常是Java中一套用于问题的反馈和处理的机制Throwable — 异常的顶级父类Error — 错误表示合理(语法上还是逻辑上都是成立的)的应用程序中出现了严重的问题,而且这个问题不应该试图捕获 —意味着在程序中,错误一旦出现不能处理 — VirtualMachineError : StackOverflowError, OutOfMemoryErrorException — 表示合理的应用程序想要捕获的问题,也因此可以处理。处理方式:要么捕获要么抛出编译时异常:在编译时期就已经出现,要求必须处理。CloneNotSupportedException UnsupportedEncodingException ParseException运行时异常:在编译时期不出现到运行的时候才出现。可以处理可以不处理 — RuntimeException ArithmeticException ArrayIndexOutOfBoundsException NullPointerException ClassCastException StringIndexOutOfBoundsException NumberFormatException自定义异常:写一个类继承Exception或者是其子类。如果是继承了RuntimeException及其子类,那么这个时候定义的是一个运行时异常;如果继承的是其他的Exception,那么定义的就是编译时异常异常的捕获方式 A. 如果多个异常的处理方式各不一样,可以使用多个catch分别捕获分别处理 B. 如果所有异常的处理方式都一样,可以捕获这些异常的父类进行统一的处理 C. 如果多个异常进行了分组,那么同一组的异常之间用 | 隔开进行分组处理 — 从JDK1.7开始

    目录,再往上一拉

    package cn.tedu.exception; public class ExceptionDemo6 { public static void main(String[] args) { System.out.println(m()); } public static int m() { int i = 4; // 方法在栈内存中执行 // 方法在执行过程中的计算和存储是分成了2块 // 在代码执行过程中,会出现计算和存储分别进行的现象 // 代码是从上到下来依次编译运行的 try { // 先运行return i++; // 在计算区域将i的值从存储区域取出来进行计算 // 在计算的时候由于++在后,所以将i的值4作为数据参与下一步运算 // 下一步运算 return 4; // 在执行return 4准备返回的时候需要检查是否有后续操作执行:i的自增,finally // 先让i进行自增为5 // 然后继续执行下一个后续操作是finally // 后续操作全部完成最后在执行刚才被挂起的return 4; return i++; } finally { // 在finally中对i再次自增为6 i++; System.out.println("finally:" + i); } } }

    目录,再往上一拉

    public static Person m() { Person p = new Person(); try { p.setName("如花"); p.setAge(80); // p是对象,所以return的是p的地址 return p; } finally { p.setName("周星星"); p.setAge(18); } }

    目录,再往上一拉

    package cn.tedu.exception; public class ExceptionDemo2 { public static void main(String[] args) /* throws FileNotExistException */ { try { String msg = readTxt("E:\\a.jpg"); System.out.println(msg); } catch (FileNotExistException e) { System.out.println(e.getMessage()); System.out.println("在处理这个问题~~~"); } catch (FileFormatException e) { System.out.println(e.getMessage()); } catch (NullPointerException e) { System.out.println("处理空指针~~~"); } // try { // String msg = readTxt("E:\\a.jpg"); // System.out.println(msg); // } catch (Exception e) { // System.out.println(e.getMessage()); // } // 一定是先子类异常后父类异常 try { String msg = readTxt("E:\\a.jpg"); System.out.println(msg); } catch (FileNotExistException | FileFormatException e) { // System.out.println(e.getMessage()); // 打印栈轨迹 e.printStackTrace(); } catch (NullPointerException e) { System.out.println("处理空指针~~~"); } catch (Exception e) { } System.out.println("running~~~"); } public static String readTxt(String path) throws FileNotExistException, FileFormatException, NullPointerException { if (path == null) throw new NullPointerException("亲,路径不能并且空~~~"); // 可能路径不存在 if (path.startsWith("H:\\")) throw new FileNotExistException("亲,这个文件不存在哦~~~"); // 文件格式不一样 if (!path.endsWith(".txt")) throw new FileFormatException("亲,需要一个TXT文件~~~"); return "读取成功~~~"; } } @SuppressWarnings("serial") class FileFormatException extends Exception { public FileFormatException() { } public FileFormatException(String msg) { super(msg); } } @SuppressWarnings("serial") class FileNotExistException extends Exception { private String msg; public FileNotExistException() { } public FileNotExistException(String msg) { this.msg = msg; } public String getMessage() { return msg; } }

    目录,再往上一拉

    public static void main(String[] args) throws CloneNotSupportedException, ParseException { // try { // System.out.println(1 / 0); // } catch (ArithmeticException e) { // System.out.println("在处理这个算术异常~~~"); // } // int[] arr = new int[3]; // System.out.println(arr[5]); // String str = null; // System.out.println(str.length()); // Object o = new Object(); // String str = (String) o; // Integer in = new Integer("abc"); // new ExceptionDemo().clone(); // "abc".getBytes("abc"); // new SimpleDateFormat("yyyy-MM-dd").parse("2012-03-05"); }

    集合

    集合是一个存储多个同一类型的数据的容器 — 大小是不固定的 - 泛型,表示集合中的元素的数据类型List - 列表 保证元素的存入顺序,列表中的元素是可以重复的。可以通过下标操作指定位置上的元素 ArrayList - 顺序表 底层是基于数组来存储数据。内存空间是连续的。默认初始容量是10,每次扩容默认增加一半,基于了右移。增删操作相对复杂,查询操作相对简单。是一个线程不安全的列表。 LinkedList - 链表 基于节点(Node)来实现的。利用节点来存储数据以及维系链表之间每一个节点的关系。内存空间不连续。增删操作相对简单,查询操作相对复杂。是一个线程不安全的列表 LinkedList:基于节点,内存空间是不连续的。相对增删简单但是查询复杂。是一个线程不安全的列表 考虑:如果在增删和查询的次数相差不多的情况下,使用ArrayList还是LinkedList? — LinkedList 因为ArrayList要保证一段连续的存储空间,而LinkedList不用,节点都是散开分布的,所以存储性能好。 LinkedList的增删是基于二分查询的,跟中间比较,小的话从头开始查找、大的话从尾开始查找。 Vector - 向量 最早的列表,依靠数组来存储数据,内存空间一定是连续的,初始默认是10,每次扩容默认增加一倍。是一个线程安全的列表Stack - 栈 继承了Vector。遵循后进先出/先进后出的原则。最先放入栈中的元素 — 栈底元素,最后放入栈中的元素 — 栈顶元素。将元素放入栈中 — 入栈/压栈,将元素从栈中取出 — 出栈/弹栈Set - 散列集合 包含的元素不重复,保证元素的唯一性 HashSet:散列集合,不包含重复的元素,不保证元素的存入顺序。底层基于HashMap来进行数据的存储。 -> 基于了数组+链表结构(链表栈结构)。默认初始容量是16,默认加载因子是0.75f,默认增加一倍。 TreeSet:要求存入的元素对应的类必须实现Comparable的接口,然后利用接口中compareTo方法进行自然排序;如果需要对某一个TreeSet单独指定排序规则,则需要传入一个Comparator对象 加载因子过小,会导致频繁发生rehash操作而降低效率,同时还造成空间资源的浪费 加载因子过大,会导致每一个桶中的链的长度过长,从而降低增删效率。 从JDK1.8开始,对HashSet的存储做了调优:如果桶中的链的长度大于了8,会将这个链式结构扭转成一个二叉树结构TreeSet — 会对元素进行整体的自然排序,需要元素对应的类实现Comparable接口 Comparable —类在实现这个接口之后对这个类的所有的对象进行整体排序 Comparator — 用于给某个对象单独指定规则 总结:如果需要给某个TreeSet对象单独指定比较规则,则使用Comparator;如果不指定比较规则,则使用Comparable进行整体的自然排序Collections - 操作集合的工具类

    目录,再往上一拉

    package cn.tedu.collection; import java.util.ArrayList; import java.util.Collection; public class CollectionDemo { public static void main(String[] args) { // 集合中存储的元素类型是String Collection<String> c = new ArrayList<String>(); // 添加元素 c.add("gwe"); c.add("hred"); c.add("hrd"); c.add("ater"); // 将集合转化为数组 // Object[] os = c.toArray(); // String[] os = (String[]) c.toArray(); // for (Object o : os) { // System.out.println(((String) o).length()); // } // String[] strs = c.toArray(new String[0]); // for (String str : strs) { // System.out.println(str.length()); // } // 获取集合中的元素个数 // System.out.println(c.size()); // 清空集合 // c.clear(); // 判断集合是否为空 // System.out.println(c.isEmpty()); // 判断元素是否存在 // System.out.println(c.contains("hrd")); // System.out.println(c.contains("aft")); // 从集合中移除指定的元素 // c.remove("gwe"); // 如果元素不存在,会直接跳过 // c.remove("age"); // System.out.println(c); } }

    目录,再往上一拉

    package cn.tedu.collection; import java.util.ArrayList; import java.util.List; public class ListDemo { public static void main(String[] args) { List<String> list = new ArrayList<String>(); // 保证元素的存入顺序 list.add("bdd"); list.add("abd"); list.add("egd"); list.add("eds"); list.add("abd"); list.add(null); // 截取子列表 System.out.println(list.subList(1, 3)); // 获取指定的元素在列表中第一次出现的位置 // System.out.println(list.indexOf("abd")); // List<String> list2 = new ArrayList<String>(); // list2.add(new String("bdd")); // list2.add("abd"); // list2.add("egd"); // list2.add("eds"); // 比较两个列表的时候是逐位比较是否一致 // System.out.println(list.equals(list2)); // for(int i = 0; i < list.size(); i++) // System.out.println(list.get(i)); // 获取指定下标上的元素 // System.out.println(list.get(1)); // 向列表的指定的下标插入指定的元素 // list.add(1,"fec"); // list.add(4, "fec"); // list.add(6, "fec"); // 移除指定下标上的元素 // list.remove(0); // list.remove(5); // 替换指定位置上的元素 // list.remove(2); // list.add(2, "abc"); // list.set(2, "abc"); System.out.println(list); } }

    右移一位和除二的区别 https://blog.csdn.net/FlushHip/article/details/82495034

    目录,再往上一拉

    手写ArrayList

    package cn.tedu.collection; import java.util.Arrays; public class ListExer { public static void main(String[] args) { ArrList list = new ArrList(1); list.add("abc"); list.add("abc"); list.add("def"); // list.add(0, "hijk"); list.remove(0); System.out.println(list); } } class ArrList { private String[] data; // 记录元素的个数 private int size = 0; public ArrList() { data = new String[10]; } public ArrList(int initialCapacity) { if (initialCapacity < 0) throw new IllegalArgumentException(); data = new String[initialCapacity]; } // 添加元素 public void add(String str) { // 判断是否需要扩容 if (size >= data.length) this.grow(); data[size++] = str; } // 扩容 private void grow() { if (data.length <= 1) data = Arrays.copyOf(data, data.length + 1); else data = Arrays.copyOf(data, data.length + (data.length >> 1)); } // 插入元素 public void add(int index, String str) { // 判断下标越界 if (index > size) throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size); // 判断扩容 if (size >= data.length) this.grow(); // 挪动元素空出对应的位置 // for (int i = size - 1; i >= index; i--) { // data[i + 1] = data[i]; // } System.arraycopy(data, index, data, index + 1, size - index); // // 插入元素 data[index] = str; size++; } private void out(int index) { // 判断下标越界 if (index >= size) throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size); } // 根据下标移除指定的元素 public void remove(int index) { this.out(index); // for(int i = index; i < size - 1; i++){ // data[i] = data[i + 1]; // } System.arraycopy(data, index + 1, data, index, size - (index + 1)); size--; } // 移除指定的元素 public void remove(String str) { // 首先先找到这个元素出现的位置 int index = indexOf(str); if (index != -1) this.remove(index); } // 找这个元素第一次出现的位置 public int indexOf(String str) { for (int i = 0; i < size; i++) { if (data[i] == str || data[i] != null && data[i].equals(str)) return i; } return -1; } public void clear() { data = new String[10]; size = 0; } public boolean contains(String str) { return indexOf(str) != -1; } public String get(int index) { this.out(index); return data[index]; } public boolean isEmpty() { return size == 0; } public void set(int index, String str) { this.out(index); data[index] = str; } public int size() { return size; } @Override public String toString() { StringBuilder sb = new StringBuilder("["); for (int i = 0; i < size; i++) { sb.append(data[i]).append(", "); } String str = sb.toString(); if (size > 0) str = str.substring(0, str.length() - 2); return str += "]"; } }

    手写LinkedList 目录,再往上一拉

    package cn.tedu.collection; public class ListExer2 { public static void main(String[] args) { LinkList list = new LinkList(); list.add("a"); list.add("b"); list.add("c"); // list.add(0,"d"); // list.add(1, "e"); // list.remove(0); // list.remove(2); list.remove(1); System.out.println(list); } } class LinkList { private int size = 0; // 节点个数 private Node first; // 第一个节点 private Node last; // 最后一个节点 public LinkList() { } public void add(String str) { // 创建节点存储数据 Node node = new Node(null, str, null); // 列表此时为空 if (size == 0) { // 如果列表为空,则头结点指向新节点 this.first = node; } else { // 原来的尾节点的下一位置为新节点 this.last.next = node; // 新节点的上一位是原来的尾节点 = this.last; } // 新的节点变成了尾节点 this.last = node; size++; } public void add(int index, String str) { // 判断下标是否越界 if (index > size) throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size); // 在尾部追加 if (index == size) { this.add(str); return; } Node node = new Node(null, str, null); // 插入的头部 if (index == 0) { node.next = this.first; this.first.prev = node; this.first = node; } else { Node no = this.getNode(index); // 原节点的上一个节点的下一位变成新的节点 no.prev.next = node; // 新的节点的上一位是原节点的上一位 node.prev = no.prev; // 新节点的下一位是原来的节点 node.next = no; // 原节点的上一位是新的节点 no.prev = node; } size++; } private Node getNode(int index) { // 获取指定位置的节点 Node no = this.first; for (int i = 0; i < index; i++) { no = no.next; } return no; } private void out(int index) { // 判断下标越界 if (index >= size) throw new IndexOutOfBoundsException("Index:" + index + ", Size:" + size); } public void remove(int index) { this.out(index); // 头部 if (index == 0) { this.first = this.first.next; this.first.prev = null; } /* 尾部 */ else if (index == size - 1) { this.last = this.last.prev; this.last.next = null; } else { Node node = this.getNode(index); // 原节点的上一个节点的下一位变成原节点的下一位 node.prev.next = node.next; // 原节点的下一个节点的上一位变成原节点的上一位 node.next.prev = node.prev; } size--; } public int indexOf(String str) { Node node = this.first; for (int i = 0; i < size; i++) { String data = node.data; if (data == str || data != null && data.equals(str)) return i; node = node.next; } return -1; } public String toString() { StringBuilder sb = new StringBuilder("["); Node node = this.first; for (int i = 0; i < size; i++) { sb.append(node.data).append(", "); node = node.next; } String str = sb.toString(); if (size > 0) str = str.substring(0, str.length() - 2); return str += "]"; } // 利用节点存储数据 private class Node { Node prev; // 上一个节点 String data; // 元素 Node next; // 下一个节点 public Node(Node prev, String data, Node next) { super(); this.prev = prev; this.data = data; this.next = next; } } }

    set集合排序

    目录,再往上一拉

    package cn.tedu.collection; import java.util.Comparator; import java.util.TreeSet; public class SetDemo2 { public static void main(String[] args) { // TreeSet<String> set = new TreeSet<String>(); // 会根据自然顺序(往往是升序)进行排序 // set.add("d"); // set.add("g"); // set.add("a"); // set.add("r"); // set.add("c"); // System.out.println(set); TreeSet<Student> set = new TreeSet<Student>(); // 按照分数进行降序排序 // TreeSet<Student> set = new TreeSet<Student>(new Comparator<Student>() // { // // @Override // public int compare(Student o1, Student o2) { // return o2.getScore() - o1.getScore(); // } // }); // 要求set中的元素所对应的类必须实现Comparable set.add(new Student("01金毛狮王", 20, 59)); set.add(new Student("03白眉鹰王", 50, 18)); set.add(new Student("02紫衫龙王", 49, 89)); set.add(new Student("05青翼蝠王", 38, 60)); for (Student s : set) { System.out.println(s); } } } class Student implements Comparable<Student> { private String name; private int age; private int score; public Student(String name, int age, int score) { this.name = name; this.age = age; this.score = score; } 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; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + ", score=" + score + "]"; } @Override // 排序规则就写在compareTo中 // 在排序的时候会根据返回值的正负来确定元素的排序顺序 // 如果返回了一个正数,那么this就会排在o之后 // 如果返回了一个负数,那么this就会排在o之前 public int compareTo(Student o) { // return this.age - o.age; //升序 // return o.age - this.age; //降序 return name.compareTo(o.name); } }

    Stack - 栈集合 目录,再往上一拉

    Stack<String> s = new Stack<String>(); // 添加元素 s.push("d"); s.push("a"); s.push("e"); s.push("s"); s.push("h"); // 从栈顶到栈底依次查找,以1基数 System.out.println(s.search("a")); // 判断栈是否为空 // System.out.println(s.empty()); // 查看栈顶元素 // 如果栈为空,则抛出空栈异常 // System.out.println(s.peek()); // 移除栈顶元素 // System.out.println(s.pop()); System.out.println(s);

    练习:使用数组/节点(Node)完成一个Stack — empty peek pop push search 目录,再往上一拉

    package cn.tedu.collection; import java.util.Arrays; import java.util.EmptyStackException; public class StackExer { public static void main(String[] args) { // ArrStack as = new ArrStack(); // as.push("a"); // as.push("b"); // as.push("c"); // as.pop(); LinkStack ls = new LinkStack(); ls.push("a"); ls.push("b"); ls.push("c"); System.out.println(ls); } } class LinkStack { private int size = 0; private Node first; public boolean empty() { return size == 0; } public void push(String str) { Node node = new Node(null, str); // if (size != 0) { // node.next = this.first; // } this.first = node; size++; } public String peek() { if (size == 0) throw new EmptyStackException(); return this.first.data; } public String pop() { String str = this.peek(); this.first = this.first.next; size--; return str; } public int search(String str) { Node node = this.first; for (int i = 0; i < size; i++) { if (node.data == str || str != null && str.equals(node.data)) return i + 1; node = node.next; } return -1; } @Override public String toString() { return "LinkStack [size=" + size + ", first=" + first + "]"; } private class Node { Node next; String data; public Node(Node next, String data) { super(); this.next = next; this.data = data; } } } class ArrStack { private String[] data = new String[10]; private int size = 0; public String peek() { // 判断栈中是否有元素 if (size == 0) throw new EmptyStackException(); return data[size - 1]; } public String pop() { String str = this.peek(); size--; return str; } public void push(String str) { // 判断是否需要扩容 if (size >= data.length) data = Arrays.copyOf(data, data.length * 2); data[size++] = str; } public int search(String str) { // for(int i = size - 1, j = 1; i >= 0; i--, j++){ // // if(str == data[i] || str != null && str.equals(data[i])) // return j; // // } for (int i = size - 1; i >= 0; i--) { if (str == data[i] || str != null && str.equals(data[i])) return size - i; } return -1; } }

    JDK8 新特性 目录,再往上一拉

    package exer1; import java.util.ArrayList; import java.util.List; import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Stream; public class StreamDemo { public static void main(String[] args) { List<String> list = new ArrayList<String>(); list.add("abe"); list.add("egs"); list.add("dgse"); list.add("3sdf"); list.add("sdh8"); list.add("dbks"); list.add("vn3hdso"); // 流式结构,但不是流,可以批量的操作集合中的数据 // JDK1.8的新特性之一 Stream<String> stream = list.stream(); System.out.println(stream.allMatch(str -> str.matches(".*\\d.*"))); // 判断集合中是否包含以字母a开头的字符串 System.out.println(stream.anyMatch(str -> str.startsWith("a"))); stream.filter(new Predicate<String>() { @Override public boolean test(String t) { return t.matches(".*\\d.*"); } }).forEach(new Consumer<String>() { @Override public void accept(String t) { System.out.println(t); } }); stream.filter(str -> str.matches(".*\\d.*")) .map(str -> str.replaceAll("\\d", "")) .forEach(str -> System.out.println(str)); // for (String str : list) { // if (str.matches(".*\\d.*")) { // str = str.replaceAll("\\d", ""); // System.out.println(str); // } // } } }

    Vector 目录,再往上一拉

    package cn.tedu.collection; import java.util.Enumeration; import java.util.Vector; public class VectorDemo { public static void main(String[] args) { // Vector<String> v = new Vector<String>(); // 表示向量的初始容量是10,每次扩容增加5个 // Vector<String> v = new Vector<String>(10, 5); // System.out.println(v.capacity()); // // for (int i = 0; i < 21; i++) { // v.add("a"); // } // // System.out.println(v.capacity()); Vector<String> v = new Vector<String>(); v.add("a"); v.add("d"); v.add("t"); v.add("h"); // 获取迭代器 Enumeration<String> e = v.elements(); // 判断后续是否还有元素 while (e.hasMoreElements()) { // 挪动指针获取这一个元素 String str = e.nextElement(); System.out.println(str); // 无法清空集合 // v.remove(str); } System.out.println(v); } }

    迭代器

    目录,再往上一拉

    迭代器是通过指针的挪动来依次获取集合中的每一个元素。Enumeration - 最早期的迭代器Iterator -通过迭代器自带的remove方法来移除当前在迭代的元素, it.remove(); 实质是:一个集合实现迭代器后(产生一个迭代器对象),迭代器会复制一份集合,然后对这份集合中每一个元素进行标记(true/false),然后去和原集合对比,确定每一个元素是否该删除。因此在迭代过程中不允许直接增删原集合,否则会产生ConcurrentModificationException 当前认证(标记)异常。Collection中的iterator方法是从Iterable中继承过来的,实现了Iterable接口的类产生的对象可以被增强for循环进行遍历。 — 增强for循环也是JDK1.5的特性之一。增强for循环本质上是一个迭代遍历,简化了迭代操作!迭代器:Iterator - 通过状态标记和指针的挪动来遍历元素 - 在迭代过程中不允许直接增删原集合。Iterable接口提供了获取迭代器的方法,实现了这个接口的类所产生的对象可以被增强for循环遍历 List<String> list = new ArrayList<String>(); list.add("abe"); list.add("egs"); list.add("dgse"); list.add("dase"); list.add("3sdf"); list.add("sdh8"); list.add("dbks"); list.add("vn3hdso"); // 通过iterator方法获取到一个Iterator对象 Iterator<String> it = list.iterator(); // 判断是否有下一个元素 while(it.hasNext()){ // 挪动指针获取这个元素 String str = it.next(); System.out.println(str); // 通过迭代器自带的remove方法来移除当前在迭代的元素 // it.remove(); list.remove(str); } System.out.println(list);

    目录,再往上一拉

    泛型

    参数化类型 - ParameterizedType — JDK1.5的特性之一 用具体类型来替代泛型的过程 — 泛型的擦除 — 编译期 ? extends 类/接口 表示传入这个类/接口或者是其子类/子接口对象 — 上限 ? super 类/接口 表示传入这个类/接口及其父类/父接口的对象 — 下限 ? 表示泛型的通配符

    package cn.tedu.type; import java.util.ArrayList; //import java.util.Iterator; import java.util.List; public class TypeDemo1 { public static void main(String[] args) { // 在早期没有泛型的限制的时候,集合中存储元素是Object类型 // List list = new ArrayList(); // List<String> list = new ArrayList(); // List list = new ArrayList<String>(); // List<String> list = new ArrayList<String>(); // 从JDK1.7开始,后边实现类的泛型可以省略不写 // 会根据程序的上文来进行类型的自动推导 List<String> list = new ArrayList<>(); list.add("a"); // list.add(5); // list.add(3.5); // list.add(new Object()); // Iterator it = list.iterator(); // while (it.hasNext()) { // Object o = it.next(); // // if (o instanceof String) { // String str = (String) o; // } else if (o instanceof Integer) { // Integer in = (Integer) o; // } // } } // public static void m(List list){} }

    目录,再往上一拉

    package cn.tedu.type; public class TypeDemo2 { public static void main(String[] args) { Demo<String, Integer> demo = new Demo<>(); demo.set("abc"); System.out.println(demo.get()); } } // <T> 表示定义了一个泛型叫T // 泛型的命名只要符合标识符的命名规则即可 // 习惯上泛型一般只使用一个大写字母进行命名 // T type // E element // K key // V value // R result/return class Demo<T, E> { // 泛型定义的变量不能直接实例化 private T t; E e; public void set(T t) { this.t = t; } public T get() { return t; } }

    目录,再往上一拉

    package cn.tedu.type; public class TypeDemo3 { public static void main(String[] args) { A a = new A(); a.m(5); a.m(true); a.m("def"); } } class A { // 表示给当前的方法定义了一个单独的泛型 public <T> void m(T t) { System.out.println(t.getClass()); } }

    目录,再往上一拉

    package cn.tedu.type; import java.util.ArrayList; import java.util.List; public class TypeDemo4 { public static void main(String[] args) { List<Integer> ins = new ArrayList<>(); ins.add(3); ins.add(4); ins.add(6); ins.add(7); ins.add(0); List<Double> dos = new ArrayList<>(); dos.add(3.6); dos.add(4.2); dos.add(6.8); dos.add(7.7); dos.add(0.2); // 泛型不存在向下兼容 print(ins); print(dos); // List<String> strs = new ArrayList<>(); // print(strs); } // 写一个新的方法来遍历元素类型是数字的列表 // 元素类型是Number或者是其子类 // ? extends 类/接口 表示传入这个类/接口或者是其子类/子接口对象 // 所能传入的元素的最大类型限定为Number // 规定了泛型的上限 public static void print(List<? extends Number> list) { // 不能再添加任何元素除非是null list.add(null); for (Number n : list) { System.out.println(n); } } // 泛型的下限 // 传入元素类型是String及其父类的列表 // ? super 类/接口 表示传入这个类/接口及其父类/父接口的对象 // 表示传入的最小类型是String public static void m(List<? super String> list){ list.add("abc"); for (Object o : list) { System.out.println(o); } } }

    目录,再往上一拉

    package cn.tedu.type; import java.util.ArrayList; import java.util.List; public class TypeDemo5 { public static void main(String[] args) { List<Integer> ins = new ArrayList<>(); ins.add(7); ins.add(3); ins.add(6); ins.add(0); ins.add(4); sort(ins); } // 可以接收任意类型,但是在排序(操作)期间不允许发生增删操作 public static void sort(List<?> list){ list.add(null); } }

    Map<K, V> - 映射

    目录,再往上一拉

    映射:用于存储键值对的容器。每一个键对应一个值,键是唯一的。一个键对应一个值。键是唯一的,值可以重复。每一个键和它所对应的值构成了键值对。— 一个Map是由多个键值对来组成。将每一个键值对看作一个对象,抽取出来一个代表键值对的接口Entry,内部会有一个内部类实现这个Entry接口。Entry是Map中的内部接口 — 一个Map是由多个Entry对象来组成的Map不是集合,但是Map是Java集合框架的成员。 Java集合框架(Java Collections Framework)包含:集合、数组、映射以及操作它们的工具类 — Arrays、Collections、Interator、Comparable、Comparator遍历映射 方式一:先获取映射中所有的键组成的集合,然后通过键获取对应的值 方式二:将所有的键值对放入集合中,然后遍历集合获取这个键值对的数据HashMap:基于哈希码存储,然后允许键和值为null。默认初始容量是16,默认加载因子是0.75f,每次默认增加一倍。自定义初始容量x,这个x介于[2n,2n+1],那么初始容量一定是2n+1 — 底层保证HashMap的容量永远是2n的形式。本身是一个异步式线程不安全的映射Hashtable:基于哈希码存储,然后不允许键和值为null。默认初始容量是11,默认加载因子是0.75f,每次默认增加一倍,然后再+1 — 11 -> 23。本身是一个同步式线程安全的映射。 ConcurrentHashMap — 异步式线程安全的映射 Map<String, Integer> map = new HashMap<>(); // 添加元素 map.put("d", 4); map.put("h", 7); map.put("z", 7); map.put("o", 3); map.put("t", 3); // 如果键相同则对应的值覆盖 map.put("o", 0); map.put("e", null); // 获取键值对的个数 System.out.println(map.size()); // 移除键值对 // map.remove("o"); // 判断键是否存在 // System.out.println(map.containsKey("f")); // 判断值是否存在 // System.out.println(map.containsValue(4)); // 根据指定的键获取对应的值 // System.out.println(map.get("o")); // 如果键不存在则返回null // System.out.println(map.get("y"));Map<String, Integer> map = new HashMap<>(); map.put("d", 4); map.put("h", 7); map.put("z", 7); map.put("o", 3); map.put("t", 3); // 遍历映射 // 方式一:先获取映射中所有的键组成的集合,然后通过键获取对应的值 // keySet表示将映射中的所有的键放入一个Set集合中 // Set<String> set = map.keySet(); // for (String key : set) { // System.out.println(key + "=" + map.get(key)); // } // 方式二:将所有的键值对放入集合中,然后遍历集合获取这个键值对的数据 // entrySet表示将映射中的所有的键值对放入一个Set集合中 Set<Map.Entry<String, Integer>> set = map.entrySet(); // 遍历集合,然后从键值对中获取键和值 for (Map.Entry<String, Integer> entry : set) { System.out.println(entry.getKey() + "=" + entry.getValue()); } System.out.println(map);

    输入一个字符串,统计其中每一个字符出现的次数 目录,再往上一拉

    package cn.tedu.map; import java.util.HashMap; import java.util.Map; import java.util.Scanner; /** * 输入一个字符串,统计其中每一个字符出现的次数 */ public class MapExer { @SuppressWarnings("resource") public static void main(String[] args) { // 获取字符串 Scanner s = new Scanner(System.in); String str = s.next(); // 定义一个映射,键存储字符,值存储个数 Map<Character, Integer> map = new HashMap<>(); // 遍历字符串,然后统计每一个字符出现的次数 for (int i = 0; i < str.length(); i++) { // 获取对应位置的字符 char c = str.charAt(i); // 判断这个字符在映射是否出现过 if (map.containsKey(c)) map.put(c, map.get(c) + 1); else map.put(c, 1); } // 遍历映射 for (Map.Entry<Character, Integer> entry : map.entrySet()) System.out.println(entry.getKey() + ":" + entry.getValue()); } }

    目录,再往上一拉

    断言

    对结果进行预测。assert 断言条件 : 错误信息;在Java中,断言不是默认开启的,需要利用参数手动指定开启 -> -ea -> -enableassertion Scanner s = new Scanner(System.in); int age = s.nextInt(); // 进行断言 // 如果断言成功,则继续往下执行 // 如果断言失败,则抛出错误AssertionError assert age > 0 : "预测年龄应该是大于0的数值,实际上是" + age; System.out.println(age); Scanner s = new Scanner(System.in); int age = s.nextInt(); // 进行断言 // 如果断言成功,则继续往下执行 // 如果断言失败,则抛出错误AssertionError assert age > 0; System.out.println(age);

    扩展:native修饰方法— 本地方法,没有方法体但不是抽象方法,方法体是在JVM中用C语言完成的,在本地方法栈中执行 目录,再往上一拉

    Scanner s = new Scanner(System.in); // 用空白字符进行分隔 int i = s.nextInt(); double d = s.nextDouble(); String str = s.next(); // 用回车换行进行分隔 // 以上次结束作为本次的开始 String str2 = s.nextLine(); // System.out.println(i); // System.out.println(d); // System.out.println(str); System.out.println(str2.equals(""));

    最新回复(0)