可变参数,Collections,Map集合,Stream

(1)可变参数

可变参数:就是一种特殊形参,定义在方法、构造器的形参列表里

                  格式:数据类型...参数名称;

                  特点:可以不传数据给它;可以传一个或者同时传多个数据给它;也可以传一个数组给它

                  好处:常常用来灵活的接收数据

    public static void main(String[] args) {
        test();
        test(10);
        test(10,20,30);
        test(new int[]{10,20,30,40});
    }
    public static void test(int...nums){
        System.out.println(nums.length);
        System.out.println(Arrays.toString(nums));
        System.out.println("-----------------------------------");
    }

注意事项  1:一个形参列表中,只能有一个可变参数

                 2:可变参数必须放在形参列表的最后面     (int age,int nums)

(2)Collections

Collection:是一个用来操作集合的工具类

方法名称 说明
public static boolean addAl1(Collection c, T... elements) 给集合批量添加元察
public static void shuffle(List list) 打乱List集合中的元素顺序
打乱List集合中的元素顺序 对List集合中的元素进行升序排序
public static void sort(List list,Comparator c) 对List集合中元素,按照比较器对象指定的规则进行排序

Collections只支持对List集合进行排序

排序方式1:

方法名称 说明
public static void sort(List list) 对List集合中元素按照默认规则排序

注意:本方法可以直接对自定义类型的List集合排序,但自定义类型必须实现了Comparable接口,指定了比较规则才可以

排序方法2:

方法名称 说明
public static void sort(List list,comparator c) 对List集合中元素,按照比较器对象指定的规则进行排序

(3)Map集合

Map集合称为双列集合,格式: {key1=value1 , key2=value2, key3=value3 , ...},一次需要存一对数据作为一个元素

Map集合的每个元素“key=value”称为一个键值对/键值对对象/一个Entry对象,Map集合也被叫做“键值对集合"

Map集合的所有键是不允许重复的,但值可以重复,键和值是一一对应的,每一个键只能找到自己对应的值

考虑一一对应的数据时:需要存储一一对应的数据时,就可以考虑使用Map集合来做

可变参数,Collections,Map集合,Stream_第1张图片

 Map集合的特点:

注意:Map系列集合的特点都是由键决定的,值只是一个附属品,值是不做要求的

HashMap(由键决定特点)︰无序、不重复、无索引;(用的最多)

LinkedHashMap (由键决定的特点):有序,不重复,无索引

TreeMap(有键决定特点):按照大小默认升序排序:不重复、无索引

        Mapmap=new HashMap<>();//经典代码

        map.put("手表",100);
        map.put("手表",220);//后面重复的数据会覆盖前面的数据(键)
        map.put("书",2);
        map.put("Java",2);
        map.put(null,null);
        System.out.println(map);//{null=null, 手表=220, Java=2, 书=2}

1)Map的常用方法

Map是双列集合的祖宗,它的功能是全部双列集合都可以继承过来使用的

方法名称 说明
public v put(K key,V value) 添加元素
public int size() 获取集合的大小
public void clear() 清空集合
public boolean isEmpty() 判断集合是否为空,为空返回true ,反之
public v get(Object key) 根据键获取对应值(若无该键,返回null)
public v remove(0bject key) 根据键删除整个元素
public boolean containsKey(Object key) 判断是否包含某个键
public boolean containsValue(0bject value) 判断是否包含某个值
public Set keySet() 获取全部键的集合
public collection values() 获取map集合的全部值

 补充:

public class ListTest1 {
    public static void main(String[] args) {
        Mapmap1=new HashMap<>();
        map1.put("java1",10);
        map1.put("java2",20);
        Mapmap2=new HashMap<>();
        map2.put("java3",10);
        map2.put("java2",222);
        map1.putAll(map2);//putAll:把map2集合的元素全部倒入一份到map1集合
        System.out.println(map1);//{java3=10, java2=222, java1=10}
        System.out.println(map2);//{java3=10, java2=222}
    }
}

(4)Map的遍历方式

Map集合的遍历方式 说明
键找值 先获取Map集合全部的键,再通过遍历键来找值
键值对 把“键值对“看成一个整体进行遍历(难度较大)
Lambda JDK 1.8开始之后的新技术(非常的简单)

1)键找值

方法名称 说明
public Set keySet() 获取所有键的集合
public v get(0bject key) 根据键获取其对应的值
        Setkeys=map.keySet();
        for (String key:keys) {
            double value =map.get(key);
            System.out.println(key+"====>"+value);
        }

