Day09 JavaSE 集合概述

Java集合概述

前言

Java集合类存放于java.util包中,是一个用来存放对象的容器

  • 集合只能用来存放对象。
  • 集合存放的是多个对象的引用,对象本身还是放在堆内存中。
  • 集合可以存放不同类型、不限数量的数据类型。

Java集合可分为Set、List、Map三大体系。

Set:无序、不可重复的集合

List:有序,可重复的集合

Map:具有映射关系的集合

1 Set

1.1 HashSet

HashSet按照Hash算法来存储集合中的元素,因此具有很好的存取和查找性能。

HashSet特点:

  • 不能保证元素的排列顺序
  • 不可重复 --> hashCode不相同
  • HashSet不是线程安全的
  • 集合元素可以使用null

排列顺序的解释:当向HashSet集合存入一个元素时,会调用该对象的hashCode()方法来得到该对象的hashCode值,根据hashCode值决定该对象在集合中存储位置。

HashSet类 --实现–> set接口 --继承–> Collection接口

基本操作:

创建HashSet: Set set = new HashSet();

  • 增、删、判断、清空;

  • add()、remove()、contains()、clear();

    package com.set;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class HashSetDemo01 {
        public static void main(String[] args) {
            Set set = new HashSet();// <=>Set<Object> set = new HashSet<Object>();
            set.add(1);//添加元素
            set.add("a");
            System.out.println(set);
    
            set.remove(1); //移除元素
            System.out.println(set);
    
            System.out.println(set.contains(1));//判断是否存在
    
            set.clear(); //清空集合
            System.out.println(set);
        }
    }
    //运行结果
    //[1, a]
    //[a]
    //false
    //[]
    
  • 遍历(迭代器遍历 / for each迭代集合)

    package com.set;
    
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    
    public class HashSetDemo01 {
        public static void main(String[] args) {
            Set set = new HashSet();// <=>Set<Object> set = new HashSet<Object>();
            set.add("a");
            set.add("b");
            set.add("c");
            set.add("d");
            set.add("d"); //set集合并未发生改变,说明set存的值是不重复的
            set.add(null); //set可以存null --> 存后发现null位于首位,故hashSet无顺序
            System.out.println(set);
            
          	//使用迭代器遍历集合
            Iterator it = set.iterator();
            while (it.hasNext()){
                System.out.println(it.next());
            }
            
          	//for each迭代集合(推荐!)
            for (Object obj : set){ //将set每一个值取出赋值给obj
                System.out.println(obj);
            }
            System.out.println(set.size()); //获取集合个数
        }
    }
    /*运行结果
    [null, a, b, c, d]
    null
    a
    b
    c
    d
    null
    a
    b
    c
    d
    5
    */
    
  • 泛型的引入

  • Set set1 = new HashSet();

    package com.set;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class HashSetDemo01 {
        public static void main(String[] args) {
            //如果想让集合只存同样类型的对象,需要使用泛型
            Set<String> set1 = new HashSet<String>();
    
            set1.add("abc");
            //set1.add(true); //非String对象不能存入
            System.out.println(set1);
        }
    }
    //运行结果:
    //[abc]
    

1.2 TreeSet

TreeSet是SortedSet接口的实现类,TreeSet可以确保集合元素处于排序状态。

TreeSet支持两种排序方法:自然排序(默认)和定制排序。

1.2.1 自然排序

TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按升序排列

  • 如果this > obj,返回1
  • 如果this < obj,返回-1
  • 如果this = obj,返回0
  • 必须放入同样类的对象(可使用泛型来限制),否则会出现类型转换异常

自然排序案例:

基本操作与HashSet中一致,遍历操作也相同,故直接给出:

package com.set;

import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetDemo01 {
    public static void main(String[] args) {
        Set<Integer> set = new TreeSet<Integer>();
        //TreeSet 自然排序
        set.add(5);
        set.add(2);
        set.add(4);
        set.add(3);
        System.out.println(set);
        set.remove(5);
        System.out.println(set.contains(3));
//        set.clear();
        //遍历同上
        //迭代器遍历
        Iterator<Integer> it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
        //for-each遍历
        for (Integer i : set){
            System.out.println(i);
        }
    }
}
/*运行结果:
[2, 3, 4, 5]
true
2
3
4
2
3
4
 */

