文档章节

Java基础进阶_day08_(Map集合,可变参数)

S
 Sunmos
发布于 2017/05/13 00:19
字数 2184
阅读 3
收藏 0

Java基础进阶_day08_(Map集合,可变参数)

1. Map集合

Map集合:将键映射到值的对象.Map集合是双列集合的顶层接口.

# Map集合特点:
* A:一个映射不能包含重复的键(相当于是Collection集合的Set集合);
* B:每个键最多只能映射到一个值;
* C:值可以重复(相当于是Collection集合的List集合).

Map集合与Collection集合的区别:

# Map集合存储的元素是成对出现的,其中键是唯一的,值是可以重复的;
# Collection集合存储的元素是单独出现的,其子接口List集合存储的是元素是可重复的,子接口Set集合存储的元素是唯一的.

集合中的数据结构:

# Map集合的底层数据结构是针对键有效的,对值无效;
# Collection集合的底层数据结构是针对存储的元素有效.

Map集合功能概述:

添加功能:

V put(K key,V value):将指定的键映射到值,返回被替换的值;

获取功能:

Set<Map.Entry<K,V>> entrySet():获取集合键值对的集合;
V get(Object key):获取指定键对应的值,没有则返回null;
Set<K> keySet():返回该集合的键集合;
Collection<V> values():返回该集合的值的集合;

删除功能:

void clear():删除集合中所有的键值对;
V remove(Object key):删除指定键对应的值,并将删除的值返回(key不返回),没有返回null;

判断功能:

boolean containsKey(Object key):判断集合中是否包含指定键;
boolean containsValue(Object value):判断集合中是否包含指定的值;
boolean isEmpty():判断集合是否为空;

长度功能:

int size():返回集合中键值对的对数.

Map集合的遍历方式:

# 方式1:通过keySet()方法获取Map的键的Set集合,通过遍历key的集合(get()方法)获取key对应的value值.
# 方式2:先获取Map集合的键值对对象的集合,通过遍历获取的集合获取每一个键值对对象,获取键值对对象的键和值.

案例:

public class MyMapDemo {
    public static void main(String[] args) {
        //创建集合对象
        Map<Integer, String> m = new HashMap<Integer, String>();
        // V put(K key,V value)
        System.out.println(m.put(1, "郭靖"));
        m.put(2, "黄蓉");
        System.out.println(m);
        // V get(Object key)
        System.out.println(m.get(1));
        System.out.println(m.get(2));
        // Set<K> keySet():
        Set<Integer> keySet = m.keySet();
        for (Integer integer : keySet) {
            System.out.println(integer);
        }
        // Collection<V> values()
        Collection<String> values = m.values();
        for (String string : values) {
            System.out.println(string);
        }
        // void clear()
        // m.clear();
        // System.out.println(m);
        // V remove(Object key)
        System.out.println(m.remove(1));
        System.out.println(m.remove(3));
        // boolean containsKey(Object key)
        System.out.println(m);
        System.out.println(m.containsKey(1));
        // boolean containsValue(Object value)
        System.out.println(m.containsValue("郭靖"));
        // boolean isEmpty()
        System.out.println(m.isEmpty());
        // int size()
        System.out.println(m.size());
        // 遍历集合,方式1
        Map<String, String> map = new HashMap<String, String>();
        map.put("郭靖", "黄蓉");
        map.put("杨康", "穆念慈");
        map.put("周伯通", "瑛姑");
        Set<String> set = map.keySet();
        for (String string : set) {
            System.out.println(string+"..."+map.get(string));
        }
        // 遍历集合,方式1
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        for (Map.Entry<String, String> entry : entrySet) {
            System.out.println(entry.getKey()+"..."+entry.getValue());
        }
    }
}

1.1 HashMap集合

HashMap集合:是基于哈希表的Map集合接口的实现类,其有个子类LinkedHashMap[键值对有序(存取顺序)].

# (键)底层数据结构是哈希表.
# 特点:键值对集合,键唯一,键值对无序(存储顺序),值可以重复.
* 哈希表保证了键的唯一性.
* 任何非null对象都可以用作键或值.

注意事项:

# 由于HashMap集合键的底层数据结构是哈希表,如果键的内容是自定义类,则需要该类重写hashCode和equals方法,否则无法保证键的唯一性.
# HashMap与~~Hashtable~~集合:
 * HashMap集合:线程不安全,效率高,键和值可以为null;
 * Hashtable集合:线程安全,效率低,键和值不允许为null.

案例:

