Java学习<下>

双列集合

特点

  1. 双列集合一次要存一对数据,分别为键和值
  2. 键不能重复,值可以重复
  3. 键和值是一 一对应的,每一个键只能找到自己对应的值
  4. 键+值这个整体 我们称之为“键对值”或者“键对值对象”,在Java中叫做”Entry对象“

Map的常见API

Map是双列集合的顶层接口,它的功能是全部双列集合都可以继承使用的

V put (K key, V value)
//添加元素
V remove(Object key)
//根据键删除键值对元素
void clear()
//移出所有的键值对元素
boolean containsKey(Object key)
//判断集合是否包含指定的键
boolean containsValue(Object value)
//判断集合是否包含指定的值
boolean isEmpty()
//判断集合是否为空
int size()
//集合的长度,也就是集合中键值对的个数

put细节

添加数据时,如果键不在,那么直接把键值对对象添加到map集合当中
添加数据的时候,如果键存在,那么会把原有的键值对象覆盖,会把覆盖的值返回

Map的遍历方式

1.键找值

//创建map集合对象
        Map<String, String> m = new HashMap<>();
        //添加元素
        m.put("奥特之父","奥特之母");
        m.put("尹志平","小龙女");
        //获取所有的键,把这些键放到同一个集合中
        Set<String> keys = m.keySet();
        //遍历单列集合,得到每一个键
        for (String key : keys){
            System.out.println(key);
            //利用键去获取值
            String value = m.get(key);
            System.out.println(key + "=" + value);

键值对

//创建map集合对象
        Map<String, String> m = new HashMap<>();
        //添加元素
        m.put("奥特之父","奥特之母");
        m.put("尹志平","小龙女");
        //通过一个方法获取所有键值对象,返回一个Set集合
        Set<Map.Entry<String, String>>entries = m.entrySet();
        //遍历entries这个集合,去得到每一个键对值对象
        for (Map.Entry<String, String> entry : entries) {
            //利用entry调用get方法获取键和值
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "=" + value);
        }
        }

Lambda表达式

//创建map集合对象
        Map<String, String> m = new HashMap<>();
        //添加元素
        m.put("奥特之父","奥特之母");
        m.put("尹志平","小龙女");
        //利用Lambda表达式进行遍历
        m.forEach(new BiConsumer<String, String>() {
            @Override
            public void accept(String key, String value) {
                System.out.println(key + "=" + value);
            }
        });
        ________________________________________________
        //创建map集合对象
        Map<String, String> m = new HashMap<>();
        //添加元素
        m.put("奥特之父","奥特之母");
        m.put("尹志平","小龙女");
        //利用Lambda表达式进行遍历
        m.forEach(( key,  value) ->System.out.println(key + "=" + value));
        }

HashMap

特点

  1. HashMap是Map里面的一个实现类
  2. 没有额外需要学习的特有方法,直接使用Map里面的方法就可以
  3. 特点都是由键决定的: 无序,不重复,无索引

练习1
需求:
创建一个HashMap集合,键是学生对象(Student),值是籍贯(String).
存储三个键值对元素,并遍历
要求:同姓名,同年龄认为是同一个学生

package com.itheima.a01.mymap;

import java.util.Objects;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

public static void main(String[] args) {
        //创建HashMap对象
        HashMap<Student,String> hm = new HashMap<>();
        //创建3个学生对象
        Student s1 = new Student("zhangsan",34);
        Student s2 = new Student("lisi",34);
        Student s3 = new Student("wangwu",34);
        //3.添加元素
        hm.put(s1,"山东");
        hm.put(s2,"浙江");
        hm.put(s3,"江苏");
        //遍历
        Set<Student> keys = hm.keySet();
        for (Student key : keys){
           String value= hm.get(key);
            System.out.println(key+ "="+ value);
        }
        System.out.println("--------------------------------------------------");
        Set<Map.Entry<Student, String>> entries = hm.entrySet();
        for (Map.Entry<Student, String> entry : entries) {
            Student key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + "=" + value);
        }
        System.out.println("--------------------------------------------------");
        hm.forEach(( student,  s) -> System.out.println(student + "=" + s)
        );

    }

练习二
需求:
某个班80名学生,现在需要组成秋游活动
班长提供了四个景点(A,B,C,D)
每个学生只能选择一个景点,请统计出最终哪个景点想去的人数最多

import java.util.*;

public class A03demo {
    public static void main(String[] args) {
        //先让同学们进行投票
        //定义一个数组存储四个景点
        String[] arr = {"A","B","C","D"};
        //利用随机数模拟80个同学投票,并把投票结果存储
        ArrayList<String> list = new ArrayList<>();
        Random r = new Random();
        for (int i = 0; i < 80 ; i++){
            int index = r.nextInt(arr.length);
            list.add(arr[index]);
        }
        //定义map集合,利用集合进行统计
        HashMap<String,Integer> hm = new HashMap<>();
        for (String name : list){
            //判断当前景点在map中是否存在
            if(hm.containsKey(name)){
                //存在
                //先获取当前景点已经出现的次数
                int count = hm.get(name);
                //表示当前景点又被投了一次
                count++;
                //把新的集合次数再次添加到集合当中
                hm.put(name,count);
            }else {
                //不存在
                hm.put(name,1);
            }
        }
        System.out.println(hm);
        //求最大值
        int max = 0;
        Set<Map.Entry<String, Integer>> entries = hm.entrySet();
        for (Map.Entry<String, Integer> entry : entries) {
            int count = entry.getValue();
            if (count>max){
                max = count;
            }

        }
        System.out.println(max);
        //判断最大值是哪一个
        for (Map.Entry<String, Integer> entry : entries) {
            int count = entry.getValue();
            if (count==max){
                System.out.println(entry.getKey());
            }

        }
    }
}

