【JavaSE 知识框架】09 Java集合


第08章 Java集合

创作日期:2021-11-11


1.Java集合框架概述

1.1 数组到集合的引申

        面向对象语言对事物的体现都是以对象的形式,为了方便对多个对象的操作,就要对对象进行存储。另一方面,使用Array存储对象方面具有一些弊端,而Java集合就像是一种容器,可以动态地把多个对象的引用放入容器中,还可用于保存具有映射关系的关联数组。

数组在内存存储方面的特点:

  • 数组初始化以后,长度就确定了
  • 数组声明的类型,就决定了进行元素初始化时的类型

数组在存储数据方面的弊端:

  • 数组初始化以后,长度就不可改变了,不便于扩展
  • 数组中提供的属性和方法少,不便于进行添加,删除,插入等操作,且效率不高,同时无法直接获取存储元素的个数
  • 数组存储的数据是有序的,可以重复的,存储数据的特点比较单一 

1.2 Java集合的框架体系

Java集合可分为 Collection 和 Map 两种体系:

  • Collection接口:单列数据,定义了存取一组对象的方法的集合
    • List:元素有序,可重复的集合
    • Set:元素无序,不可重复的集合
  • Map接口:双列数据,保存具有影射关系“key-value”键值对的集合

Collection接口继承树

Map接口继承树


2.Collection的接口方法

import java.util.*;

/**
 * Welcome to Idea Java
 *
 * @author Administrator
 * @date 2021/11/26 8:29
 **/
public class CollectionTest {
    public static void main(String[] args) {
        Collection collection1 = new ArrayList();

        //add(Object e):将元素e添加到集合collection中
        collection1.add(123);
        collection1.add("lisi");
        collection1.add(new Date());
        System.out.println(collection1);// [123, lisi, Fri Nov 26 08:36:35 CST 2021]

        //size():获取元素个数
        System.out.println(collection1.size());// 3

        //addAll():将集合a中的元素全部添加到集合b中
        Collection collection2 = new ArrayList();
        collection2.addAll(collection1);
        System.out.println(collection2);// [123, lisi, Fri Nov 26 08:39:39 CST 2021]

        //clear():将集合元素清空
        collection2.clear();

        //isEmpty():判断集合是否为空
        System.out.println(collection2.isEmpty());// true

        //contains(Object):判断集合是否包含某个元素
        System.out.println(collection1.contains("lisi"));// true

        //containsAll(Collection b):判断集合b中的元素是否都存在于集合a中
        collection2.add("zan");
        collection2.add("lisi");
        System.out.println(collection1.containsAll(collection2));// false

        //remove():移除集合中的某个元素
        System.out.println(collection1.remove("lisi"));// true
        System.out.println(collection1);// [123, Fri Nov 26 08:48:22 CST 2021]

        //removeAll():从当前集合a中移除与集合b中相同的所有元素
        collection2.add(123);
        System.out.println(collection2);// [zan, lisi, 123]
        System.out.println(collection2.removeAll(collection1));// true
        System.out.println(collection1);// [123, Fri Nov 26 08:55:48 CST 2021]
        System.out.println(collection2);// [zan, lisi]

        //retainAll():获取当前集合a与集合b中的交集,并返回给当前集合
        collection1.add("lisi");
        System.out.println(collection1);//[123, Fri Nov 26 08:58:37 CST 2021, lisi]
        System.out.println(collection1.retainAll(collection2));// true
        System.out.println(collection1);// [lisi]

        //equals():判断集合a与集合b是否相同,需要元素全部相同才能返回true
        System.out.println(collection1.equals(collection2)); // false
        Collection collection3 = new ArrayList();
        collection3.add("lisi");
        System.out.println(collection1.equals(collection3));// true

        //hashCode():返回当前集合的哈希值
        System.out.println(collection1.hashCode());

        //toArray():集合向数组的转型
        Object[] objects = collection2.toArray();
        System.out.println(Arrays.toString(objects)); // [zan, lisi]

        //toList():数组向集合的转型
        List<Object> objects1 = Arrays.stream(objects).toList();
        System.out.println(objects1);// [zan, lisi]
    }
}

3.Iterator迭代器遍历集合