2)键值对

Map提供的方法 说明
Set > entrySetO 获取所有“键值对”的集合
        Set> entries=map.entrySet();
        for (Map.Entryentry:entries) {
            String key=entry.getKey();
            double value=entry.getValue();
            System.out.println(key+"====>"+value);
        }

3)Lambda

方法名称 说明
default void forEach(BiConsumeraction) 结合lambda遍历Map集合
     map.forEach((k,v)->{
            System.out.println(k+"====>"+v);
        });

4)HashMap的底层原理

HashMap(由键决定特点)︰无序、不重复、无索引;(用的最多)

HashMap跟Hashset的底层原理是一模一样的,都是基于哈希表实现的

实际上:原来学的Set系列集合的底层就是基于Map实现的,只是Set集合中的元素只要键数据,不要值数据而已

HashMap的键依赖hashCode方法和equals方法保证键的唯一

如果键存储的是自定义类型的对象,可以通过重写hashCode和equals方法,这样可以保证多个对象内容一样时,HashMap集合就能认为是重复的

5)LinkedHashMap的底层原理

LinkedHashMap (由键决定的特点):有序,不重复,无索引

底层数据结构依然是基于哈希表实现的,只是每个键值对元素又额外的多了一个双链表的机制记录元素顺序(保证有序)

实际上:原来学习的LinkedHashSet集合的底层原理就是LinkedHashMap

6)TreeMap的底层原理

TreeMap(有键决定特点):按照大小默认升序排序:不重复、无索引

原理:TreeMap跟TreeSet集合的底层原理是一样的,都是基于红黑树实现的排序

TreeMap集合同样也支持两种方式来指定排序规则

让类实现Comparable接口,重写比较规则

TreeMap集合有一个有参数构造器,支持创建Comparator比较器对象,以便用来指定比较规则

 (5)集合的嵌套

集合的嵌套:指集合中的元素又是一个集合

import java.util.*;

public class ListTest1 {
    public static void main(String[] args) {
        Map> map=new HashMap<>();

        List cities1=new ArrayList<>();
        Collections.addAll(cities1,"南京市","扬州市","苏州市","无锡市","常州市");
        map.put("江苏省",cities1);
        System.out.println(map);//{江苏省=[南京市, 扬州市, 苏州市, 无锡市, 常州市]}
    }
}

(6)Stream

也叫Stream流,是Jdk8开始新增的一套APl(java.util.stream.*),可以用于操作集合或者数组的数据

优势: Stream流大量的结合了Lambda的语法风格来编程,提供了一种更加强大,更加简单的方式操作集合或者数组中的数据,代码更简洁,可读性更好

        //List
        List names=new ArrayList<>();
        Collections.addAll(names,"张三丰","张无忌","周芷若","赵敏","张强");

        List list=new ArrayList<>();
        for (String name:names) {
            if (name.startsWith("张")&&name.length()==3){
                list.add(name);
            }
        }



        //Stream流
        List list2=names.stream().filter(s->s.startsWith("张")).filter(a->a.length()==3).collect(Collectors.toList());

1)Stream的使用步骤

可变参数,Collections,Map集合,Stream_第2张图片

 2)获取Stream流

【1】获取集合的Stream流

public interface Stream ...{  }

Collection提供的如下方法 说明
default Stream stream() 获取当前集合对象的Stream流
List names=new ArrayList<>();
Collections.addAll(names,"张三丰","张无忌","周芷若","赵敏","张强");
Stream stream=names.stream();

【2】获取数组的Stream流

Arrays类提供的如下方法 说明
public static Stream stream(T[] array) 获取当前数组的stream流
Stream类提供的如下方法 说明
public static Stream of(T... values) 获取当前接收数据的Stream流
        Set set=new HashSet<>();
        Collections.addAll(set,"刘德华","张曼玉","蜘蛛精","马德","德玛西亚");
        Stream stream1=set.stream();
        stream1.filter(s->s.contains("德")).forEach(s-> System.out.println(s));

【3】获取Map的Stream流

        Map map=new HashMap<>();
        Set keys=map.keySet();
        Stream ks=keys.stream();

        Collection values=map.values();
        Stream vs=values.stream();

        Set>entries=map.entrySet();
        Stream> kvs=entries.stream();

        kvs.filter(e->e.getKey().contains("巴")).forEach(e->System.out.println(e.getKey()+"---->"+e.getValue()));

