1.映射
-
HashMap
public static void main(String[] args) { /* 嵌套类/内置类/内部类/内部接口 K : key V : value E : element R : ReturnType T : type Map<K, V> : 存储的是键值对。每个键值对成为映射项(Entry);键唯一,值是可重复的;每个键最多只能映射到一个值。 |HashMap<K, V> : 键采用哈希表结构 允许null键null值 线程不安全 不保证键的插入顺序和迭代顺序一致 |LikedHashMap<K, V> : 键采用 哈希表 + 链表 结构 保证键的插入顺序和迭代顺序一致 |Hashtable<Object,Object> : 键采用哈希表结构 不允许null键null值 线程安全 |Properties : 表示了一个持久的属性集。 Properties 可保存在流中或从流中加载。 属性列表中每个键及其对应值都是一个字符串。 |TreeMap<K, V> : 键采用二叉树结构 */ LinkedHashMap<Character, Integer> map = new LinkedHashMap<>(); // 增 // void putAll(Map<? extends K,? extends V> m) // 从指定映射中将所有映射关系复制到此映射中(可选操作)。 // V put(K key, V value) : 当键是第一次存入map时,返回 null ; // 如果不是第一次,用新值取代旧值,并将旧值作为返回值返回 // 将指定的值与此映射中的指定键关联(可选操作)。 map.put('A', 1); map.put('e', 5); map.put('a', 1); map.put(null, null); System.out.println("value = " + map.put('z', 26)); System.out.println("value = " + map.put('z', 22)); System.out.println("map = " + map); // 查 // int size() 映射项的个数 // 返回此映射中的键-值映射关系数。 System.out.println("map.size() = " + map.size()); // V get(Object key) 根据键获取值 // 返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。 System.out.println("map.get('z') = " + map.get('z')); // Map : 第一种遍历方式 : // Set<K> keySet() : 将所有的键提取出来存到 Set 中 // 返回此映射中包含的键的 Set 视图。 // 1.获取所有键所在的集合 Set<Character> keySet = map.keySet(); // 2.遍历键所在的集合,得到每一个键 for (Iterator<Character> iterator = keySet.iterator(); iterator.hasNext(); ) { // 3.结合 Map 中 的 V get(K k) 函数来获取值 Character key = iterator.next(); Integer value1 = map.get(key); System.out.println(key + " ::: " + value1); } // Map 的第二种遍历方式 : // Set<Map.Entry<K,V>> entrySet() // 返回此映射中包含的映射关系的 Set 视图。 // 1.获取所有映射项所在的集合 Set<Map.Entry<Character, Integer>> entrySet = map.entrySet(); // 2.遍历集合,得到每一个映射项 for (Iterator<Map.Entry<Character, Integer>> iterator = entrySet.iterator(); iterator.hasNext(); ) { Map.Entry<Character,Integer> entry = iterator.next(); // 3.根据 Map.Entry 提供 getKey() 和 getValue() 函数来获取键和值 Character key = entry.getKey(); Integer value1 = entry.getValue(); System.out.println(key + " ~~~ " + value1); if (new Character('z').equals(key)) { entry.setValue(28); } } // Map 的第三种遍历方式(只有值): // Collection<V> values() 将所有的值提取出来存到 Collection 中 // 返回此映射中包含的值的 Collection 视图。 map.values().forEach(System.out::println); System.out.println("--------------------------------------------"); // 删 // V remove(Object key) // 如果存在一个键的映射关系,则将其从此映射中移除(可选操作), 并将其值返回。 System.out.println("remove = " + map.remove(null)); System.out.println("map = " + map); // void clear() // 从此映射中移除所有映射关系(可选操作)。 // 判断 // boolean containsKey(Object key) // 如果此映射包含指定键的映射关系,则返回 true。 System.out.println("map.containsKey('d') = " + map.containsKey('d')); System.out.println("map.containsKey('f') = " + map.containsKey('z')); // boolean containsValue(Object value)` // 如果此映射将一个或多个键映射到指定值,则返回 true。 System.out.println("map.containsValue(1) = " + map.containsValue(1)); System.out.println("map.containsValue(11) = " + map.containsValue(11)); // boolean isEmpty() // 如果此映射未包含键-值映射关系,则返回 true。 System.out.println("--------------------------------------------"); // JDK8.0新增 // Map 的第四种遍历方式 : // default void forEach(BiConsumer<? super K,? super V> action) // Consumer<T> void accept(T t); // BiConsumer<K, V> void accept(T t, U u); map.forEach((key, value1) -> { if (new Character('a').equals(key)) { map.put('a', 26); } System.out.println(key + " ^_^ " + value1); } ); // default V getOrDefault(Object key, V defaultValue) 根据键得值. 但是为了防止空指针错误,如果是空键,会返回设定的默认值 System.out.println("map.get('o') = " + map.get('o')); System.out.println("map.getOrDefault('o',1521) = " + map.getOrDefault('o', 1521)); // default V putIfAbsent(K key, V value) : 存在就不添加,也不修改值,并且返回指定的键对应的值; 不存在时才添加 System.out.println("integer = " + map.putIfAbsent('A', 250)); System.out.println("map = " + map); // default boolean remove(Object key, Object value) : 根据键和值进行移除,必须该映射项的键和值完全匹配,才能移除掉 System.out.println("flag = " + map.remove('A', 1)); System.out.println("flag = " + map.remove('a', 62)); System.out.println("map = " + map); // default V replace(K key, V value) System.out.println("replace = " + map.replace('e', 3333)); // default boolean replace(K key, V oldValue, V newValue) boolean replace1 = map.replace('Y', 25, 5555); System.out.println("replace1 = " + replace1); boolean replace2 = map.replace('z', 25, 6666); System.out.println("replace2 = " + replace2); System.out.println(map); System.out.println("map = " + map); // default void replaceAll(BiFunction< K, V, V> function) map.replaceAll(new BiFunction<Character, Integer, Integer>() { @Override public Integer apply(Character k, Integer v) { return v += 10; } }); System.out.println("map = " + map); // 效果和下面lambda表达式一致 map.replaceAll((k, v) -> v += 10); // JDK 9.0 // static <K,V> Map.Entry<K,V> entry(K k, V v) // JDK10 // static <K,V> Map<K,V> copyOf(Map<? extends K,? extends V> map) 返回的是不可变映射(不可增删,可改可查) }
-
TreeMap
/* |TreeMap<K, V> : 键采用二叉树结构 对键进行排序 1.自然排序 : Comparable<T> : 要求实体类实现该接口 2.自定义排序 : Comparator<T> : 不需要实体类实现该接口,需要编写比较器 */ TreeMap<User, String> treeMap = new TreeMap<>(); treeMap.put(new User("lisi", 20), "黄金"); treeMap.put(new User("zs", 36), "白银"); treeMap.put(new User("zhaoliu", 20), "黄金"); treeMap.put(new User("kitty", 22), "黄金"); treeMap.put(new User("kitty", 19), "黄金"); treeMap.put(new User("kitty", 33), "黄金"); treeMap.forEach((k, v) -> System.out.println(k + " ::: " + v));// lambda 格式 : () -> {} System.out.println("~~~~~~~~~~~~~~~~Comparator~~~~~~~~~~~~~~~~~~~~~~~~"); TreeMap<User, String> treeMap3 = new TreeMap<>((o1, o2) -> { int num = Integer.compare(o1.getAge(), o2.getAge()); if (num == 0) { return -o1.getName().compareTo(o2.getName()); } return num; } ); treeMap3.put(new User("lisi", 20), "黄金"); treeMap3.put(new User("zs", 36), "白银"); treeMap3.put(new User("zhaoliu", 20), "黄金"); treeMap3.put(new User("kitty", 22), "黄金"); treeMap3.put(new User("kitty", 19), "黄金"); treeMap3.put(new User("kitty", 33), "黄金"); treeMap3.forEach((k, v) -> System.out.println(k + " ::: " + v));// lambda 格式 : () -> {} } public class User implements Comparable<User>{ private String name; private Integer age; public User(String name, Integer age) { this.name = name; this.age = age; } @Override public int compareTo(User o) { // 名字升序,年龄降序 int num = name.compareTo(o.name); if (num == 0) { return -age.compareTo(o.age); } return num; } public String getName() { return name; } public Integer getAge() { return age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
-
泛型
public static void main(String[] args) { /* 1、 泛型(Generic)格式: 通过<>来定义要操作的引用数据类型。 优点:1. 运行时异常转换为编译时错误; 2. 避免强制类型转换。 <>用来接收类型, 解决操作的数据类型不确定的问题 2、 什么时候定义泛型类? 当类中要操作的引用数据类型不确定的时候定义泛型类; 早期定义Object来完成扩展。 现在定义泛型来完成扩展。 3、 泛型格式 泛型定义在方法上时,位置在 void 前面; 定义在静态方法上时,位置在 static 之后、 void 之前; 接口也可以泛型 */ ArrayList<String> arrayList1 = new ArrayList<>(); arrayList1.add("aaa"); arrayList1.add("bbb"); arrayList1.add("ccc"); arrayList1.add("ddd"); ArrayList<Number> arrayList2 = new ArrayList<>(); arrayList2.add(123); arrayList2.add(3.14); arrayList2.add(3.0F); arrayList2.add(123L); ArrayList<Integer> arrayList3 = new ArrayList<>(); arrayList3.add(3306); arrayList3.add(3306); arrayList3.add(3306); arrayList3.add(3306); printArrayList1(arrayList1); System.out.println("----------------------"); printArrayList1(arrayList2); System.out.println("----------------------"); printArrayList1(arrayList3); System.out.println("----------------------"); printArrayList2(arrayList2); System.out.println("----------------------"); printArrayList2(arrayList3); } public static <T> void printArrayList1(ArrayList<T> arrayList){ for (T t : arrayList) { System.out.println("t = " + t); } } /* ? : 通配符 泛型的上下限 : 上限: 从父类开始向下进行限制 ? extends E E 和 E的子类型 下限: 从父类开始向下进行限制 ? super E E 和 E的父类型 缺点: 不能使用类型的具体属性 ?与<T>的区别:能否类型装换 */ public static void printArrayList2(ArrayList<? extends Number> arrayList){// 使用?时无需<T> for (Object o : arrayList) { System.out.println("o = " + o); } }
2.数组和集合
-
数组和集合的相互转换
public static void main(String[] args) { // 数组 ---> 集合 : 转换后是固定集合, 不能使用集合的增删功能 // Arrays : static <T> List<T> asList(T... a) // 返回一个受指定数组支持的固定大小的集合。 // 1.引用型数组 : 转换后,数组中的元素作为集合中元素进行存储 String[] strings = new String[]{"aaa", "bbb", "ccc"}; List<String> list = Arrays.asList(strings); System.out.println("list = " + list); System.out.println(list.indexOf("bbb")); List<Integer> list1 = Arrays.asList(3306, 1521, 8080);// 会自动从基本数据类型转变为封装类 System.out.println("list1 = " + list1); // 2.基本数据类型数组 : 转换后, 数组本身作为集合的元素进行存储, 即整个数组作为一个元素存储(地址值) int[] arr = {11, 12, 13}; List<int[]> ints = Arrays.asList(arr); System.out.println("ints = " + ints); // 集合 ---> 数组 // Object[] toArray() Object[] objects = list.toArray(); for (Object o : objects) { System.out.println("o = " + o); } System.out.println("----------------------"); // <T> T[] toArray(T[] a) String[] strings1 = list.toArray(new String[0]); for (String s : strings1) { System.out.println("s = " + s); } // Stream : 1.获取Stream 2.中间操作 3.终止操作 : forEach()是终止操作之一 Stream<String> stream = Arrays.stream(strings1);// 获取到的Stream对象只能使用一次 stream.forEach(System.out::println); // stream.forEach(System.out::println); // Stream对象第二次使用 会有 : IllegalStateException // Arrays.stream(strings1).forEach(System.out::println); // 上述的lambda表达式 }
-
数组常用工具
public static void main(String[] args) { // static int binarySearch(byte[] a, byte key): 折半查找/二分查找 : 前提 数组以按升序排好顺序 int[] arr = {12, 3, 1, 98, 67, 90, 11, 52}; Arrays.sort(arr); System.out.println(Arrays.toString(arr)); int index = Arrays.binarySearch(arr, 11);// 找到了返回对应的索引值 System.out.println("index = " + index); index = Arrays.binarySearch(arr, 13);// 没找到返回负数, 且该返回值的绝对值, 是指定数值应该排在数组中的位置(减1) System.out.println("index = " + index); System.out.println("----------------------"); // static byte[] copyOf(byte[] original, int newLength) : 复制数组并添加指定长度的新内容, 填默认值 int[] newArr = Arrays.copyOf(arr, arr.length * 2); System.out.println(Arrays.toString(newArr)); System.out.println("----------------------"); // static boolean[] copyOfRange(boolean[] original, int from, int to) : 复制数组中指定长度的内容 int[] ints = Arrays.copyOfRange(arr, 1, 5); System.out.println(Arrays.toString(ints)); System.out.println("----------------------"); // static boolean deepEquals(Object[] a1, Object[] a2) : 多维数组内容是否相同 int[][] arr2 = {{1521}, {3306, 124, 126}, arr}; int[][] arr3 = {{1521}, {3306, 124, 126}, arr}; System.out.println(arr2 == arr3); System.out.println(arr2.equals(arr3)); System.out.println(Arrays.deepEquals(arr2, arr3)); System.out.println("----------------------"); // static boolean equals(boolean[] a, boolean[] a2) 仅用于一维数组不能用于二维数组 int[] arr4 = {12, 3, 1, 98, 67, 90, 11, 52}; int[] arr5 = {12, 3, 1, 98, 67, 90, 11, 52}; System.out.println(Arrays.equals(arr4, arr5)); System.out.println(Arrays.equals(arr2, arr3)); System.out.println(Arrays.deepToString(arr2));// deepToString 展示多维数组内容 // static void fill(boolean[] a, boolean val) 将数组整个或指定位置的内容, 填充/修改为指定内容 Arrays.fill(arr4, 110); System.out.println(Arrays.toString(arr4)); Arrays.fill(arr5, 1, 5, 110); System.out.println(Arrays.toString(arr5)); // static void sort(byte[] a) : 串行排序 String[] strings = {"da", "fdsa", "java", "html", "css", "js", "sql", "JavaEE"}; Arrays.sort(strings); System.out.println(Arrays.toString(strings)); // 可重写sort : 先按长短来排, 再看内容 Arrays.sort(strings, (String o1, String o2) -> { int num = Integer.compare(o1.length(), o2.length()); if (num == 0) { return -o1.compareTo(o2);// -代表反序 } return -num; } ); System.out.println(Arrays.toString(strings)); // JDK8.0新增 // static void parallelPrefix(double[] array, int fromIndex, int toIndex, DoubleBinaryOperator op) // static void parallelSetAll(int[] array, IntUnaryOperator generator) // static void parallelSort(byte[] a) : 并行排序 // static void parallelSort(byte[] a, int fromIndex, int toIndex) // static void setAll(int[] array, IntUnaryOperator generator) // static Spliterator.OfDouble spliterator(double[] array) // static Spliterator.OfDouble spliterator(double[] array, int startInclusive, int endExclusive) }