3.1  Iterator迭代器的概述

  • Iterator对象称为迭代器(设计模式的一种),主要用于遍历Collection集合中的元素。
  • GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。
  • Collection接口继承了java.lang.Iterable接口,该接口有一个itreator()方法,那么所有实现了Collection接口的集合类都有一个treator()方法,用以返回一个实现了Iterator接口的对象。
  • Iterator仅用于遍历集合,Iterator本身并不提供承装对象的能力。如果需要创建Iterator对象,则必须有一个被迭代的集合。
  • 集合对象每次调用itreator()方法都得到一个全新的迭代对象,默认游标都在集合的第一个元素之前。

3.2  Iterator迭代器的使用

import java.util.*;

// 集合元素的遍历操作 使用迭代器Iterator接口
public class CollectionTest {
    public static void main(String[] args) {
        Collection collection1 = new ArrayList();
        collection1.add(123);
        collection1.add("lisi");
        collection1.add(new Date());

        //集合实现Iterator接口
        Iterator iterator = collection1.iterator();
        //使用迭代器Iterator接口对象循环遍历
        while(iterator.hasNext()){
            //hasNext():判断是否还有下一个元素
            //next():指针下移,将下移以后集合位置上的元素返回
            System.out.println(iterator.next());
        }
        
        //使用迭代器remove()方法对集合元素进行删除
        Iterator iterator1 = collection1.iterator();
        while(iterator1.hasNext()){
            Object next = iterator1.next();
            if ("lisi".equals(next)){
                iterator1.remove();
            }
        }
    }
}

        注意:Iterator可以删除集合的元素,但是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法;若果还未调用next()或在上一次调用next方法之后已经调用了remove方法,再调用remove都会报异常。

3.3 集合遍历的另一种实现方式

增强for循环:foreach()的使用:

import java.util.*;

// 增强for循环:foreach()的使用
public class CollectionTest {
    public static void main(String[] args) {
        Collection collection1 = new ArrayList();
        collection1.add(123);
        collection1.add("lisi");
        collection1.add(new Date());

        for (Object o:collection1) {
            System.out.println(o);
        }
    }
}

4.Collection子接口一:List

4.1 List接口概述

  • 鉴于Java中数组用来存储数据的局限性,我们通常使用List替代数组
  • List集合类中元素有序,且可重复,集合中的每个元素都具有其对应的顺序索引。
  • List容器中的元素都对应一个整数型的序号记载其在容器中的位置,可以根据序号存取容器中的元素。
  • JDK API中List接口的实现类常用的有:ArrayList,LinkedList和Vector。       

4.2 List接口的方法

        List除了从Collection集合继承的方法外,List集合还添加了一些根据索引来操作集合元素的方法:

  • void add(int index,Object ele):在index位置插入ele元素
  • boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
  • Object get(int index):获取指定index位置的元素
  • int indexOf(Object obj):返回obj在当前集合中首次出现的位置
  • int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
  • Object remove(int index):移除指定index位置的元素,并返回此元素
  • Object set(int index,Object obj):设置指定index位置的元素为ele
  • List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
import java.util.*;
//List接口的方法
public class CollectionTest {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        ArrayList arrayList1 = new ArrayList();

        arrayList.add(1);
        arrayList.add(3);
        arrayList.add(5);
        arrayList.add(6);

        arrayList1.add(4);

        //void add(int index,Object ele):在index位置插入ele元素
        arrayList.add(1,2);
        System.out.println(arrayList);//[1, 2, 3, 5, 6]

        //boolean addAll(int index,Collection eles):从index位置开始将eles中的所有元素添加进来
        arrayList.addAll(3,arrayList1);
        System.out.println(arrayList);//[1, 2, 3, 4, 5, 6]

        //Object get(int index):获取指定index位置的元素
        System.out.println(arrayList.get(1));//2

        //int indexOf(Object obj):返回obj在当前集合中首次出现的位置
        System.out.println(arrayList.indexOf(1));//0

        //int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
        System.out.println(arrayList.lastIndexOf(1));//0

        //Object remove(int index):移除指定index位置的元素,并返回此元素
        System.out.println(arrayList1);//[4]
        System.out.println(arrayList1.remove(0));//4
        System.out.println(arrayList1);//[]

        //Object set(int index,Object obj):设置指定index位置的元素为ele
        System.out.println(arrayList);//[1, 2, 3, 4, 5, 6]
        arrayList.set(0,0);
        System.out.println(arrayList);//[0, 2, 3, 4, 5, 6]

        //List subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合
        System.out.println(arrayList.subList(1,6));//[2, 3, 4, 5, 6]

    }
}