public class MyMap_HashMapDemo {
    public static void main(String[] args) {
        HashMap<Student, String> hm = new HashMap<Student, String>();
        hm.put(new Student("郭靖", 23), "12");
        hm.put(new Student("黄蓉", 23), "13");
        hm.put(new Student("洪七公", 40), "14");
        hm.put(new Student("郭靖", 23), "15");
        Set<Student> keySet = hm.keySet();
        for (Student student : keySet) {
            String s = hm.get(student);
            System.out.println(student.getName()+"..."+student.getAge()+"..."+s);
        }
    }
}
class Student {
    private String name;
    private int age;
    public Student() {}
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
    // 重写hashCode和equals方法
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }
}

1.2 LinkedHashMap集合

LinkedHashMap集合:Map接口的哈希表和链接列表实现,具有可预知的迭代顺序(存储和取出顺序一致),是LinkedHashMap集合是HashMap集合类的子类.

# 底层数据结构是哈希表和链表.
* 特点:键唯一,值可重复,有序(存取顺序一致).
* 哈希表保证了键的唯一性,链表保证了键值对的存取顺序一致.

案例:

public class MyMap_HasMap_LinkedHashMapDemo {
    public static void main(String[] args) {
        LinkedHashMap<String, String> hm = new LinkedHashMap<String, String>();
        hm.put("123", "java");
        hm.put("1234", "android");
        hm.put("123", "javaEE");
        hm.put("1235", "java");
        Set<String> keySet = hm.keySet();
        for (String string : keySet) {
            System.out.println(string+"..."+hm.get(string));
        }
    }
}

1.3 TreeMap集合

TreeMap集合:是实现了Map集合接口的子类.

# 底层数据结构是红黑树(自平衡的二叉树).
# 特点:键唯一,值可重复,无序(元素存取顺序).
* 键的红黑树数据结构保证了键的唯一性和排序.

构造方法:

public TreeMap():该构造方法的键是自然排序;
public TreeMap(Comparator<? super K> comparator):该构造方法创建的对象的键是按照比较器comparator进行排序.

注意事项:

# 键自然排序:无参构造
 * 当键是自定义对象时,需要该对象所属的类实现Comparable接口,并实现其中的compareTo方法,在该方法中定义排序规则.
# 键比较器排序:有参数构造
 * 当键是自定义对象时,在创建集合对象时,使用实现Comparator接口的匿名内部类,并实现其中的compare方法,在方法中定义排序规则.

案例:

public class MyMap_TreeMapDemo {
    public static void main(String[] args) {
        // 创建集合对象
        TreeMap<Student, String> tm = new TreeMap<Student, String>(new Comparator<Student>() {
            // 重写方法,定义排序规则
            @Override
            public int compare(Student s1, Student s2) {
                // 主要条件,年龄
                int num = s2.getAge() - s1.getAge();
                // 次要条件,姓名
                int num2 = num==0?s1.getName().compareTo(s2.getName()):num;
                return num2;
            }
        });
        tm.put(new Student("郭靖", 23), "12");
        tm.put(new Student("黄蓉", 23), "13");
        tm.put(new Student("洪七公", 40), "14");
        tm.put(new Student("郭靖", 23), "15");
        Set<Student> keySet = tm.keySet();
        for (Student student : keySet) {
            String s = tm.get(student);
            System.out.println(student.getName()+"..."+student.getAge()+"..."+s);
        }

        // 练习
        // 统计一个字符串中各个字符出现的次数
        test01();
    }

    /* * 统计一个字符串中各个字符出现的次数 */
    public static void test01() {
        // 定义存储字符的集合
        TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
        // 定义键盘录入对象
        Scanner sc = new Scanner(System.in);
        // 定义接收键盘录入的字符串
        System.out.println("请输入一个字符串:");
        String s = sc.nextLine();
        // 将字符串转换为字符数组
        char[] chs = s.toCharArray();

        // 遍历字符数组,统计各个字符出现的次数
        for (int i = 0; i < chs.length; i++) {
            if(tm.containsKey(chs[i])) {
                int num = tm.get(chs[i]);
                num++;
                tm.put(chs[i], num);
            }else {
                tm.put(chs[i], 1);
            }
        }

        // 定义字符串缓冲区对象
        StringBuilder sb = new StringBuilder();
        Set<Character> ketSet = tm.keySet();
        for (Character character : ketSet) {
            sb.append("\""+character+"\"").append("(").append(tm.get(character)).append(")");
        }
        // 输出结果
        System.out.println(sb.toString());

    }
}
// 自定义类
class Person {
    private String name;
    private int age;
    public Person() {}
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    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;
    }
}

2. 可变参数

可变参数:定义方法时不确定参数的个数.

使用格式:

修饰符  返回值类型  方法名 (数据类型...  变量名) {}

注意事项:

# 方法的变量名其实是一个数组;
# 如果一个方法有可变参数并且有多个参数,则可变参数必须是最后一个参数.

Arrays工具类:

public static <T> List<T> asList(T... a):将数组转换为集合.
注意事项:该方法转换成的集合本质还是数组,长度不变,所以不支持改变数组长度的操作(增删),修改可以.

