Java容器数据类型

前言

容器就是能装对象的对象;

由于List、Set、Map这3个接口,向上都实现了1个Collection接口,我把3者统称为集合数据类型;

一、List容器

Java的ArryList等价于Python中的List,它是线性数据结构,相对于Arry数组来说是可变长的。

List向上实现了Collection接口,向下有2个实现类,分别是ArrayList和LinkedList,两者形成优势互补,使用方法一致。

1.ArrayList(列表)

 ArrayList的内存是连续的,方便我们查询和遍历,但是不利于修改数据。

package Sets;

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

public class TestList {
    public static void main(String[] args) {
        //列表
        List arrayList = new ArrayList();
        arrayList.add("老北京");
        arrayList.add("双胞胎");
        arrayList.add("六丁目");
        arrayList.add("康师傅");
        //[老北京, 双胞胎, 六丁目, 康师傅]
        System.out.println(arrayList);


        //链表
        List likedList = new LinkedList();
        likedList.add("老北京");
        likedList.add("双胞胎");
        likedList.add("六丁目");
        likedList.add("康师傅");
        //[老北京, 双胞胎, 六丁目, 康师傅]
        System.out.println(likedList);


    }
}

2.LinkedList(链表)

链表的内存是不连续的,链表的优势是利于删除和新增数据,但是不利于数据遍历和查询(从头开始找到下一个,在到下一个.....)。

3.常用操作

列表(List)和链表(LikedList)都实现了List接口,所以2者可以调用的方法是一致的。

package Sets;

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

public class TestList {
    public static void main(String[] args) {
        //列表
        //添加元素
        List list = new ArrayList();
        list.add("老北京");
        list.add("双胞胎");
        list.add("六丁目");
        list.add("康师傅");
        list.add(1);
        //[老北京, 双胞胎, 六丁目, 康师傅]
        System.out.println(list);

        //删除元素
        list.remove("康师傅");
        System.out.println(list);

        //查看列表的长度
        System.out.println(list.size());

        //获取单个值:在list中任何元素都属于Object类型,但是我们使用值时需要强转
        Object item2 = list.get(2);
        System.out.println((String) item2); //向下转型
        Object item3 = list.get(3);
        System.out.println((int) item3); //向下转型

        //成员关系判断等价于python中的in
        System.out.println(list.contains(1));
        System.out.println(list.contains("康帅傅"));

        //变量列表
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }


    }
}

二、Set集合

从功能上来说Java中的Set集合等同于Python中的set,相较于List来说,set天然去重,没有重复的元素;

package Sets;

import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;

public class TestSet {
    public static void main(String[] args) {
        Set set = new HashSet();
        set.add("CS");
        set.add("DNF");
        set.add("LOL");
        set.add("CS"); //Set天然去重,重复的数据是添加不进去的
        //[CS, LOL, DNF]
        System.out.println(set);

        //TreeSet:会自动对集合中元素进行排序,而HashSet不会。
        Set treeSet = new TreeSet();
        treeSet.add(10);
        treeSet.add(102);
        treeSet.add(200);
        //[10, 102, 200]
        System.out.println(treeSet);
    }
}

1.HashSet

元素不重复并且是无序的;

2.TreeSet

TreeSet除了对集合内的元素进行去重之外,还会对内部元素进行自动排序

      //TreeSet:会自动对集合中元素进行排序,而HashSet不会。
        Set treeSet = new TreeSet();
        treeSet.add(10);
        treeSet.add(102);
        treeSet.add(200);
        //[10, 102, 200]
        System.out.println(treeSet);

3.常用方法

HashSet和TreeSet都实现Set接口,所以2者能调用的方法也是一致的。

package Sets;

import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.HashSet;
public class TestSet {
    public static void main(String[] args) {
        Set set = new HashSet();
        set.add("CS");
        set.add("DNF");
        set.add("LOL");
        set.add("CS"); //Set天然去重,重复的数据是添加不进去的
        set.add(120); //Int--->Integer
        //[CS, LOL, DNF]
        //查看Set集合的长度
        System.out.println(set.size());
        //删除元素
        set.remove("DNF");
        System.out.println(set);

        //成员关系判断
        System.out.println(set.contains("LOL"));
    }
}

三、Map集合

Map相当于Python中的dict字典,用于存储key、value键值对。

1.HashMap

HashMap是无序的,但查询效率高。

      //1.HashMap:无序的
        Map map = new TreeMap();
        map.put("zay", "周杰伦");
        map.put("wf", "汪峰");
        map.put("tz", "陶喆");
        map.put("zbc", "周笔畅");
        //{tz=陶喆, wf=汪峰, zay=周杰伦, zbc=周笔畅}
        System.out.println(map);