4.3 List实现类之一:ArrayList

  • ArrayList是List接口的典型实现类,主要实现类
  • 本质上,ArrayList是对象引用的一个”变长“数组
  • ArrayList的JDK 1.8之前与之后的实现区别?
    • JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组
    • JDK1.8:ArrayList像懒汉式,一开始创建一个长度为0的数组,当添加一个元素时再创建一个容量为10的数组
  • ArrayList.asList()方法返回的List集合,既不是ArrayList实例,也不是Vector实例。ArrayList.asList()方法返回值是一个固定长度的List集合

4.4 List实现类之二:LinkedList

        LinkedList:双向链表,内部没有声明数组。而定义了Node类型的first和last,用于记录首末元素。同时,定义内部类Node,作为LinkedList中保存数据的基本结构,对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高。Ndoe除了保存数据,还定义了两个变量: prev:变量记录前一个元素的位置;next:变量记录下一个元素的位置。

新增方法:

  • void addFirst(Object obj)
  • void addLast(Object obj)
  • Object getFirst()
  • Object getLast()
  • Object removeFirst()            
  • Object removeLast()

4.5 List实现类之三:Vector

  • Vector的内部实现类似于ArrayList,Vector也是基于一个容量能够动态增长的数组来实现的,该类是JDK1.0版本添加的类,它的很多实现方法都加入了同步语句,因此是线程安全的(但Vector其实也只是相对安全,有些时候还是要加入同步语句来保证线程的安全)。        
  • Vector继承于AbstractList,实现了List接口,可以对它进行队列操作;实现了RandmoAccess接口,即提供了随机访问功能;实现了Cloneable接口,能被克隆;实现了Serializable接口,因此它支持序列化,能够通过序列化传输。

4.6 ArrayList,LinkedList,Vector三者的异同

  • ArrayList:作为List接口的主要实现类,线程不安全,效率高,底层使用Object[] elementData存储。
  • LinkedList:对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率比
  • ArrayList高,底层使用双向链表。
  • Vector:作为List接口的古老实现类,线程安全,效率低,底层使用Object[] elementData存储。

5.Collection子接口二:Set

5.1 Set接口概述

Set:存储无序的,不可重复的数据

  • 无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。
  • 不可重复性:保证添加的元素按照equals()判断时,不能返回true。即相同的元素只能添加一个。
  • Set接口是Collection的子接口,set接口没有提供额外的方法
  • Set集合不允许包含相同的元素,如果试着把两个相同的元素加入同一个Set集合中,则添加操作失败。
  • Set判断两个对象是否相同不是使用 == 运算符,而是根据equals()方法

5.2 Set实现类之一:HashSet

  • HashSet 是Set 接口的典型实现,大多数时候使用Set集合时都使用这个实现类。
  • HashSet 按 Hash算法来存储集合中的元素,因此具有很好的存取,查找,删除性能。
  • HashSet 具有以下特点:不能保证元素的排列顺序;HashSet不是线程安全;集合元素可以说null
  • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode()方法比较相等,并且两个对象的 equals()方法返回值也相等。
  • 对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等原则。即:“相等的对象必须具有相等的散列码”。

5.3 Set实现类之二:LinkedHashSet

  • LinkedHashSet是HashSet的子类
  • LinkedHashSet根据元素的hashCode值来决定元素的存储位置,但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入顺序保存的。
  • LinkedHashSet插入性能略低于HashSet,但在迭代访问Set里的全部元素时有很好的性能。
  • LinkedHashSet不允许集合元素重复。

5.4 Set实现类之二:TreeSet

  • TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。
  • TreeSet底层使用红黑树结构存储数据
  • 新增的方法如下:(了解)
    • Comparator comparator()
    • Object first()
    • Object last()
    • Object lower(Object e)
    • Object higher(Object e)  
    • SortedSet subSet(fromElement,toElement)
    • SortedSet headSet(toElement)
    • SortedSet tailSet(fromElement)              
  • TreeSet 两种排序方法:自然排序和定制排序。默认情况下,ThreeSet采用自然排序。

5.5 TreeSet的练习实例

import java.util.Comparator;
import java.util.TreeSet;

/**
 * Welcome to Idea Java
 *
 * @author Administrator
 * @date 2021/11/27 9:55
 **/