案例:

public class MyArgsDemo {
    public static void main(String[] args) {
        // 调用可变参数方法
        System.out.println(sum(1,2,3));
        System.out.println(sum(1,2));
        System.out.println(sum(1,2,3,4));
        // 多个参数的可变参数,可变参数必须最后一个参数
        System.out.println(sum1(2.4,1,2,3));

        // 将数组转换为集合
        String[] s = {"java","python","android"};
        List<String> asList = Arrays.asList(s);
        // 可变参数
        // List<String> asList = Arrays.asList("java","python","android");
        // List<String> asList = Arrays.asList("java","python");
        for (String string : asList) {
            System.out.println(string);
        }
        // asList.add("java"); // java.lang.UnsupportedOperationException
        // asList.remove(0); // UnsupportedOperationException
        asList.set(0, "java");
    }

    // 定义可变参数
    public static int sum(int... num) {
        int sum = 0;
        // 使用增强for循环遍历数组
        for (int i : num) {
            sum += i;
        }
        return sum;
    }
    // 定义可变参数
    public static int sum1(double num1, int... num2) {
        int sum = 0;
        // 使用增强for循环遍历数组
        for (int i : num2) {
            sum += i;
        }
        System.out.println(num1);
        return sum;
    }
}

本文转载自:http://blog.csdn.net/l631106040120/article/details/69055840

共有 人打赏支持
S
粉丝 0
博文 34
码字总数 0
作品 0
成都
kotlin学习笔记-异常好玩的list集合总结

不积跬步无以至千里,不积小流无以成江海 先看看Kotlin中for循环的遍历 kotlin和Java中的集合工具类 Java中集合及其工具类 Kotlin中Java中集合及其工具类 List MutableList Set MutableSet Ma...

codeGoogle
07/16
0
0
《Kotlin 程序设计》第四章 Kotlin 语法基础

第四章 Kotlin 语法基础 正式上架:《Kotlin极简教程》Official on shelves: Kotlin Programming minimalist tutorial 京东JD:https://item.jd.com/12181725.html 天猫Tmall:https://detai......

程序员诗人
2017/05/29
0
0
Scala开发问题汇总(不断更新中)

1、Scala教程 Scala Tutorial 2、Java和Scala集合如何进行互转? CONVERSIONS BETWEEN JAVA AND SCALA COLLECTIONS Converting Java collections to Scala 3、如何将List转换为Map? Conver......

九州暮云
07/05
0
0
Scala笔记整理(二):Scala数据结构—数组、map与tuple

[TOC] 数组 定长数组 如果你需要一个长度不变的数组,可以用Scala中的Array。例如: 在JVM中,Scala的Array以Java数组方式实现。示例中的数组在JVM中的类型为java.lang.String[]。Int、Doubl...

xpleaf
04/18
0
0
Java高级部分笔记-------Java5.0的新特性

静态导入 1.1 JDK 1.5 增加的静态导入语法用于导入类的某个静态属性或方法。使用静态导入可以简化程序对类静态属性和方法的调用。 1.2 语法:Import static 包名.类名.静态属性|静态方法|* ...

查封炉台
2014/04/21
0
0

没有更多内容

加载失败,请刷新页面

加载更多

70.shell的函数 数组 告警系统需求分析

20.16/20.17 shell中的函数 20.18 shell中的数组 20.19 告警系统需求分析 20.16/20.17 shell中的函数: ~1. 函数就是把一段代码整理到了一个小单元中,并给这个小单元起一个名字,当用到这段...

王鑫linux
今天
0
0
分布式框架spring-session实现session一致性使用问题

前言:项目中使用到spring-session来缓存用户信息,保证服务之间session一致性,但是获取session信息为什么不能再服务层获取? 一、spring-session实现session一致性方式 用户每一次请求都会...

WALK_MAN
今天
5
0
C++ yield()与sleep_for()

C++11 标准库提供了yield()和sleep_for()两个方法。 (1)std::this_thread::yield(): 线程调用该方法时,主动让出CPU,并且不参与CPU的本次调度,从而让其他线程有机会运行。在后续的调度周...

yepanl
今天
4
0
Java并发编程实战(chapter_3)(线程池ThreadPoolExecutor源码分析)

这个系列一直没再写,很多原因,中间经历了换工作,熟悉项目,熟悉新团队等等一系列的事情。并发课题对于Java来说是一个又重要又难的一大块,除非气定神闲、精力满满,否则我本身是不敢随便写...

心中的理想乡
今天
31
0
shell学习之获取用户的输入命令read

在运行脚本的时候,命令行参数是可以传入参数,还有就是在脚本运行过程中需要用户输入参数,比如你想要在脚本运行时问个问题,并等待运行脚本的人来回答。bash shell为此提 供了read命令。 ...

woshixin
今天
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部