2.TreeMap

TreeMap是有序的,但查询效率地。

     //2.TreeMap:TreeMap会自动根据key排序
        Map map1 = new TreeMap();
        map1.put(11, "周杰伦");
        map1.put(22, "蔡徐坤");
        map1.put(33, "六小灵通");
        map1.put(44, "汪峰");
        //{11=周杰伦, 22=蔡徐坤, 33=六小灵通, 44=汪峰}
        System.out.println(map);     

3.常用操作

HashMap和TreeMap都实现了Map类,所以两者可调用的方法也一致;

package Sets;

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

public class TestMap {
    public static void main(String[] args) {
        //Map集合
        //1.HashMap:无序的
        Map map = new TreeMap();
        map.put("zay", "周杰伦");
        map.put("wf", "汪峰");
        map.put("tz", "陶喆");
        map.put("zbc", "周笔畅");
        //{tz=陶喆, wf=汪峰, zay=周杰伦, zbc=周笔畅}
        System.out.println(map);

        //2.TreeMap:TreeMap会自动根据key排序
        Map map1 = new TreeMap();
        map1.put(11, "周杰伦");
        map1.put(22, "蔡徐坤");
        map1.put(33, "六小灵通");
        map1.put(44, "汪峰");
        //{11=周杰伦, 22=蔡徐坤, 33=六小灵通, 44=汪峰}
        System.out.println(map);

        //3.常用操作
        
        //Map获取value
        System.out.println(map1.get(11));

        //Map删除数据
        map1.remove(22);
        System.out.println(map1);

        //Map的长度
        System.out.println(map1.size());

        //Map-Key成员关系判断
        System.out.println(map1.containsKey(11));

        //Map-Value成员关系判断
        System.out.println(map1.containsValue("周杰伦"));

        //Map覆盖Value
        map1.put(11, "只因你太美");
        System.out.println(map1);//{11=只因你太美, 33=六小灵通, 44=汪峰}

        //Map获取所有的keys
        System.out.println(map1.keySet()); //[11, 33, 44]




    }
}

4.练习

package Sets;

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

public class TestPractice {

    public static void main(String[] args) {
        //预设敏感词汇
        List badWords = new ArrayList();
        badWords.add("苍井空");
        badWords.add("武藤兰");
        badWords.add("波多野结衣");
        badWords.add("仓木麻衣");
        badWords.add("麻生希");
        //输入关键词
        Scanner sc = new Scanner(System.in);
        System.out.print("请输入关键词: ");
        String keyWord = sc.next().trim();
        //检查敏感词
        if (badWords.contains(keyWord)) {
            //替换敏感词
            keyWord = String.format("%s老师", keyWord.charAt(0));
        }
        for (int i = 0; i < badWords.size(); i++) {
            String improperWord = (String) badWords.get(i);
            if (keyWord.contains(improperWord)) {
                String replacedStringg = "";
                for (int j = 0; j < improperWord.length(); j++) {
                    replacedStringg += "*";
                }
                String replacedWord = keyWord.replace(improperWord, replacedStringg);
                keyWord = replacedWord;

            }

        }
        System.out.println(keyWord);
    }


}

四、迭代集合

在Python中我们可以使用for循环遍历一切可迭代对象;

那么在Java中我们如何遍历set集合,这种没有索引的非线性数据类型呢?

我们也可以把Set、List转换成1个迭代器进行迭代获取值,从而达到遍历的目的。

1.迭代List

package Sets;

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

public class TestIter {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("蔡徐坤");
        list.add("吴亦凡");
        list.add("李易峰");
        list.add("鹿晗");
        System.out.println(list);
        //for循环遍历
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }
        //List转换成1个迭代器
        Iterator it = list.iterator();
        System.out.println(it.next()); //第1个
        System.out.println(it.next());//下1个
        System.out.println(it.next());//下1个
        System.out.println(it.next());//下1个
        // System.out.println(it.next()); //没有元素了就抛出异常

        //迭代器循环List
        while (it.hasNext()){
            System.out.println(it.next());
        }
        

    }
}

2.迭代Set

package Sets;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class IterSet {
    public static void main(String[] args) {
        Set set = new HashSet();
        set.add("小坤坤");
        set.add("小凡凡");
        set.add("小憨憨");
        set.add("小峰峰");

        //创建1个迭代器:既然Set是没有索引的,那我们创建1个迭代器
        Iterator it = set.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

    }
}

3.迭代Map