1.2.2 定制排序

TreeSet中存放自己定义的类对象,现需按照自己想要的方式进行排序,需使用定制排序。

实现方法:

  • 创建自己的类并实现Comparator<Person>接口,例如Person类,内含name,age属性。
  • 在Person类中创建无参构造器+有参构造器。
  • Person类中重写compare方法,传入两对象,按照age比较并返回1、-1、0。

TreeSet创建使用:Set<Person> set = new TreeSet<Person>(new Person());

定制排序案例:

package com.set;

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

public class TreeSetDemo02 {
    public static void main(String[] args) {
        Person p1 = new Person("张三", 23);
        Person p2 = new Person("里斯", 25);
        Person p3 = new Person("王武", 20);
        Person p4 = new Person("Lucy", 19);

        Set<Person> set = new TreeSet<Person>(new Person());
        set.add(p1);
        set.add(p2);
        set.add(p3);
        set.add(p4);

        for (Person p : set){
            System.out.println(p.name + " "+ p.age);
        }

    }
}
class Person implements Comparator<Person> { //将person对象存入TreeSet中,并按照年龄排序
    int age;
    String name;
    //无参构造器
    public Person(){

    }
    //有参构造器
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    public int compare(Person o1, Person o2) { //年龄正序排列
        if (o1.age > o2.age) {
            return 1;
        } else if (o1.age < o2.age) {
            return -1;
        } else {
            return 0;
        }
    }
}
//运行结果:
//Lucy 19
//王武 20
//张三 23
//里斯 25

2 List

List代表一个元素有序、且可重复的集合,集合中的每个元素都有其对应的顺序索引。

List对象创建:List<String> list = new ArrayList<String>();

ArrayList和Vector是List接口的两个典型实现,区别:

  • Vector是一个古老的集合,通常建议ArrayList。
  • ArrayList是线程不安全的,Vector是线程安全的。

常用操作:

函数名称 函数功能
add() 1)添加元素
2指定位置添加元素
addAll() 指定位置添加另一集合中所有元素
remove() 删除元素(可根据索引也可根据元素名称)
set() 更改指定位置元素
get() 根据索引取出指定位置元素
indexOf() 获取指定元素在集合中第一次出现的索引下标
lastIndexOf() 获取指定元素在集合中最后一次出现的索引下标
sublist() 截取list集合,返回新的list集合(左闭右开)
size() 返回列表元素个数

案例展示:

package com.list;

import java.util.ArrayList;
import java.util.List;

public class ListDemo01 {
    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("a"); //索引为0
        list.add("c"); //索引为1
        list.add("c"); //索引为2
        list.add("d"); //索引为3
        list.add("d"); //允许使用重复元素
        System.out.println(list);

        list.add(1,"b"); //在指定位置插入数据,其后数据均往后移动
        System.out.println(list);

        List<String> l = new ArrayList<String>();
        l.add("123");
        l.add("efg");
        list.addAll(0,l); //在指定索引下标位置插入集合
        System.out.println(list);

        list.remove(4); //根据指定索引下标移除数据
        System.out.println(list);

        list.set(1,"456"); //根据指定索引下标修改元素
        System.out.println(list);

        System.out.println(list.get(2)); //取出指定位置元素
        System.out.println(list);


        System.out.println(list.indexOf("d")); //获取指定元素在集合中第一次出现的索引下标
        System.out.println(list.lastIndexOf("d")); //获取指定元素在集合中最后一次出现的索引下标

        List<String> sublist = list.subList(2,5); //取出索引下标为[2,5)的元素,注意左闭右开
        System.out.println(sublist);
        System.out.println(sublist.size());
    }
}
/*运行结果:
[a, c, c, d, d]
[a, b, c, c, d, d]
[123, efg, a, b, c, c, d, d]
[123, efg, a, b, c, d, d]
[123, 456, a, b, c, d, d]
a
[123, 456, a, b, c, d, d]
5
6
[a, b, c]
3
 */