public class SetTest {
    public static void main(String[] args) {

        //为treeSet设置定制排排序,安装生日进行排序,每次创建都进行对比排序
        TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if (o1 instanceof Employee && o2 instanceof Employee) {
                    Employee employee1 = (Employee) o1;
                    Employee employee2 = (Employee) o2;

                    MyData data1 = employee1.getBirthday();
                    MyData data2 = employee2.getBirthday();

                    int minYear = data1.getYear() - data2.getYear();
                    if (minYear != 0) return minYear;
                    int minMouth = data1.getMonth() - data2.getMonth();
                    if (minMouth != 0) return minMouth;
                    return data1.getDay() - data2.getDay();
                }
                return 0;
            }
        });

        Employee employee1 = new Employee("阿哥", 12, new MyData(1998, 03, 25));
        Employee employee2 = new Employee("曹哥", 45, new MyData(1991, 02, 03));
        Employee employee3 = new Employee("一哥", 25, new MyData(1988, 05, 22));
        Employee employee4 = new Employee("帝哥", 50, new MyData(1988, 05, 13));
        Employee employee5 = new Employee("逼哥", 30, new MyData(1977, 12, 18));

        treeSet.add(employee1);
        treeSet.add(employee2);
        treeSet.add(employee3);
        treeSet.add(employee4);
        treeSet.add(employee5);

        for (Object O : treeSet) {
            System.out.println(O);
        }

    }
}

//Employee类
class Employee implements Comparable {
    private String name;
    private int age;
    private MyData birthday;

    public Employee() {
    }

    public Employee(String name, int age, MyData birthday) {
        this.name = name;
        this.age = age;
        this.birthday = birthday;
    }

    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 MyData getBirthday() {
        return birthday;
    }

    public void setBirthday(MyData birthday) {
        this.birthday = birthday;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", birthday=" + birthday +
                '}';
    }

    //Employee实现Comparable接口,按照name排序,自然排序
    @Override
    public int compareTo(Object o) {
        if (o instanceof Employee) {
            Employee e = (Employee) o;
            return e.name.compareTo(this.name);
        }
        return 0;
    }
}

//MyData类
class MyData {
    private int year;
    private int month;
    private int day;

    public MyData() {
    }

    public MyData(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    @Override
    public String toString() {
        return "MyData{" +
                "year=" + year +
                ", month=" + month +
                ", day=" + day +
                '}';
    }
}

6.Map接口

6.1 Map接口继承树

6.2 Map的实现类结构 

  • Map:双列数据,存储key-value对的数据
  • HashMap:作为Map的主要实现类,线程不安全,效率高,存储null的key和value,底层:数据+链表+红黑树
  • LinkedHashMap:保证在遍历Map元素时,可以按照添加的顺序实现遍历;在原有的HashMap基础上,添加了一对指针,指向前一个和后一个;对于频繁的遍历操作,此类执行效率高于HashMap
  • TreeMap:保证安装添加的key-value对进行排序,实现排序遍历,此时考虑key的自然排序或定制排序,底层使用红黑树
  • Hashtable:古老的实现类:线程安全,效率低,不能存储null的key和value
  • Properties:常用来处理配置文件,key和value都是String类型

6.3 Map接口的理解

  • Map中的key:无序的,不可重复的。使用Set存储所有的key,key所在的类要重写equals()方法和hashCode()方法。
  • Map中的value:无序的,可重复的,使用Collection存储所有的value,value所在的类要实现equals()方法。
  • Map中的entry:一个键值对:key-value构成了一个Entry对象,无序的,不可重复的,使用Set存储所有的entry。

6.4 Map接口中的常用方法

  • 添加,删除,修改操作
    • Object put(Object key,Object value):将指定键值对添加到或修改当前map对象当中

    • void putAll(Map m):将m中的所有键值对存放到当前map中