【4】获取数组的Stream流

        String[]names2={"张三丰","张无忌","周芷若","赵敏","张强"};
        Stream s1=Arrays.stream(names2);
        Stream s2=Stream.of(names2);

3)Stream流常见的中间方法

中间方法指的是调用完成后会返回新的Stream流,可以继续使用(支持链式编程)

Stream提供的常用中间方法 说明
Stream filter( Predicate< ? super T> predicate) 用于对流中的数据进行过滤
Stream sorted( 对元素进行升序排序
Stream sorted(Comparator comparator) 按照指定规则排序
Stream limit(long maxSize) 获取前几个元素
Stream skip(long n) 跳过前几个元素
Stream distinct() 去除流中重复的元素
Stream map(Function mapper) 对元素进行加工,并返回对应的新流
static Stream concat(Stream a,Stream b) 合并a和b两个流为一个流
//数据
scores.stream().filter(s -> s >=60).sorted().forEach(s -> System.out.println(s));//升序


//对象
students.stream().filter(s -> s.getAge() >= 23 && s.getAge() <= 30).sorted((o1, o2)-> 02.getAge()- o1.getAge()).forEach(s -> System.out.println(s));//根据对象的年龄排序


//去身高最高的3位学生
students.stream().sorted((o1,o2) -> Double.compare(o2.getHeight(),o1.getHeight())).limit(3).forEach(s -> System.out.println(s));

students.stream().sorted((o1,o2) -> Double.compare(o2.getHeight(),o1.getHeight())).limit(3).forEach(System.out::println);


//身高最低的2名学生
students.stream().sorted((o1,o2) -> Double.compare(o2.getHeight(),o1.getHeight())).slip(students.size()-2).forEach(s -> System.out.println(s));



//找出身高超过168的学生叫什么名字,要求去除重复的名字
students.stream().filter(s -> s.getHeight() > 168).map(s->s.getName()).forEach(s -> system.out.println(s));

4)Strem流常见的终结方法

终结方法指的是调用完成后,不会返回新Stream了,没法继续使用流了

Stream提供的常用终结方法 说明
void forEach(consumer action) 对此流运算后的元素执行遍历
long count() 统计此流运算后的元素个数
Optionalmax(Comparator comparator) 获取此流运算后的最大值元素
Optional min(Comparator< ? super T> comparator) 获取此流运算后的最小值元素
//请计算出身高超过168的学生有几人
long size=students.stream().filter(s->s.getHeight()>168).count();


//请找出身高最高的学生对象,并输出
Student s=students.stream().max((o1, o2) -> Double.compare(o1.getHeight(),o2.getHeight() )).get();


//请找出身高最低的学生对象,并输出
Student s=students.stream().min((o1, o2) -> Double.compare(o1.getHeight(),o2.getHeight() )).get();

【1】收集Stream流

收集Stream流:就是把Stream流操作后的结果转回到集合或者数组中去返回

Stream流:方便操作集合/数组的手段;集合/数组:才是开发中的目的

流只能收集一次

Stream提供的常用终结方法 说明
R collect(collector collector) 把流处理后的结果收集到一个指定的集合中去
object[] toArray() 把流处理后的结果收集到一个数组中去
//请找出身高超过170的学生对象,并放到一个新集合中去返回
Liststudents1=students.stream().filter(a->a.getHeight()>170).collect(Collectors.toList());


Setstudents2=students.stream().filter(a->a.getHeight()>170).collect(Collectors.toSet());


//请找出身高超过170的学生对象,并把学生对象的名字和身高,存入到一个Map集合返回
Mapmap=students.stream().filter(a->a.getHeight()>170).distinct().collect(Collectors.toMap(a->a.getName(), a->a.getHeight()));
//distinct()去除重复对象

//请找出身高超过170的学生对象,并放到一个数组中去返回
Object[]arr=students.stream().filter(a->a.getHeight()>170).toArray();
Student[]arr=students.stream().filter(a->a.getHeight()>170).toArray(len->new Student[len]);
Collectors工具类提供了具体的收集方式 说明
public static collector toList() 把元素收集到List集合中
public static collector toSet() 把元素收集到set集合中
public static collector toMap(Function keyMapper , Function valueMapper) 把元素收集到Map集合中

你可能感兴趣的:(java,算法,数据结构)