Java-17 集合、正则、map简单介绍
1.SimpleDateFormat
-
SimpleDateFormat主要用于将日期进行格式化,可以将Date转成指定格式的字符串,也可以将字符串转成日期。
-
构造方法:
public SimpleDateFormat() 默认格式做转换 public SimpleDateFormat(String pattern) 按指定格式做转换
-
成员方法:
public String format(Date date); public Date parse(Strig dateStr) throws ParseExcepiton;
-
format方法 date->string
import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo1 { public static void main(String[] args) { // 获取当前时间 Date date = new Date(); System.out.println(date); // 无参构造方法。默认格式 xxxx/xx/xx 上午 xx:xx SimpleDateFormat sdf = new SimpleDateFormat(); String str = sdf.format(date); System.out.println(str);// 2020/10/17 上午10:32 SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String str2 = sdf2.format(date); System.out.println(str2);// 2020-10-17 10:35:46 } }
-
parse方法 string-->date
public class SimpleDateFormatDemo1 { // throws ParseException抛出异常 public static void main(String[] args) throws ParseException { // 声明Str date格式 SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH/mm/ss"); String str3 = "2010-02-02 12/12/12"; // Str 转 date Date date2 = sdf3.parse(str3); System.out.println(date2); } }
注意:一定要保证String的格式 和 SimpleDateFormat中的Patten 保持一致。
-
日期转换练习
// 把字符串"2018-10-15 11:11:11" 转成字符串 "11:11:11 15/10/2018" import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; public class SimpleDateFormatDemo2 { public static void main(String[] args) throws ParseException { String str1 = "2018-10-15 11:11:11"; SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:SS"); // 转换成date Date date = sdf1.parse(str1); System.out.println(date);// Mon Oct 15 11:11:00 CST 2018 SimpleDateFormat sdf2 = new SimpleDateFormat("SS:mm:HH dd/MM/yyyy"); String str2 = sdf2.format(date); // 转化成String System.out.println(str2);// 11:11:11 15/10/2018 } }
2.正则表达式
-
正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符,及这些特定字符的组合,组成一个"规则字符串"。这个“规则字符串”的一种过滤。
-
练习
// 验证qq号,不能以0开头 ,5-15位 public class RegexDemo1 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); System.out.println("请输入QQ号:"); String qq = sc.next(); boolean result = checkQQ(qq); if (result) { System.out.println("合法QQ"); } else { System.out.println("不合格QQ"); } } private static boolean checkQQ(String qq) { String regex = "[1-9][0-9]{4,14}"; return qq.matches(regex); } }
-
常用规则:
. 任何字符 \d 数字[0-9] \D 非数字 [^0-9] \s 空白字符 \r\n\x0B\f\r \S 非空白字符 \w 单词字符 [a-zA-Z_0-9] \W 非单词字符 X? X的0次或1次 X* X的0次或多次 x+ X的一次或多次 X{n} X的n次 X{n,} X的至少n次 X{n,m} 至少n次,不超过m次 [abc]a、b 或 c (简单类) \b 单词边界
-
匹配一个整数或小数
System.out.println("12.34".matches("\\d+(\\.\\d+)?"));
-
匹配手机号
String phoneRegex = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(17[013678])|(18[0,5-9]))\\d{8}$"; System.out.println("13500000000".matches(phoneRegex));
-
验证邮箱
String emailRegex = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; System.out.println("1324df@qq.com".matches(emailRegex));
-
split分割
public class RegxDemo2 { public static void main(String[] args) { String str1 = "11,22,33"; String[] split1 = str1.split(","); System.out.println(split1[1]); String str2 = "11.22.33"; String[] split2 = str2.split("\\."); System.out.println(split2[1]); String path = "C:\\demo\\a.txt"; String[] split3 = path.split("\\\\"); System.out.println(split3[2]); } }
-
练习:有一个字符串 "2 3 1 11 4" 转成"1 2 3 4 11"
public class RegexDemo3 { public static void main(String[] args) { String str = "2 3 1 11 4"; String[] arr = str.split(" "); // 创建等长int数组 int[] arr2 = new int[arr.length]; for (int i=0;i<arr.length;i++) { String s = arr[i]; int a = Integer.parseInt(s); arr2[i] = a;// 把转成int值存储int数组 } // 对int数组排序 Arrays.sort(arr2); // 遍历拼接 StringBuilder builder = new StringBuilder(); for (int i=0;i<arr2.length;i++) { builder.append(arr2[i]).append(" "); } System.out.println(builder.toString().trim()); } }
-
练习:
// 1+2+3+4...+10=55 public class LianxiaddDemo { public static void main(String[] args) { StringBuilder s = new StringBuilder(); int sum = 0; // for循环不能使用 加号 拼接字符串否则性能很低。 for (int i=1;i<=10;i++) { s.append(i).append("+"); sum += i; } String s2 = s.substring(0, s.length()-1); System.out.println(s2 + "=" + sum); } }
-
正则替换
replaceAll();
-
把手机号中间四位替换*
public class RegexDemo4 { public static void main(String[] args) { String mobile = "13333333333"; String result = mobile.replaceAll("(\\d{3})(\\d{4})(\\d{4})", "$1****$3"); System.out.println(result); } }
-
获取三个字母单词
import java.util.regex.Pattern; import java.util.regex.Matcher; public class RegexDemo5 { public static void main(String[] args) { String str = "ni hao a wo jiao xiao liu ? ni shi shui?"; // 获取Pattern对象 Pattern p = Pattern.compile("\\b[a-zA-Z]{3}\\b"); // 获取Matcher, Matcher 中封装了所有匹配结果 Matcher m = p.matcher(str); // 获取结果 while (m.find()) { System.out.println(m.group()); // hao // liu // shi } } }
注意:m.group不能单独使用,需要先m.find才能使用m.group
3.集合
-
面向对象语言对事务的体现都是以对象形式,所以为了方便对多个对象的操作,Java提供了集合类。
-
数组和集合类同是容器,它们不同?
1.数组虽然也可以存储对象,但长度是固定的,集合长度是可变的。 2.数组中可以存储基本数据类型,集合只能存储对象。
-
集合缺点:
集合只能用于存储对象,集合长度是可变的,集合可以存储不同类型对象。
-
集合类关系图:
虚线表示接口,实线表示类
-
Collection中方法
-
add 添加
Collection c = new ArrayList(); c.add(123);// 123是Integer类型 c.add(12.4); c.add("helloworld"); System.out.println(c);// [123, 12.4, helloworld]
-
remove 移除
boolean r = c.remove(123); System.out.println(r );// true
-
clear清空
-
isEmpty是否为空
System.out.println(c.isEmpty());
-
size集合长度
System.out.println(c.size());
-
contains包含
System.out.println(c.contains(12.4));
-
addAll 添加所有
import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; public class CollectionDemo2 { public static void main(String[] args) { Collection c1 = new ArrayList(); c1.add("c1-1"); c1.add("c1-2"); c1.add("c1-3"); Collection c2 = new LinkedList(); c2.add("c2-1"); c2.add("c2-2"); c2.add("c2-3"); // c2 元素 添加 c1中 c1.addAll(c2); System.out.println(c1); } }
-
removeAll 移除所有
c1.removeAll(c2);
-
containsAll 是否全部包含
c1.containsAll(c2);
-
retainAll 取交集
c1.retainAll(c2)
-
-
Collection 遍历
- 一种集合转数组,另一种通过迭代器遍历。
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; public class CollectionDemo3 { public static void main(String[] args) { Collection c = new ArrayList(); c.add("1"); c.add("1"); c.add("2"); c.add("3"); c.add("4"); System.out.println(c); // 1.集合转数据 Object[] array = c.toArray(); // 遍历 for (int i=0;i<array.length;i++) { System.out.println(array[i]); } // 2.迭代器 Iterator it = c.iterator(); // 判断是否有下一个值 while (it.hasNext()) { // 打印下一个值 System.out.println(it.next()); } } }
-
List中方法
-
有序的,元素可以重复
-
add(int index,E element) 插入
import java.util.ArrayList; import java.util.Collection; import java.util.List; public class ListDemo1 { public static void main(String[] args) { // 泛型:限制集合中的元素只能存储某一种的数据类型(jdk>=1.5) /** * 泛型只在编译时有效,再底层.class文件中没有泛型(泛型的擦除)。 * */ Collection c = new ArrayList(); List<String> list = new ArrayList<> (); list.add("哈");// Collection 中方法 list.add(0, "呼");// ArrayList 中的方法 System.out.println(list);// [呼, 哈] } }
- remove(int index) 根据索引值移除元素
list.remove(1);
- get(int index) 根据索引值取元素
list.get(1); // 可以通过for循环遍历 for (int i=0;i<list.size();i++){ System.out.println(list.get(i)); }
- set(int index)
list.set(1, "呵");
- ListIterator listIterator
List<String> list = new ArrayList<> (); // hashPrevious 查看前面是否有元素 while (it.hashPrevious){ System.out.println(it.previous()); } // 上面相当于从后往前遍历。 // 需要注意是,要想从后往前遍历,需要先从前往后遍历以边,将指针指到最后位置,先执行如下类似逻辑代码。 while (it.hasNext()){ System.out.println(it.next()); }
-
-
四种遍历方式
import java.util.List; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; public class ListTestDemo { public static void main(String[] args) { List<Person> list = new ArrayList<> (); Person p1 = new Person("Tom", '男', 23); Person p2 = new Person("Lucy", '女', 20); list.add(p1); list.add(p2); // 1.转数组方式 Object[] arr1 = list.toArray(); for (int i=0;i<arr1.length;i++) { System.out.println(arr1[i]); } System.out.println("------------------"); // 2.迭代器方式 Iterator arr2 = list.iterator(); while (arr2.hasNext()) { System.out.println(arr2.next()); } System.out.println("------------------"); // 3.for get方式 for (int i=0;i<list.size();i++) { System.out.println(list.get(i)); } System.out.println("------------------"); // 4.ListIterator ListIterator<Person> it2 = list.listIterator(); while (it2.hasNext()) { System.out.println(it2.next()); } } } class Person{ String name; char gender; int age; public Person() { } public Person(String name,char gender,int age) { super(); this.name = name; this.age = age; this.gender = gender; } @Override public String toString() { return "Person [name=" + name + ", gender=" + gender + ", age=" + age + "]"; } }
-
练习:将"张三,18,男;李四,20,男;王五,33,男"切分创建Person对象,并存储在集合中。
List<Person> list2 = new ArrayList<> (); String str2 = "张三,18,男;李四,20,男;王五,33,男"; String[] a1 = str2.split(";"); for (int i=0; i<a1.length ;i++) { String sa = a1[i]; String[] a2 = sa.split(","); String name = a2[0]; int age = Integer.parseInt(a2[1]); char gender = a2[2].charAt(0); Person p = new Person(name,gender,age); list2.add(p); } System.out.println(list2); }
-
List中去重:
- 方式1:新建一个空集合,添加元素前判断当前序列有没有该元素,没有就添加,有就放弃添加。
- 方式2:在原有集合上,前一个元素和后一个元素进行对比,重复进行删除操作。删除会造成序列元素变少,索引值应回到原来索引位置。
import java.util.ArrayList; import java.util.List; public class ListquchongDemo { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("大哥"); list.add("二哥"); list.add("大哥"); list.add("三哥"); list.add("大哥"); List<String> r = distinct(list); System.out.println(r );// [大哥, 二哥, 三哥] List<String> r2 = distinct2(list); System.out.println(r2); } public static List<String> distinct2(List<String> list) { for (int i=0;i<list.size()-1;i++) { for (int j=i+1; j<list.size();j++) { if (list.get(i).equals(list.get(j))) { list.remove(j); j--; } } } return list; } public static List<String> distinct(List<String> list){ // 创建一个新的集合,用于存放不重复的元素 List <String> result =new ArrayList<>(); // 从要去重的集合中拿到每一个元素,去新的集合中做判断,如果新的集合中不存在, // 则存入新的集合,如果新的集合存在,就不存。 for (int i=0;i<list.size();i++) { String s = list.get(i); if (!result.contains(s)) { result.add(s); } } // 返回结果 return result; } }
-
Object类型List去重
import java.util.List; import java.util.ArrayList; public class ListTest2 { // 属性值去重方式,通过重写hashCode和equals public static void main(String[] args) { List <Personss> list = new ArrayList<> (); list.add(new Personss("张三", 12,'男')); list.add(new Personss("李四", 15,'男')); list.add(new Personss("王二", 19,'男')); list.add(new Personss("张三", 12,'男')); List<Personss> r = distinct(list); System.out.println(list); } public static List<Personss> distinct(List<Personss> list){ List <Personss> result = new ArrayList(); for (int i=0;i<list.size();i++) { Personss p = list.get(i); if (!result.contains(p)) { result.add(p); } } return result; } } class Personss{ String name; int age; char gender; public Personss() {} public Personss(String name, int age,char gender) { this.age = age; this.name = name; this.gender = gender; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + gender; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Personss other = (Personss) obj; if (age != other.age) return false; if (gender != other.gender) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]"; } }
-
LinkList
-
数组中,增删慢,当扩容需要移动元素,消耗大量空间,它内部元素是连续的,并且有索引值,查询块。而ArrayList底层是数组实现的。所以它特点是增删慢,查询快。
-
而链表内元素地址不是连续的,内部每个元素为一个节点,每个节点指向下一个元素(保存下一个元素地址值)。它的特点增删快,查询慢。而LinkList底层是链表实现的(随机查询慢)。
-
LinkList独有方法
import java.util.List; import java.util.LinkedList; public class LinkListDemo { public static void main(String[] args) { LinkedList <Integer> list = new LinkedList<> (); list.add(10); list.add(20); list.add(30); // 头部添加元素 list.addFirst(100); // 尾部添加元素 list.addLast(200); System.out.println(list);// [100, 10, 20, 30, 200] // 获取头部元素 System.out.println(list.getFirst());// 100 // 获取尾部元素 System.out.println(list.getLast());// 200 // 移除尾部元素 list.removeLast(); // 移除头部元素 list.removeFirst(); System.out.println(list);// [10, 20, 30] } }
-
4.for each循环
-
for循环,从jdk5产生的新特性,主要用于集合或数组遍历。
-
格式:
for (数据类型 变量名:数组名/集合名){ // 变量名: 集合中的每一个元素 }
-
示例:
import java.util.List; import java.util.ArrayList; import java.util.Collection; public class ForeachDemo { public static void main(String[] args) { // 数组循环 int[] arr = new int[] {5,12,53,0,11}; for (int a:arr) { System.out.println(a); } // List for循环 List<Integer> list = new ArrayList<> (); list.add(100); list.add(200); list.add(300); for (Integer i:list) { System.out.println(i); } // Collection Collection c = new ArrayList(); c.add(123); c.add(456); c.add(789); for (Object o:c) { System.out.println(o); } } }
5.可变参数
-
用于定义方法的时候不知道定义多少个参数。(jdk5后产生新特性)。
-
格式:
修饰符 返回值类型 方法名(数据类型... 变量名){}
-
注意:
这里变量起始是一个数组。 如果一个方法有可变参数,并由多个参数,那么,可变参数必须是最后一个,一个方法中最多只能有一个可变参数。
-
示例:
public class ChangeableParamDemo { public static void main(String[] args) { System.out.println(getSum(1,2,3,4,5,6,7)); } public static int getSum(int ...a) { int sum = 0; for (int i : a) { sum += i; } return sum; } }
6.集合和数组相互转换
-
集合转数组:
import java.util.List; import java.util.ArrayList; import java.util.Arrays; public class ArrayCollectionDemo { public static void main(String[] args) { // 集合转数组。toArray方法 List <String> list = new ArrayList<>(); list.add("a"); list.add("b"); list.add("c"); Object[] arr = list.toArray(); // 数组转集合 /* * Arrays工具类中asList方法 * public static <T> List<T> asList(T... a) * T代表类型 * */ // 方式1: List<Integer> list2 = Arrays.asList(1,2,3,4,5,6); System.out.println(list2);// [1, 2, 3, 4, 5, 6] // 方式2: Integer[] arr2 = new Integer[] {3,4,6,11,2,8}; List<Integer> list3 = Arrays.asList(arr2);// 得到是Arrays中内部类,该类没有实现add/remove System.out.println(list3);// [3, 4, 6, 11, 2, 8] // 而使用Arrays.asList 得到集合是一个只读集合,不能进行add/remove 操作 // 通过创建一个新的ArrayList,把元素添加到新的ArrayList就可以进行add/remove操作 List<Integer> list4 = new ArrayList<>(list3); list4.add(300); System.out.println(list4); } }
7.Set用法
-
Set中元素是不能重复的,并且是无序的(没有索引).
Set HashSet:不能保证存入和取出顺序 LinkedHashSet: 能够保证存入和取出的顺序(链表) TreeSet:能够对内部元素,进行排序
-
HashSet:
public class SetDemo { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("曹操"); set.add("刘备"); set.add("张飞"); set.add("赵云"); set.add("关羽"); set.add("刘备"); System.out.println(set);// [关羽, 张飞, 刘备, 曹操, 赵云] } } // 可以看到上面Set元素是无序的
-
LinkHashSet
Set<String> set = new LinkedHashSet<>(); System.out.println(set);// [曹操, 刘备, 张飞, 赵云, 关羽] // 而LinkHashSet是有序的。
-
元素不可重复性判断是通过hashCode/equals这两个方法决定的,它是先求出要存的元素的hashCode,看集合是否有元素的hashCode和它相同,如果没有相同,则直接存入set里面。如果hashCode相同,再比较equals如果true确实相同,不能存入。false可以存入。
-
set遍历方式:
import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.LinkedHashSet; public class SetDemo { public static void main(String[] args) { Set<String> set = new HashSet<>(); set.add("曹操"); set.add("刘备"); set.add("张飞"); set.add("赵云"); set.add("关羽"); set.add("刘备"); System.out.println(set);// [曹操, 刘备, 张飞, 赵云, 关羽] // 1.toArray Object[] array = set.toArray(); for (Object o: array) { System.out.println(o); } //2.迭代器 Iterator<String> it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } //3.foreach for(String s:set) { System.out.println(s); } } }
-
练习创建一个Set
存储三个元素。打印集合,要求打印是属性。要求集合中只能保存两个元素,使用三种方式遍历。 // 重写 toString 和hashcode 通过属性去重 import java.util.HashSet; import java.util.Iterator; import java.util.Set; public class SetDemo2 { public static void main(String[] args) { Set<Person> ps = new HashSet<>(); ps.add(new Person("张三", 18, '男')); ps.add(new Person("李四", 20, '女')); ps.add(new Person("张三", 18, '男')); System.out.println(ps); } } class Person{ String name; int age; char gender; public Person() { } public Person(String name,int age, char gender) { this.name = name; this.age = age; this.gender = gender; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + ", gender=" + gender + "]"; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + gender; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public 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 (gender != other.gender) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
-
Set生成不重复随机数
import java.util.HashSet; import java.util.Random; import java.util.Set; public class SetDemo3 { public static void main(String[] args) { Random r = new Random(); Set<Integer> set = new HashSet<>(); while (set.size() != 10) { int i = r.nextInt(20) + 1; set.add(i); } System.out.println(set); } }
-
利用Set实现List去重。
import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; public class SetDemo4 { public static void main(String[] args) { List<String> list = new ArrayList<> (); list.add("大哥"); list.add("二哥"); list.add("大哥"); list.add("三哥"); System.out.println(distinct(list)); } public static List<String> distinct(List<String> list){ Set<String> set = new HashSet<> (); // 将list元素添加set去重 set.addAll(list); // 清空list list.clear(); // 将去重set中元素添加list中 list.addAll(set); return list; } }
8.Map
-
Map是双列集合根接口。
-
将键映射到值的对象
-
一个映射不能包含重复的键。
-
每个键最多只能映射到一个值key=value
-
Map接口和Collection接口的不同,Map是双列的,Collection是单列的。
-
Map的键唯一,Collection的子体系Set是唯一的。
-
Map集合的数据结构值针对键有效,跟值无关。
-
Map分类
HashMap: key不能重复,但是可以为null,不能保证key存入和取出顺序。 LinkedHashMap:可以保证key存入和取出的顺序。
-
Map中方法
put(k key, v value) 添加元素 remove(Object key) 移除元素 对应键值对 void clear() 清空map boolean containsKey(Object key) 是否包含key boolean containsValue(Object value) 是否包含value boolean isEmpty() 是否为空(长度是否为0) int size() 键值对的个数
-
示例:
import java.util.HashMap; import java.util.Map; public class MapDemo1 { public static void main(String[] args) { Map<Integer,String> map = new HashMap<>(); map.put(5, "数字5"); map.put(6, "数字6"); map.put(7, "数字7"); String result1 = map.put(8, "数字8"); System.out.println(result1);// null String result2 = map.put(7, "number seven"); System.out.println(result2);// 数字7 System.out.println(map);// {5=数字5, 6=数字6, 7=数字7} System.out.println(map.remove(9));// null System.out.println(map.remove(7));// number seven System.out.println(map.containsKey(7));//false System.out.println(map.containsValue("数字6"));// true map.clear(); System.out.println(map.isEmpty());// true } }
-
HashMap遍历
import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapCDemo2 { public static void main(String[] args) { Map<Integer,String> map = new HashMap<>(); map.put(1, "one"); map.put(2, "two"); map.put(3, "three"); map.put(4, "four"); // 1.map遍历方式:获取所有key keySet: // 获取所有key Set<Integer> keySet = map.keySet(); for (Integer key : keySet) { // 循环所有key,通过get方法打印所有value System.out.println(map.get(key)); } // 2.map遍历方式:获取所有键和值 entrySet Set<Map.Entry<Integer,String>> entrySet = map.entrySet(); for (Map.Entry<Integer, String> entry : entrySet) { System.out.println(entry.getKey() + ":" +entry.getValue()); } // 3.map遍历方式:获取所有value values Collection<String> values = map.values(); for (String s : values) { System.out.println(s); } } }
- 上述遍历方式也可以通过迭代器写
import java.util.Map.Entry; import java.util.Iterator; Iterator<Entry<Integer,String>> it = entrySet.iterator(); while(it.hasNext()) { Entry<Integer,String> entry = it.next(); System.out.println(entry.getKey() + ":" + entry.getValue()); }
-
练习:统计字符串个数:
import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class MapDemo3 { public static void main(String[] args) { Map<Character,Integer> map = new HashMap<>(); Scanner sc = new Scanner(System.in); System.out.println("请输入字符串:"); String str = sc.next(); for (int i=0;i<str.length();i++) { char ch = str.charAt(i); // 根据key去map中取value,如果有值就返回value,如果没有返回默认值。 Integer count = map.getOrDefault(ch, 0); count++; map.put(ch, count); // Integer count = map.get(ch); // if (count == null) { // // 字符第一处出现 // map.put(ch, 1); // }else { // // 不是第一次出现 // count++; // map.put(ch, count); // } } System.out.println(map); } } // 请输入字符串: // asdaerteatsfcx // {a=3, r=1, s=2, c=1, d=1, t=2, e=2, f=1, x=1}
-
HashMap实现原理:
-
HashMap是通过哈希表(散列表)实现的。 数组+链表。
Map map = new HashMap(); // 它的底层是数组+链表,主体是数组。 当执行map.put(1,a); key=1 首先求出hashCode, 对hashCode进行hash运算,运算结果代表它存储数组中的位置(bucket)。 但是当数组存储bucket位置中已经存在元素(hash相同,存在hash冲撞),它会对比它们之间key,如果不相同,它会用链表连接当前位置所有元素,后进来元素放在头上(头插法)。如果比较key相同,就把对应value值进行替换。
-