package Sets;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class IterMap {
    public static void main(String[] args) {
        Map maping = new HashMap();
        maping.put("太尉", "高俅");
        maping.put("高衙内", "高坎");
        maping.put("禁军教头", "王进");
        maping.put("鲁提辖", "鲁达");
        System.out.println(maping);

        //方案一:通过把map的keys转换成Iteratore遍历字典
        Set set = maping.keySet();
        Iterator it = set.iterator();
        while (it.hasNext()) {
            String key = (String) it.next();
            System.out.printf("%s<-->%s\n", key, maping.get(key));

        }
        //方案二:entrySet()遍历字典
        Set set1 = maping.entrySet();
        Iterator it1 = set1.iterator();
        while (it1.hasNext()) {
            Map.Entry entry = (Map.Entry) it1.next();
            System.out.printf("%s《===》%s\n", entry.getKey(), entry.getValue());

        }


    }
}

五、泛型

Java和Python的最大不同就是Java是1门强类型的静态语言,使用变量就要声明数据类型;

既然List、Set、Map这3种容器里面,可以存放任何数据类型的元素,那么当我们获取这些元素的时候,就需要进行大量的向下转型操作;

我们不能把食用盐和白砂糖都放在1个罐子里;

泛型:就是通过给容器贴1个标签,规范容器中的元素的数据类型,使集合中存放元素的数据类型保持一致,从而避免了每次对元素的强转操作;

 需要注意的是:我们不能给泛型指定primitive type也就是基础的数据类型;

package 泛型;

import java.util.*;

public class Test01 {
    public static void main(String[] args) {
        //注意:变量声明和实例化的时都需要标记泛型<>
        List<String> list = new ArrayList<String>();
        list.add("高俅");
        list.add("药店");
        list.add("苏东坡");
        list.add("驸马");
        list.add("端王");
        list.add("宋徽宗");
        list.add("高太尉");

//        list.add(111); //不可以装int
        System.out.println(list);

        //获取数据时,不需要强转操作
        String s = list.get(list.size() - 1);
        System.out.println(s);

        //泛型Map
        Map<String, String> map = new HashMap<String, String>();
        map.put("高二哥", "高俅");
        map.put("抓药的", "高俅");
        map.put("书童", "高俅");
        map.put("北宋太尉", "高俅");

        //通过增强for循环 遍历字典
        for (String key : map.keySet()) {
            System.out.printf("%s--%s\n", key, map.get(key));
        }


    }
}

六、Collections工具类

由于List、Set、Map这3个接口,向上都实现了1个Collection接口,我把它们统称为集合数据类型;

针对集合数据类型,JDK还提供了1个Collections工具类,帮助我们更便捷地操作使用集合数据类型

我们主要使用Collections工具类,对集合进行排序、求极值;

package CollectionTools;

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

public class Test01 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(132);
        list.add(2019);
        list.add(8866);
        System.out.println(list);

        //求最大和最小值
        Integer maxNumber = Collections.max(list);
        Integer minNumber = Collections.min(list);
        System.out.println(maxNumber);
        System.out.println(minNumber);

        //排序
        Collections.sort(list);
        System.out.println(list);

        //洗牌
        Collections.shuffle(list);
        System.out.println(list);

        //1次性在列表中添加多个值
        Collections.addAll(list, 1, 2, 3, 3);
        System.out.println(list);

    }
}

七、练习

package CollectionTools;

import java.util.*;

public class Practive {
    public static void main(String[] args) {
        //练习1
        //将如下字符串转换成1个TreeMap
        String dictString = "k1:1,k2:2,k3:3";
        String[] klist = dictString.split(",");
        Map<String, String> kMap = new TreeMap<String, String>();

        for (int i = 0; i < klist.length; i++) {
            String item = klist[i];
            String[] subItem = item.split(":");
            kMap.put(subItem[0], subItem[1]);
        }
        System.out.println(kMap);

        //练习2
        //将小于66的数字保存至sixMap的key1
        //将于于66的数字保存至sixMap的key2
        int[] numberArray = {11, 22, 33, 44, 55, 66, 77, 88};
        Map<String, List<Integer>> sixMap = new HashMap<String, List<Integer>>();
        List belongKey1 = new LinkedList();
        List belongKey2 = new LinkedList();
        for (int i = 0; i < numberArray.length; i++) {
            int currentNumber = numberArray[i];
            if (numberArray[i] <= 66) {
                belongKey1.add(currentNumber);
                sixMap.put("key1", belongKey1);
            } else {
                belongKey2.add(currentNumber);
                sixMap.put("key2", belongKey2);
            }
        }
        System.out.println(sixMap);

    }
}

参考

原文地址:https://www.cnblogs.com/sss4/p/15580640.html