欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Java中的集合(Collection,Map)

程序员文章站 2024-03-06 08:44:25
...

集合类体系结构

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));	// JavaWeb
        System.out.println(list.remove("And"));	// true
        System.out.println(list.set(1,"OvO"));	// Love
        System.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());	// Love
        System.out.println(strings.getLast());	// Java
        System.out.println(strings.removeFirst());	// Love
        System.out.println(strings.removeLast());	// Java
        System.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());  // 1160460865
        System.out.println(s2.hashCode());  // 1247233941
        System.out.println("hello".hashCode()); // 99162322
        System.out.println("java".hashCode());  // 3254818
        System.out.println("hello".hashCode()); // 99162322
        System.out.println("重地".hashCode());    // 1179395
        System.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会做以下操作

  1. 判断哈希表是否初始化,如果未初始化,则进行初始化
  2. 根据对象的哈希值计算对象的存储位置,如果该位置没有元素,则存储元素
  3. 存入的元素与以前的元素比较哈希值
  4. 如果哈希值不同,则存入元素
  5. 如果哈希值相同,则调用对象的equals()方法进行比较
  6. 如果不相同,则存入元素,如果相同,则说明重复,不存入元素

如果使用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

Java中的集合(Collection,Map)


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;
    }

    @Override
    public int compareTo(Student s) {	// 重写compareTo方法
//        return 0;   // 返回0则认为该元素重复,不添加数据
//        return 1;   // 升序输出,如果没指定元素,只有return,则按照输入顺序升序输出
//        return -1;  // 降序输出
        int i = this.age - s.age;   // this相当于s2 , o相当于s1
        int 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>() {	// 匿名内部类重写方法
            @Override
            public int compare(Student s1, Student s2) {	// s1 则相当于 this
                int 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.java

public 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;
    }

    @Override
    public 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>() {
            @Override
            public 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("春日部"));	// true
        System.out.println(map.containsValue("樱桃小丸子"));	// true
        System.out.println(map.isEmpty());	// false
        System.out.println(map.size());	// 2
        map.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;
    }

    @Override
    public 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);
    }

    @Override
    public 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() 方法进行生成
Java中的集合(Collection,Map)
Java中的集合(Collection,Map)

一路默认下一步即可。

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();	// 获取输入的字符串		acddbegladgingm
        HashMap<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);	// 循环设置key
            Integer 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]
    }