    • void clear():清空当前map中的所有数据

import java.util.HashMap;
import java.util.Map;

public class MapTest {
    public static void main(String[] args) {
        Map map1 = new HashMap();
        //Object put(Object key,Object value):将指定键值对添加到或修改当前map对象当中
        map1.put("lisi",1);
        map1.put("zhangsan",2);
        map1.put("wanger",3);
        System.out.println(map1);//{lisi=1, zhangsan=2, wanger=3}

        Map map2 = new HashMap();
        map2.put("mazi",4);
        System.out.println(map2);//{mazi=4}

        //void putAll(Map m):将m中的所有键值对存放到当前map中
        map1.putAll(map2);
        System.out.println(map1);//{mazi=4, lisi=1, zhangsan=2, wanger=3}

        //void clear():清空当前map中的所有数据
        map2.clear();
        System.out.println(map2);//{}
    }
}
  • 元素查询的操作
    • Object get(Object  key):获取指定key对应的value
    • boolean containsKey(Object  key):是否包含指定的key
    • boolean containsValue(Object  value):是否包含指定的value
    • int size():返回Map中键值对的个数
    • boolean isEmpty():判断当前Map是否为空
    • boolean equals(Object obj):判断当前map和参数对象obj是否相等
import java.util.HashMap;
import java.util.Map;

public class MapTest {
    public static void main(String[] args) {
        Map map1 = new HashMap();
        map1.put("lisi",1);
        map1.put("zhangsan",2);
        map1.put("wanger",3);
        System.out.println(map1);//{lisi=1, zhangsan=2, wanger=3}

        Map map2 = new HashMap();
        map2.put("mazi",4);
        System.out.println(map2);//{mazi=4}

        //Object get(Object  key):获取指定key对应的value
        System.out.println(map1.get("wanger"));//3

        //boolean containsKey(Object key):是否包含指定的key
        System.out.println(map2.containsKey("zhangsan"));//false

        //boolean containsValue(Object value):是否包含指定的value
        System.out.println(map2.containsValue(4));//true

        //int size():返回Map中键值对的个数
        System.out.println(map1.size());//3

        //boolean isEmpty():判断当前Map是否为空
        System.out.println(map2.isEmpty());//false

        //boolean equals(Object obj):判断当前map和参数对象obj是否相等
        System.out.println(map1.equals(map2));//false
    }
}import java.util.HashMap;
import java.util.Map;

public class MapTest {
    public static void main(String[] args) {
        Map map1 = new HashMap();
        map1.put("lisi",1);
        map1.put("zhangsan",2);
        map1.put("wanger",3);
        System.out.println(map1);//{lisi=1, zhangsan=2, wanger=3}

        Map map2 = new HashMap();
        map2.put("mazi",4);
        System.out.println(map2);//{mazi=4}

        //Object get(Object  key):获取指定key对应的value
        System.out.println(map1.get("wanger"));//3

        //boolean containsKey(Object key):是否包含指定的key
        System.out.println(map2.containsKey("zhangsan"));//false

        //boolean containsValue(Object value):是否包含指定的value
        System.out.println(map2.containsValue(4));//true

        //int size():返回Map中键值对的个数
        System.out.println(map1.size());//3

        //boolean isEmpty():判断当前Map是否为空
        System.out.println(map2.isEmpty());//false

        //boolean equals(Object obj):判断当前map和参数对象obj是否相等
        System.out.println(map1.equals(map2));//false
    }
}
  • 元视图操作的方法
    • Set keySet():返回所有的key构成的Set集合
    • Collection values:返回所有value构成的Collection集合
    • Set entrySet():返回所有的键值对构成的Set集合
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

public class MapTest {
    public static void main(String[] args) {
        Map map1 = new HashMap();
        map1.put("lisi",1);
        map1.put("zhangsan",2);
        map1.put("wanger",3);
        System.out.println(map1);//{lisi=1, zhangsan=2, wanger=3}

        Map map2 = new HashMap();
        map2.put("mazi",4);
        System.out.println(map2);//{mazi=4}

        //Set keySet():返回所有的key构成的Set集合
        Set set1 = map1.keySet();
        System.out.println(set1);//[lisi, zhangsan, wanger]

        //Collection values:返回所有value构成的Collection集合
        Collection values = map1.values();
        System.out.println(values);//[1, 2, 3]

        //Set entrySet():返回所有的键值对构成的Set集合
        Set set2 = map1.entrySet();
        System.out.println(set2);//[lisi=1, zhangsan=2, wanger=3]
    }
}

7.Cllections工具类

7.1 Cllections工具类的概述

  • Collections是一个操作Set,List和Map等集合的工具类
  • Collections中提供了一系列静态的方法对集合元素进行排序,查询和修改操作,还提供了对集合对象设置不可变,对集合对象实现同步控制等方法
  • 排序操作:(均为static方法)
    • reverse(List):反转List中元素的顺序
    • shuffle(List):对List集合元素进行随机排序
    • sort(List):根据元素的自然顺序对指定List集合元素按升序排序
    • sort(List,Comparator):根据指定的Comparator产生的顺序对List集合元素进行排序
    • swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
import java.util.*;

public class MapTest {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        System.out.println(list);//[1, 2, 3, 4]

