Java中的集合(Collection,Map)
集合类体系结构
Collection集合
Collection集合概述
- 是单例集合的顶层接口,它表示一组对象,这些对象也被成为Collection元素
- JDK不提供此接口的任何直接实现,它提供更具体的子接口(如Set和List)实现
创建Collection集合的对象
- 多态的方式
- 具体的实现类ArrayList
List集合中存储的元素是可以重复的,即如果两个相同值得元素 ,地址会不相同。而Set中不可重复元素,如果两个元素得值相同,则会共用一个地址。
Collection集合的常用方法
- boolean add( E e ):添加元素
- boolean remove( Object o ):从集合中移除指定元素
- void clear():清空集合中的元素
- boolean contains( Object o ):判断集合中是否存在指定元素
- boolean isEmpty():判断集合是否为空
- int size():返回集合的长度
Collection集合的遍历
Iterator :迭代器,集合的专用遍历方式
- Iterator< E > iterator():返回集合中元素的迭代器,通过集合的iterator()方法得到
- 迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
Iterator 中的常用方法
- E next():返回迭代中的下一个元素
- boolean hasNext():如果迭代具有更多元素,则返回true
public static void main(String[] args) {Collection<String> c = new ArrayList<>(); // 创建集合对象strings.add("I");strings.add("Love");strings.add("Java");strings.add("And");strings.add("JavaScript");Iterator<String> it = c.iterator(); // 返回集合中元素的迭代器while(it.hasNext()){System.out.println(it.next());}}
例题:Collection集合存储学生对象并且遍历
public static void main(String[] args) {Collection<Student> students = new ArrayList<>();students.add(new Student(1,"蜡笔小新",5));students.add(new Student(2,"风间彻",5));students.add(new Student(3,"樱田妮妮",5));Iterator<Student> it = students.iterator();while(it.hasNext()){Student next = it.next();System.out.println("学号为:" + next.getNumber() + "\t\t姓名为:" + next.getName() + "\t\t年龄为:" + next.getAge());}}
// 学号为:1 姓名为:蜡笔小新 年龄为:5
// 学号为:2 姓名为:风间彻 年龄为:5
// 学号为:3 姓名为:樱田妮妮 年龄为:5
List集合
List集合概述和特点
集合概述
- 有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素兵搜索列表中的元素
- 与Set集合不同,列表通常允许重复的元素
特点
- 有序:存储和取出的元素顺序一致
- 可重复:存储的元素可以重复
创建集合对象的方法
List< E > list = new ArrayList< E >();
List集合常用方法
- void add( int index, E element):在此集合指定位置插入元素
- E remove( int index ):删除指定索引出处的元素,返回被修改的元素
- E set( int index, E element):修改指定索引处的元素,返回被修改的元素
- E get( int index):返回指定索引处的元素
public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("I");list.add("Love");list.add("Java");list.add("And");list.add("JavaScript");System.out.println(list); // [I, Love, Java, And, JavaScript]list.add(1,"JavaWeb");System.out.println(list); // [I, JavaWeb, Love, Java, And, JavaScript]System.out.println(list.remove(1)); // JavaWebSystem.out.println(list.remove("And")); // trueSystem.out.println(list.set(1,"OvO")); // LoveSystem.out.println(list); // [I, OvO, Java, JavaScript]System.out.println(list.get(2)); // Java}
List存储学生数组并遍历的方式与Collection集合的方式一样,只不过List集合可以使用for循环进行遍历
使用迭代器遍历集合时,不允许在集合中添加/删除元素,但是可以修改元素,因为增加/删除元素会触发并发修改异常,这个异常可以通过分析源码理解,如果想要在遍历中根据条件增加/删除元素操作,可以使用for循环遍历
ListIterator 迭代器
ListIterator中的常用方法
- E next():返回迭代中的下一个元素
- boolean hasNext():判断迭代是否还有元素
- E previous():返回迭代中的上一个元素
- boolean hasPrevious():判断迭代的反方向是否还有更多元素
- void add( E e ):增加元素
public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("a");list.add("b");list.add("c");list.add("d");ListIterator<String> it = list.listIterator();while(it.hasNext()){System.out.print(it.next() + " "); // a b c d }System.out.println();while(it.hasPrevious()){System.out.print(it.previous() + " "); // d c b a }System.out.println();while(it.hasNext()){String next = it.next();if(next.equals("a")){it.add("java");}}System.out.println(list); // [a, java, b, c, d]}
listIterator 与 Iterator的区别
ListIterator是List集合特有的迭代器,通过List集合的 listIterator() 方法得到,它允许我们沿任一方向遍历列表,并且可以在迭代期间修改列表
前者在调用add()方法时,会将实际的修改值赋值给预期的修改值,而后者的add()方法中则不会进行此赋值,所以前者可以在迭代的时候进行增加或者删除元素( add() remove() ),而后者是不行的,否则会出现并发修改异常
List集合子类特点
List集合常用子类:ArrayList , LinkedList
- ArrayList:底层数据结构是数组,查询快,增删慢
- LinkedList:底层数据结构是链表,增删快,查询慢
ArrayList<String> array = new ArrayList<String>();
LinkedList<String> linked = new LinkedList<String>();
LinkedList集合常用功能
- public void addFirst( E e ):在该列表开头插入指定元素
- public void addLast( E e ):在该列表末尾追加指定元素
- public E getFirst():返回此列表中的第一个元素
- public E getLast():返回此列表中的最后一个元素
- public E removeFirst():从列表中删除并返回第一个元素
- public E removeLast():从列表中删除并返回最后一个元素
public static void main(String[] args) {LinkedList<String> strings = new LinkedList<>();strings.add("I");strings.addFirst("Love");strings.addLast("Java");System.out.println(strings); // [Love, I, Java]System.out.println(strings.getFirst()); // LoveSystem.out.println(strings.getLast()); // JavaSystem.out.println(strings.removeFirst()); // LoveSystem.out.println(strings.removeLast()); // JavaSystem.out.println(strings); // [I]}
ArrayList
Set集合
Set集合的特点
- 不包含重复元素的集合
- 没有带索引的方法,所以不能使用普通for循环遍历
public static void main(String[] args) {Set<String> strings = new HashSet<String>(); // HashSet对迭代顺序不做任何保证(不保证存储和取出的数据顺序一致)strings.add("a");strings.add("b");strings.add("c");strings.add("d");strings.add("a");Iterator<String> it = strings.iterator();for (String s:strings) {System.out.print(s + "\t"); // a b c d 重复元素自动合并}}
哈希值
哈希值是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
Object类中有一个方法可以获取对象的哈希值
- public int hashCode():返回对象的哈希码值
public static void main(String[] args) {Student s1 = new Student(1, "蜡笔小新", 5);Student s2 = new Student(2, "风间彻", 5);System.out.println(s1.hashCode()); // 1160460865System.out.println(s2.hashCode()); // 1247233941System.out.println("hello".hashCode()); // 99162322System.out.println("java".hashCode()); // 3254818System.out.println("hello".hashCode()); // 99162322System.out.println("重地".hashCode()); // 1179395System.out.println("通话".hashCode()); // 1179395}
- 同一个对象的哈希值是相同的
- 默认情况下,不同对象的哈希值是不同的,不过我们可以通过重写hashCode()方法来让不同对象的哈希值相同
HashSet
- 底层数据结构是哈希表
- 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
- 没有带索引的方法,所以不能使用普通for循环遍历
- 由于是Set集合,所以是部包含重复元素的集合
public static void main(String[] args) {HashSet<String> strings = new HashSet<>();strings.add("1"); // 注意此处开始的存储顺序是无序的strings.add("2");strings.add("6");strings.add("7");strings.add("3");strings.add("5");strings.add("4");strings.add("9");strings.add("10");for (String s:strings) {System.out.print(s + "\t"); // 1 2 3 4 5 6 7 9 10 取出的顺序与存储的顺序不一致}}
HashSet保证元素唯一性的过程
在存入数据时,HashSet会做以下操作
- 判断哈希表是否初始化,如果未初始化,则进行初始化
- 根据对象的哈希值计算对象的存储位置,如果该位置没有元素,则存储元素
- 存入的元素与以前的元素比较哈希值
- 如果哈希值不同,则存入元素
- 如果哈希值相同,则调用对象的equals()方法进行比较
- 如果不相同,则存入元素,如果相同,则说明重复,不存入元素
如果使用HashSet来存储并且遍历学生数组的话
HashSet<Student> hashSet = new HashSet<Student>();
Student s1 = new Student(1,"A",1);
Student s2 = new Student(1,"A",1);
hashSet.add(s1);
hashSet.add(s2);
// 两个对象都会存入
为了避免存储重复值的对象,我们需要在学生类中重写hashCode() 以及equals() 方法,使用快速重写自动生成方法即可
哈希表
哈希表底层采用数组 + 链表实现,可以说是一个元素为链表的数组
哈希表的默认长度为16
LinkedHashSet集合
LinkedHashSet集合的特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次序
- 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
- 由哈希表保证元素唯一,也就是说没有重复的元素
LinkedHashSet<String> linkedHashSet = new LinkedHashSet<String>();
TreeSet
TreeSet集合特点
- 元素会按照一定的规则排序,具体排序方式取决于构造方法
- TreeSet():根据元素的自然排序进行排序
- TreeSet( Comparator comparator ):根据指定的比较器进行排序
- 没有带索引的方法,所以不能用普通for循环遍历
- 由于是Set集合,所以不包含重复元素的集合
TreeSet<Integer> treeSet = new TreeSet<Integer>();
自然排序Comparable的使用
例题:使用TreeSet存储学生信息,并且按照年龄从小到大排序,年龄相同时,按照姓名的字母顺序排序
// Student.java
public class Student implements Comparable<Student>{private int number;private String name;private int age;public Student(int number,String name,int age){this.number = number;this.name = name;this.age = age;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}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;}@Overridepublic int compareTo(Student s) { // 重写compareTo方法
// return 0; // 返回0则认为该元素重复,不添加数据
// return 1; // 升序输出,如果没指定元素,只有return,则按照输入顺序升序输出
// return -1; // 降序输出int i = this.age - s.age; // this相当于s2 , o相当于s1int i2 = i==0?this.name.compareTo(s.name):i;return i2; // 如果为0则不添加,如果大于0则升序排序,如果小于0则降序排序}
}
// main.java
public static void main(String[] args) {TreeSet<Student> students = new TreeSet<Student>();students.add(new Student(1,"lbxx",4));students.add(new Student(2,"fjc",8));students.add(new Student(3,"ytnn",2));students.add(new Student(4,"ad",7));students.add(new Student(5,"zn",1));students.add(new Student(6,"cm",3)); // 年龄相同,则对姓名按照字母进行排序students.add(new Student(6,"bm",3));students.add(new Student(6,"am",3));for (Student s:students) {System.out.println(s.getNumber() + "\t\t" + s.getName() + "\t\t" + s.getAge());}}
/*
5 zn 1
3 ytnn 2
6 am 3
6 bm 3
6 cm 3
1 lbxx 4
4 ad 7
2 fjc 8
*/
比较器排序Comparator的使用
TreeSet<Student> students = new TreeSet<Student>(new Comparator<Student>() { // 匿名内部类重写方法@Overridepublic int compare(Student s1, Student s2) { // s1 则相当于 thisint num1 = s1.getAge() - s2.getAge(); // 不能访问属性,使用方法获取属性int num2 = num1 == 0 ? s1.getName().compareTo(s2.getName()) : num1;return num2;}});
- 用TreeSet集合存储自定义对象,带参构造方法使用的是比较器排序对元素进行排序的
- 比较器排序,就是**让集合构造方法接收Comparator的实现类对象,**重写compare( T o1 , T o2)方法
- 重写方法时,一定要注意排序规则必须按照要求的主要条件和次要条件来写
例题:用自然排序或比较器排序对学生进行总分排序,如果总分一样则按照姓名排序
// Students.javapublic class Students implements Comparable<Students>{ // 自然排序比较法private int id;private String name;private double chinese;private double math;private double english;private double sum;public Students(){}public Students( int id, String name, double chinese, double math, double english){this.id = id;this.name = name;this.chinese = chinese;this.math = math;this.english = english;this.sum = this.chinese + this.math + this.english;}public double getSum() {return sum;}public void setSum(float sum) {this.sum = sum;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public double getChinese() {return chinese;}public void setChinese(float chinese) {this.chinese = chinese;}public double getMath() {return math;}public void setMath(float math) {this.math = math;}public double getEnglish() {return english;}public void setEnglish(float english) {this.english = english;}@Overridepublic int compareTo(Students s) {int num = (int) (this.sum - s.sum);int num2 = num == 0 ? this.getName().compareTo(s.getName()) : num;return num2;}
}
// main.java
import java.util.*;public class main {public static void main(String[] args) {TreeSet<Students> students = new TreeSet<Students>(); // 自然排序法的TreeSet定义/*TreeSet<Students> students = new TreeSet<Students>(new Comparator<Students>() {@Overridepublic int compare(Students s1, Students s2) { // 比较器排序方法int num = (int) (s1.getSum() - s2.getSum());int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;return num2;}});*/ // 比较器排序法的TreeSet定义students.add(new Students(1,"d",65,78,45));students.add(new Students(2,"h",34,56,77));students.add(new Students(3,"r",23,46,89));students.add(new Students(4,"j",45,79,47));students.add(new Students(5,"q",54,68,98));students.add(new Students(6,"k",87,58,87));students.add(new Students(7,"m",27.5,64,79.5));Iterator<Students> it = students.iterator();while(it.hasNext()){Students s1 = new Students();s1 = it.next();System.out.println(s1.getId() + "\t\t" + s1.getName() + "\t\t" + s1.getChinese() + "\t\t" + s1.getMath() + "\t\t" + s1.getEnglish() + "\t\t" + s1.getSum());}}
}
如果使用比较器排序法,那么Students类就不用继承Comparable接口
Map集合
Map集合概述
- interface Map < K , V >:键值对
- 将键映射到值的对象,不能包含重复的键,每个键可以映射到最多一个值
创建Map集合
- 多态的方式
- 具体的实现类:HashMap
public static void main(String[] args) {Map<String, String> map = new HashMap<String , String>();map.put("翻斗花园","胡图图");map.put("春日部","蜡笔小新");map.put("清水市","樱桃小丸子");// map.put("清水市","野比大雄"); 如果新添加的数据和以前的数据键相同,但是值不相同,那么新的值就会把以前的值覆盖System.out.println(map); // {翻斗花园=胡图图, 春日部=蜡笔小新, 清水市=樱桃小丸子}// System.out.println(map); // {翻斗花园=胡图图, 春日部=蜡笔小新, 清水市=野比大雄}}
Map集合常用方法
- V put( K key , V value):添加元素,返回该键对应的值
- V remove( Object key):根据键值对删除元素,返回该键对应的值,如果没有则返回null
- void clear():移除所有键值对元素
- boolean containsKey( Object key ):判断集合是否包含指定的键
- boolean containsValue( Object value):判断集合是否包含指定的值
- boolean isEmpty():判断集合是否为空
- int size():集合的长度
public static void main(String[] args) {Map<String, String> map = new HashMap<String , String>();map.put("翻斗花园","胡图图");map.put("春日部","蜡笔小新");map.put("清水市","樱桃小丸子");System.out.println(map); // {翻斗花园=胡图图, 春日部=蜡笔小新, 清水市=樱桃小丸子}System.out.println(map.remove("翻斗花园")); // 胡图图System.out.println(map); // {春日部=蜡笔小新, 清水市=樱桃小丸子}System.out.println(map.containsKey("春日部")); // trueSystem.out.println(map.containsValue("樱桃小丸子")); // trueSystem.out.println(map.isEmpty()); // falseSystem.out.println(map.size()); // 2map.clear(); System.out.println(map); // {}}
Map集合的获取功能
- V get( Object key ):根据键获取值,返回获取的值,没有则返回null
- Set < K > KeySet():获取所有键的集合,键是唯一的,所以使用Set集合
- Collection < V > values():获取所有值的集合
- Set < Map.Entry < K , V > > entrySet():获取所有键值对对象的集合
public static void main(String[] args) {Map<String, String> map = new HashMap<String , String>();map.put("翻斗花园","胡图图");map.put("春日部","蜡笔小新");map.put("清水市","樱桃小丸子");System.out.println(map.get("春日部")); // 蜡笔小新Set<String> strings = map.keySet();for (String s:strings) {System.out.print(s + "\t"); // 翻斗花园 春日部 清水市 }System.out.println();Collection<String> values = map.values();for (String s:values) {System.out.print(s + "\t"); // 胡图图 蜡笔小新 樱桃小丸子}}
Map集合的遍历
方法1:先获取键所组成的集合,使用Map的 get() 方法来根据键寻找对应的值,然后进行输出
public static void main(String[] args) {Map<String, String> map = new HashMap<String , String>();map.put("翻斗花园","胡图图");map.put("春日部","蜡笔小新");map.put("清水市","樱桃小丸子");Set<String> strings = map.keySet();for (String s:strings) {System.out.println("key = " + s + "\tvalue = " + map.get(s));// key = 翻斗花园 value = 胡图图// key = 春日部 value = 蜡笔小新// key = 清水市 value = 樱桃小丸子}}
方法2:先获取所有键值对对象的集合,遍历集合,得到每一个键值对对象( Set < Map.Entry < K , V > > entrySet() )
public static void main(String[] args) {Map<String, String> map = new HashMap<String , String>();map.put("翻斗花园","胡图图");map.put("春日部","蜡笔小新");map.put("清水市","樱桃小丸子");Set<Map.Entry<String, String>> entries = map.entrySet();for (Map.Entry<String, String> s : entries){ // 注意此处接收对象的类型System.out.println("key = " + s.getKey() + "\tvalue = " + s.getValue());// key = 翻斗花园 value = 胡图图// key = 春日部 value = 蜡笔小新// key = 清水市 value = 樱桃小丸子}}
例题:HashMap存储学生数据并且遍历输出
// Student.java
public class Student {private int number;private String name;private int age;public Student(int number,String name,int age){this.number = number;this.name = name;this.age = age;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}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;}}
// main.java
public static void main(String[] args) {Map<String, Student> map = new HashMap<>();map.put("A",new Student(1,"蜡笔小新",5));map.put("B",new Student(2,"风间彻",5));map.put("C",new Student(3,"樱田妮妮",5));Set<Map.Entry<String, Student>> entries = map.entrySet();for ( Map.Entry<String, Student> s: entries) {System.out.println("key = " + s.getKey() + "\t学号为:" + s.getValue().getNumber() + "\t姓名为:" + s.getValue().getName() + "\t年龄为:" + s.getValue().getAge());// key = A 学号为:1 姓名为:蜡笔小新 年龄为:5// key = B 学号为:2 姓名为:风间彻 年龄为:5// key = C 学号为:3 姓名为:樱田妮妮 年龄为:5}}
例题:HashMap存储学生数据,以学生为键,地址为值进行存储并遍历,如果学生对象的成员变量值相同,我们就认为是同一个对象
// Student.java
import java.util.Comparator;
import java.util.Objects;public class Student{private int number;private String name;private int age;public Student(int number,String name,int age){this.number = number;this.name = name;this.age = age;}public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}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;}@Overridepublic boolean equals(Object o) { // equals()方法if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;Student student = (Student) o;return number == student.number &&age == student.age &&Objects.equals(name, student.name);}@Overridepublic int hashCode() { // hashCode()方法return Objects.hash(number, name, age);}
}
// main.java
import java.util.*;public class Demo{public static void main(String[] args) {Map<Student, String> map = new HashMap<>();map.put(new Student(1,"蜡笔小新",5),"春日部");map.put(new Student(2,"风间彻",5),"向日葵班");map.put(new Student(3,"樱田妮妮",5),"双叶幼稚园");map.put(new Student(1,"蜡笔小新",5),"日本"); // 用来测试重复学生数据的覆盖Set<Map.Entry<Student, String>> entries = map.entrySet();for ( Map.Entry<Student, String> s: entries) {System.out.println("居住地为:" + s.getValue() + "\t学号为:" + s.getKey().getNumber() + "\t姓名为:" + s.getKey().getName() + "\t年龄为:" + s.getKey().getAge());// 居住地为:向日葵班 学号为:2 姓名为:风间彻 年龄为:5// 居住地为:双叶幼稚园 学号为:3 姓名为:樱田妮妮 年龄为:5// 居住地为:日本 学号为:1 姓名为:蜡笔小新 年龄为:5}}}
关于生成hashCode() 和 equals() 方法,IDEA中在Student类中使用 alt + insert 快捷键,选中equals() 和 hashCode() 方法进行生成
一路默认下一步即可。
ArrayList嵌套HashMap
public static void main(String[] args) {ArrayList<Map<String, String>> array = new ArrayList<>();Map<String, String> map1 = new HashMap<String,String>();map1.put("春日部","蜡笔小新");map1.put("唐","杜甫");Map<String, String> map2 = new HashMap<String,String>();map2.put("清水","樱桃小丸子");map2.put("唐","李白");Map<String, String> map3 = new HashMap<String,String>();map3.put("翻斗花园","胡图图");map3.put("明","朱熹");array.add(map1);array.add(map2);array.add(map3);int count = 1;for (Map<String, String> s:array) {System.out.println("这是ArrayList中的第" + count + "组数据");for (Map.Entry<String, String> a:s.entrySet()) {System.out.println("键为:" + a.getKey() + "\t值为:" + a.getValue());}count++;}/*for (Map<String, String> s:array) { // 第二种遍历方法Set<String> strings = s.keySet();System.out.println("这是ArrayList中的第" + count + "组数据");for (String key:strings) { // key为键String value = s.get(key);System.out.println("键为:" + key + "\t值为:" + value);}count++;}*/}/* 这是ArrayList中的第1组数据键为:唐 值为:杜甫键为:春日部 值为:蜡笔小新这是ArrayList中的第2组数据键为:唐 值为:李白键为:清水 值为:樱桃小丸子这是ArrayList中的第3组数据键为:翻斗花园 值为:胡图图键为:明 值为:朱熹 */
HashMap嵌套ArrayList
public static void main(String[] args) {Map<String, ArrayList<String>> map = new HashMap<>();ArrayList<String> array1 = new ArrayList<String>();array1.add("Java");array1.add("JavaScript");ArrayList<String> array2 = new ArrayList<String>();array2.add("Sql");array2.add("MySql");ArrayList<String> array3 = new ArrayList<String>();array3.add("MyBaits");array3.add("Spring");map.put("A",array1);map.put("B",array2);map.put("C",array3);Set<Map.Entry<String, ArrayList<String>>> entries = map.entrySet();int count = 1;for (Map.Entry<String, ArrayList<String>> s:entries) {System.out.println("这是HashMap中的第" + count + "组数据");ArrayList<String> value = s.getValue();System.out.print("键为:" + s.getKey() + "\t值数组为:");for (String val:value) { // val为ArrayList数组System.out.print(val + "\t");}System.out.println();count++;}}
/* 这是HashMap中的第1组数据键为:A 值数组为:Java JavaScript 这是HashMap中的第2组数据键为:B 值数组为:Sql MySql 这是HashMap中的第3组数据键为:C 值数组为:MyBaits Spring */
统计字符串中每个字符出现次数
要求从键盘输入字符串,输出格式如下a(1)b(2)c(3)…
分析:因为要统计次数,所以我们设置 HashMap 中键为字符,值为次数, HashMap< Character , Integer >。将字符作为键,保证键唯一,才能进行次数统计。在录入集合的过程中,如果这个键值在集合中不存在,则存入键,设置值为1;如果这个键已经存在了,那就让值加一之后,重新将键和值存入集合,键因为存在,所以新值会覆盖旧值。
public static void main(String[] args) {Scanner sc = new Scanner(System.in);System.out.println("请输入字符串:");String line = sc.nextLine(); // 获取输入的字符串 acddbegladgingmHashMap<Character, Integer> hashMap = new HashMap<Character, Integer>(); // 设置 HashMap// 如果使用HashMap,有的时候输出并不会按照字符进行排序,这时我们可以改用 TreeMap// TreeMap<Character, Integer> hashMap = new TreeMap<Character, Integer>();// TreeMap会对键进行排序for (int i = 0; i < line.length(); i++) {char key = line.charAt(i); // 循环设置keyInteger value = hashMap.get(key); // 获取该键对应的值if(value == null){ // 值为null表示该键不存在hashMap.put(key,1); // 存入键,设置值为1}else{ // 该键已经存在了value++; // 让值加一hashMap.put(key,value); // 重新存入集合}}StringBuilder str = new StringBuilder(); // 用StringBuilder来设置输出格式Set<Map.Entry<Character, Integer>> entries = hashMap.entrySet();for (Map.Entry<Character, Integer> s:entries) {str.append(s.getKey()).append("(").append(s.getValue()).append(")");}System.out.println(str.toString()); // a(2)b(1)c(1)d(3)e(1)g(3)i(1)l(1)m(1)n(1)}
如果要对键进行排序,那么就使用TreeMap
Collections
Collections类的概述
是针对集合操作的工具类
Collections类的常用方法
- public static < T extends Comparable< ? super T > > void sort( List < T > list )::将指定的列表按升序排序
- public static void reverse( List < ? > list ):反转指定列表中元素的顺序
- public static shufflereverse( List < ? > list ):使用默认的随机源随机排列指定的列表。也就是每次调用随机排列元素
public static void main(String[] args) {List<Integer> list = new ArrayList<>();for(int i = 0 ; i < 10 ; i++){Random num = new Random();list.add(num.nextInt(20) + 1);}System.out.println(list); // [2, 4, 9, 5, 2, 20, 8, 6, 19, 10]Collections.sort(list);System.out.println(list); // [2, 2, 4, 5, 6, 8, 9, 10, 19, 20]Collections.reverse(list);System.out.println(list); // [20, 19, 10, 9, 8, 6, 5, 4, 2, 2]Collections.shuffle(list); // 每一次调用都会重新随机排列System.out.println(list); // [8, 19, 4, 20, 5, 2, 9, 2, 10, 6]Collections.shuffle(list);System.out.println(list); // [10, 20, 9, 4, 2, 2, 19, 6, 5, 8]}
Java中的集合(Collection,Map)相关推荐
- Java中Set集合是如何实现添加元素保证不重复的?
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | 公众号「武培轩」 Java中Set集合是如何实 ...
- 万字长文深入理解java中的集合-附PDF下载
文章目录 1. 前言 2. List 2.1 fail-safe fail-fast知多少 2.1.1 Fail-fast Iterator 2.1.2 Fail-fast 的原理 2.1.3 Fai ...
- (转)java中对集合对象list的几种循环访问总结
Java集合的Stack.Queue.Map的遍历 在集合操作中,常常离不开对集合的遍历,对集合遍历一般来说一个foreach就搞定了,但是,对于Stack.Queue.Map类型的遍历,还是有一些讲 ...
- java中的集合框架_JAVA中的集合框架(上)List
第一节 JAVA中的集合框架概述 集合的概念,现实生活中:很多事物凑在一起就是一个集合:数学中的集合:具有相同属性事物的总体:JAVA中的集合:是一种工具类,就像是容器,储存任意数量的具有共同属性的对 ...
- java中各种集合的用法和比较
一,java中各种集合的关系图 Collection 接口的接口 对象的集合 ├ List 子接口 按进入先后有序保存 可重复 │├ L ...
- java 中的集合_JAVA中的集合
JAVA中集合,是java中的基础概念,今天接着跟讲课准备课件的机会,重新整理一下关于JAVA中的集合的概念. 集合的概念 java中的集合类是用来存放对象的 集合相当于一个容器,里面包容着一组对象- ...
- JAVA中的集合概念
JAVA中的集合: 集合的概念:一种操作方便的对象容器,可以存储并管理多个对象(存储管理多个对象的一种工具),很多时候替换数组 集合相关的内容位于java.util包中,使用需要导包: 集合的分类:c ...
- java list 前100个_实现java 中 list集合中有几十万条数据,每100条为一组取出
解决"java 中 list集合中有几十万条数据,每100条为一组取出来如何实现,求代码!!!"的问题. 具体解决方案如下: /** * 实现java 中 list集合中有几十万条 ...
- Java中的集合浅析
java中的集合就像是一个容器一样,专门用来存储java对象的引用,这些对象可以是任意的数据类型并且长度可变,集合类位于java.util包中. java集合按照其存储结构可以分为两大类,一个是单列集 ...
- 二十三、JAVA中的Set和Map
JAVA中的Set和Map 1. Set接口 1.1 概述 1.2 特点 1.3 常用方法 1.4 案例 测试常用方法 2. HashSet 2.1 概述 2.2 案例 获取HashSet里的元素 3 ...
最新文章
- linux如何编译tex,Linux下优秀的文本编辑器(Markdown、LaTeX、MathJax)
- System.Security.Cryptography.CryptographicException,密钥集不存在
- 如何实现DataGridView实时更新数据【Z】
- 7.1Python异常处理
- License分类 + 引入开源软件时License的注意事项
- linux分区设置大小,Linux调整磁盘分区大小
- 作者:牟少敏,博士,山东农业大学教授。
- Python打包文件为exe,PyInstaller应用
- Git Flow分支管理
- ES6(三)——回调地狱和promise异步任务顺序执行(传参、错误处理)
- 2、Android构建本地单元测试
- vt linux tty中文,Linux输入子系统和tty关系影述
- gtest测试代码编写思想
- 计算机中硬盘驱动器安装在哪里,解决方法:在笔记本电脑中安装硬盘驱动器的步骤如何在笔记本电脑中安装硬盘驱动器...
- KNX智能照明系统在福安中医院的应用
- 锂电池充电——充电保护电路
- Cadence PVS (Physical Verification System) rule 语法详解
- vscode代码自动保存插件_VSCode 云同步扩展设置 Settings Sync 插件
- 微信关注二维码不显示
- 人人皆可二次元!小姐姐生成不同风格动漫形象,肤色、发型皆可变
热门文章
- 清风数学建模--回归系数的解释
- 传统串口设备快速实现联网的解决方案(串口-以太网网关、Modbus网关、Modbus Poll/Slave调试软件的使用、Modbus报文数据实例分析)
- 《2019秋招腾讯、招银面试问题》
- HydraJohn的简单使用
- 91sp.vido.ws.php,104.27.179.100
- python list输出去掉中括号_Python 输出时去掉列表元组外面的方括号与圆括号的方法...
- 【PE/makefile】编译标记EXTRA_CFLAGS介绍和使用方法
- 新浪的开放云计算平台Sina App Engine
- 独立产品灵感周刊 DecoHack #024 - 90年代的网站设计
- matlab中威布尔函数的概率分布