3 Map

Map用来保存具有映射关系的数据,因此Map集合里保存两组值,一组值保存Key,另外一组保存Value。

(这里的Map有点类似于python中的字典)

Key不允许重复,且Key与Value存在一对一关系。

3.1 HashMap

常用操作:

函数名称 函数功能
put() 添加数据
get() 根据key取值
remove() 根据key移除键值对
size() 返回键值对个数
containsKey() 判断map集合中是否包含指定的key
containsValue() 判断map集合中是否包含指定的value
clear() 清空map集合
map.keySet() 获取map集合中key的集合
map.values() 获取map集合中所有values值
(返回HashMap$Values类型数据)

基本操作案例:

package com.map;

import java.util.*;

public class MapDemo01 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("a",1); //添加数据
        map.put("c",2);
        map.put("e",2);
        map.put("f",2);
        System.out.println(map);

        System.out.println(map.get("c")); //根据key取值

        map.remove("c"); //根据key移除键值对
        System.out.println(map);
        System.out.println(map.size()); //map集合长度

        System.out.println(map.containsKey("c")); //判断map集合中是否包含指定的key
        System.out.println(map.containsValue(1)); //判断map集合中是否包含指定的Value

        map.values(); //获取map集合的所有Value值
        System.out.println(map.values().getClass().getName()); //查看返回类型
      
        map.clear();//清空
    }
}
/*运行结果:
{a=1, c=2, e=2, f=2}
2
{a=1, e=2, f=2}
3
false
true
java.util.HashMap$Values
 */

遍历操作案例:

两种方式:1、map.keySet() 2、map.entrySet()(推荐使用!)

package com.map;

import java.util.*;

public class MapDemo01 {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("a",1); //添加数据
        map.put("e",2);
        map.put("f",2);
        System.out.println(map); 
      
        //遍历map集合,通过map.keySet();
        Set<String> keys = map.keySet(); //获取map集合的key的集合
        for (String key : keys) {
            System.out.println("key: " + key + ", value: " + map.get(key));
        }

        //通过map.entrySet();(性能更优,推荐使用)
        Set<Map.Entry<String,Integer>> entrys = map.entrySet(); //Map.Entry表示映射关系,map.entrySet()返回包含该关系的Set视图
        for (Map.Entry<String, Integer> en : entrys){
            System.out.println("key: " + en.getKey()+", value: "+ en.getValue());
        }
    }
}
/*运行结果:
key: a, value: 1
key: e, value: 2
key: f, value: 2
key: a, value: 1
key: e, value: 2
key: f, value: 2
 */

3.2 TreeMap

TreeMap也支持两种排序方法:自然排序与定制排序(与TreeSet类似)

此处仅展示自然排序的使用,定制排序可仿照TreeSet编写。

  • 案例展示:
package com.map;

import java.util.Map;
import java.util.TreeMap;

public class MapDemo02 {
    public static void main(String[] args) {
        Map<Integer, String> map = new TreeMap<Integer, String>();
        map.put(4,"a");
        map.put(3,"b");
        map.put(5,"b");
        map.put(2,"e");
        System.out.println(map);

        //自然排序使用的是英文字典顺序排序,且数字在字母之前
        Map<String, String> map1 = new TreeMap<String, String>();
        map1.put("a","b");
        map1.put("c","d");
        map1.put("b","e");
        map1.put("d","f");
        map1.put("ab","ab");
        map1.put("1","11");
        map1.put("12","12");
        map1.put("2","2");
        System.out.println(map1);
    }
}
/*运行结果:
{2=e, 3=b, 4=a, 5=b}
{1=11, 12=12, 2=2, a=b, ab=ab, b=e, c=d, d=f}
*/

注:TreeMap自然排序<String排序>使用的是英文字典顺序,且数字在字母之前!

写在最后

因为苦涩,才去品尝,因为感动,才去深爱。

To Demut and Dottie!

发布了32 篇原创文章 · 获赞 39 · 访问量 1738

猜你喜欢

转载自blog.csdn.net/qq_44958172/article/details/104659402