LinkedHashMap

由键决定:有序,不重复,无索引
这里的有序指的是保证存储和取出元素顺序一致
原理:底层数据结构依然是哈希表,只是每个键对元素有额外多了一个双链表的机制记录存储顺序

TreeMap

TreeMap跟TreeSet底层原理一样,都是红黑树结构的
由键决定特性:不重复、无索引、可排序
可排序:对键进行排序
注意:默认按照键的从小到大进行排序,也可以自己规定键的排序规则

代码书写两种排序规则
实现Comparable接口,指定比较规则
创建集合时传递Comparator比较器对象,指定比较规则
TreeMap基本应用
需求1:
键:整数表示id
值:字符串表示商品名称
要求:按照id的升序排列,按照id降序排列

 //创建集合对象
        TreeMap<Integer,String> tm = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2-o1;
            }
        });
        //添加元素
        tm.put(1,"月里约");
        tm.put(2,"纯牛马");
        tm.put(3,"省巢");
        //打印集合
        System.out.println(tm);

需求2:
键:学生对象
值:籍贯
要求:按照学生年龄的升序排列,年龄一样按照姓名的字母排列,同姓名年龄视为同一个人

package a02treemap;

public class Student implements Comparable<Student>{
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }

    @Override
    public int compareTo(Student o) {
        int i =this.getAge() - o.getAge();
        i = i == 0 ? this.getName().compareTo(o.getName()) : i;

        return i;
    }
}

//创建集合
        TreeMap<Student,String> tm = new TreeMap<>();
        //创建3个学生对象
        Student s1 = new Student("zhangsan",23);
        Student s2 = new Student("lisi",23);
        Student s3 = new Student("wangwu",23);
        //添加元素
        tm.put(s1,"江苏");
        tm.put(s2,"山东");
        tm.put(s3,"浙江");
        //打印
        System.out.println(tm);

可变参数

public static void main(String[] args){
	getSum(...args:1,2,3,4,5,6,7,8,9,10);
}
public static int getSum(int...args){

} 

底层:
可变参数底层就是一个数组
只不过不需要我们自己创建,java会帮我们创建好

可变参数的小细节:
1、在方法的形参中最多只能写一个可变参数
可变参数,理解为一个大胖子,有多少吃多少
2、在方法的形参当中,如果出现了可变参数意外,还有其他的形参,那么可变参数要写在最后

Collection

作用;collection不是集合,而是集合工具类

public static <T> boolean addAll(Collection<T> c, T... elements)
//批量添加元素(给单列集合)
public static void shuffle<List<?> list)
//打乱List集合元素的顺序
public static <T> void sort(List<T> list)
//排序
public static <T> void sort(List<T> list, Comparator<T> c)
//根据指定的规则进行排序
public static <T> int binarySearch (List<T> list, T key)
//以二分查找法查找元素
public static <T> void copy(List<T> dest, List<T> src)
//拷贝集合中的元素
public static <T> int fill(List<T> list, T obj)
//使用指定的元素填充集合
public static <T> void max/min(Collection<T> coll)
//根据默认的自然排序获取最大/最小值
public static <T> void swap(List<?> list, int i, int j)
//交换集合中指定位置的元素

斗地主(欠着)

不可变集合

创建不可变集合:不可以被修改的集合

static <E> List<E> of(E...elements)
//创建一个具有指定元素的List集合对象
static <E> Set<E> of(E...elements)
//创建一个具有指定元素的Set集合对象
static <K,V> Map<K,V> of(E...elements()
//创建一个具有指定元素的Map集合对象

创建map集合的细节:
1.键不能重复
2.Map里面的of方法,参数是有上限的,最多只能传20个参数,10个键值对

Stream流

体验Stream流的作用
需求:按照下面的要求完成集合的创建和遍历
创建一个集合,存储多个字符串元素
1、把所有以“张”开头的元素存储到新集合中
2、把“张”开头的,长度为三的元素再存储到新的集合中
3、遍历打印最终结果

ArrayList<String> list1 = new ArrayList<>();
list1.add("张无忌");
list1.add("周芷若");
list1.add("赵敏");
list1.add("张强");
list1.add("张三丰");

list1.stream().filter(name->name.startsWith("张")).filter(name->name.length()==3).forEach(name-> System.out.println(name));

Stream流的思想
结合了Lambda表达式,简化集合、数组的操作
Stream流的使用步骤
过滤——转换——中间方法——方法调用完毕之后,还可以调用其他方法
统计——打印——终结方法——最后一步,调用完毕之后,不能调用其他方法

1、先得到一条Stream流(流水线),并把数据放上去
2、使用中间方法对流水线按上的数据进行操作
3、使用中介方法对流水线上的数据进行操作
单列集合

default Stream <E> stream()
//Collection中的默认方法

双列集合——没有方法名——无法直接使用Stream流
数组

public static<T> Stream<T>stream(T[] array)
//Arrays工具类中的静态方法

Stream接口中静态方法of的细节
方法的形参是一个可变参数,可以传递一堆零散的数据,也可以传递数组
但是数组必须是引用数据类型的,如果传递基本数据类型,是会把整个数组当作一个元素,放到Stream中
Stream流的中间方法

Stream<T> filter(Predicate<? super T> predicate)
//过滤
Stream<T> limit(long maxSize)
//获取前几个元素
Steram<T> skip(long n)
//跳过前几个元素
Steram<T> distinct()
//元素去重,依赖hashCode和equals方法
static <T> Steram<T>concat(Stream a,Stream b)
//合并a和b两个流为一个流
Steram<R> map(Function<T,R> mapper) 
//转换流中的数据类型

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值