        //reverse(List):反转List中元素的顺序
        Collections.reverse(list);
        System.out.println(list);//[4, 3, 2, 1]

        //shuffle(List):对List集合元素进行随机排序
        Collections.shuffle(list);
        System.out.println(list);//[3, 4, 2, 1]

        //sort(List):根据元素的自然顺序对指定List集合元素按升序排序
        Collections.sort(list);
        System.out.println(list);//[1, 2, 3, 4]

        //swap(List,int,int):将指定list集合中的i处元素和j处元素进行交换
        Collections.swap(list,0,3);
        System.out.println(list);//[4, 2, 3, 1]
    }
}

7.2 Collections常用方法

  • 查找,替换

    • Object max(Collection):返回给定集合中的最大元素

    • Object min(Collection):返回给定集合中的最小元素

    • int frequency(Collection,Object):返回指定集合中指定元素的出现次数

    • void copy(List dest,List src):将src中的内容复制到dest中

    • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List对象的所有旧值 

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class MapTest {
    public static void main(String[] args) {
        List list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);

        List list1 = Arrays.asList(new Object[list.size()]);

        System.out.println(list);//[1, 2, 3, 4]

        //Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
        System.out.println(Collections.max(list));//4

        //Object min(Collection):根据元素的自然顺序,返回给定集合中的最小元素
        System.out.println(Collections.min(list));//1

        //int frequency(Collection,Object):返回指定集合中指定元素的出现次数
        System.out.println(Collections.frequency(list,1));//1

        //void copy(List dest,List src):将src中的内容依次覆盖到dest中
        Collections.copy(list1,list);
        System.out.println(list1);//[1, 2, 3, 4]

        //boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List对象的所有旧值
        Collections.replaceAll(list,1,4);
        System.out.println(list);//[4, 3, 2, 4]
    }
}

7.3 集合的练习实例

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

//练习一
public class Test {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        List list = new ArrayList();
        for (int i = 0; i < 10; i++) {
            list.add(scanner.nextInt());
        }
        //自然顺序 从小到大
        Collections.sort(list);
        //反转元素的顺序变成从大到小
        Collections.reverse(list);
        System.out.println(list);
    }
}
import java.util.*;
//练习二
/*把学生名与考试分数录入到Set中,并按分数显示前三名成绩学员的名字要求用Set实现,定义Student类实现Comparable接口。*/
public class SortStudentScores {
    public static void main(String[] args) {
        Set<Student> set = new HashSet<>();
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入学生的姓名和成绩");
        String name;
        int score;
        int i = 1;
        int m =1;
        /*Student tmp = new Student();放在外面的话,修改tmp会影响到set中的对象*/
        while (true) {
            Student tmp = new Student();//创建不同的对象;
            System.out.print("请输入第" + i + "位学生的姓名:");
            name = sc.nextLine();
            tmp.setName(name);
            System.out.print("请输入第" + i++ + "位学生的成绩:");
            score = Integer.parseInt(sc.nextLine());
            if (m == 5) break;
            tmp.setScore(score);
            /*通过变量监视可以发现,通过add添加到set的操作时讲tmp对象的地址存入set,如果这是任然在tmp实例(同一个实例上做值的修改,那么还是还会导致set所指的对象发生变化
             * 因此我们需要一个个的创建不同的对象才可以.*/
            set.add(tmp);
            m++;
        }
        List<Student> list = new ArrayList<>();
        for (Student x : set) {
            list.add(x);
        }
        Collections.sort(list);
        System.out.println("您输入的成绩生成成绩单结果:");
        for(Student x:list){
            System.out.println(x);
        }
        System.out.println("前三名学生的姓名为:");
        Iterator<Student> it=list.iterator();/*不要用new去处理迭代器,list中的iterator方法会返回一个合适的迭代器,而不是人为创建Iterator对象*/
        for(int j = 0;j<3&&it.hasNext();j++){
            System.out.println(it.next());
        }

    }
}

class Student implements Comparable<Student> {
    String name;
    int score;

    public void setName(String name) {
        this.name = name;
    }

    public void setScore(int score) {
        this.score = score;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return score == student.score &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, score);//注意是.hash而不是hashCode
    }


    @Override
    public int compareTo(Student o) {
        return o.score - this.score;
    }

    @Override
    public String toString() {
        return name + "--->" + score;
    }
}

上一节:【JavaSE 知识框架】08 枚举类和注解

下一节:【JavaSE  知识框架】10 泛型 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深山老Java

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值