Fork me on GitHub

JavaSE Day17 Queue Map 过滤器 Stream


Collections 工具类

集合的工具类

package day17;

import java.util.ArrayList;

import java.util.*;

public class TestCollections01 {
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        List<String> list = new ArrayList<>();
        // 添加
        Collections.addAll(list, "aa","bb","cc","xx");
        System.out.println(list);
        // 自然升序
        Collections.sort(list);
        System.out.println(list);
        // 自定义规则
        Collections.sort(list,(s1,s2)->s2.compareTo(s1));
        System.out.println(list);
        // 前提升序排序 返回: 位置索引,不存在 -输入点 -1;
        System.out.println(Collections.binarySearch(list, "ee"));
        // 返回集合中 最大的 和最小的元素
        System.out.println(Collections.max(list));
        System.out.println(Collections.min(list));
        // 反转集合元素,
        Collections.reverse(list);
        System.out.println(list);
        // 
        list.add("xx");
        System.out.println(list);
        // 返回第二个参数元素 在第一个参数 集合中出现的次数
        System.out.println(Collections.frequency(list, "xx"));
        // 填充,用第二个参数元素替换掉集合中的所有元素
        Collections.fill(list, "hello");
    }
}

Queue

https://user-gold-cdn.xitu.io/2017/11/10/e7b0b84b3aa15435928a5840268384c8?imageView2/0/w/1280/h/960/format/webp/ignore-error/1

方法

添加 删除 获取列表头元素 操作失败时
add remove element 会产生异常
offer poll peek 不会产生异常,而是返回特定的值

LinkedList也是Queue的实现类;

package day17;

import java.util.LinkedList;
import java.util.Queue;

public class TestQueue03 {
    public static void main(String[] args) {
        // 队列
        Queue<String> q = new LinkedList<>();
        // 入队:向队尾添加元素
        // 添加成功true,失败 引发异常
        q.add("aa");
        // 添加成功true, 失败 false
        q.offer("bb");
        q.offer("cc");
        // 只有linkedList特殊
        q.offer(null);
        System.out.println(q);
        q.forEach(System.out::println);
        // 出队
        System.out.println("--------------");
       /* // 删除失败,引发异常
        System.out.println(q.remove());
        // 删除失败,返回null
        System.out.println(q.poll());
        System.out.println(q);*/
        while (q.size() > 0) {
//            System.out.println(q.poll());
            // 获得失败,null
            System.out.println(q.peek());

        }
    }
}

数据结构

队列

队列

是一组操作受限的线性表,只能在队尾增加数据,队头删除数据,属于先进先出的数据模型;

PriorityQueue类

是queue的实现类,按照一定的优先级进行排列的

package day17;

import java.util.PriorityQueue;
import java.util.Queue;

public class TestPriorityQueue04 {
    public static void main(String[] args) {
        // 优先队列
        // 默认自然升序
        Queue<String> q = new PriorityQueue<>((o1, o2) -> o2.compareTo(o1));
        q.add("bb");
        q.add("aa");
        q.add("cc");
        q.add(null);
        // 不能完全保证顺序
        System.out.println(q);
        q.forEach(System.out::println);
        // 出队的顺序
        while (q.size() > 0) {
            System.out.println(q.poll());
        }
    }
}

注意

队列 不允许加入null值;
只有LinkedList特殊;可以加null,但是要避免;

Deque接口 双端队列

队列方法

添加 删除 获取列表头元素 操作失败时
addFirst addLast removeFirst removeLast getFirst getLast 会产生异常
offerFirst offerLast pollFirst pollLast peekFirst peekLast 不会产生异常,而是返回特定的值

栈方法

push 入栈
pop 出栈

package day17;

import java.util.ArrayDeque;
import java.util.Deque;

public class TestDeque05 {
    public static void main(String[] args) {
        // 队列 -------先进先出-----------
        Deque<String> d1 = new ArrayDeque<>();
        // 入队
        d1.addFirst("aa");
        d1.add("bb");// 队列的方法 添加从队尾开始
        d1.offer("cc");
        d1.offerLast("dd");
        // 出队
        while(d1.size() >0){
            System.out.println(d1.pollFirst());
//            System.out.println(d1.poll());// 队列的方法,移除从头开始
        }
        // 栈-------------------
        Deque<String> d2 = new ArrayDeque<>();
        // 入栈
        d2.addFirst("aa");
        d2.offerFirst("bb");
        d2.offerFirst("cc");
        d2.push("ff");
        d2.push("gg");
        d2.push("hh");

        // 出栈
        while(d2.size() >0){
//            System.out.println(d2.pollFirst());
            System.out.println(d2.pop());
        }
    }
}

ArrayQueue和LinkedList的区别

ArrayQueue 底层数据结构是数组
LinkedList 底层数据结构是链表

Map接口

映射,键值对,(实际上set就是一个map,但是set的值是object);双列存储;
https://user-gold-cdn.xitu.io/2017/11/10/e7b0b84b3aa15435928a5840268384c8?imageView2/0/w/1280/h/960/format/webp/ignore-error/1

HashMap

默认的初始容量: 16个,(桶,数组长度)
staticfinalintDEFAULT_INITIAL_CAPACITY=1<<4;
最大的容量
staticfinalintMAXIMUM_CAPACITY=1<<30;
负载因子 0.75
staticfinalfloatDEFAULT_LOAD_FACTOR=0.75f;

超过负载因子是会扩容

键值个数:size 0
数组的容量:lenth 16
负载因子: 0.75 size/lenth 超过4分之三,就会扩容
扩容: 2倍扩容

查看hashSet的源码

 public HashSet() {
        map = new HashMap<>();
    }

所以说 Set实际上就是一个Map;

查看HashMap的put源码

    /**
     * The default initial capacity - MUST be a power of two.
     */
    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16

    /**
     * The maximum capacity, used if a higher value is implicitly specified
     * by either of the constructors with arguments.
     * MUST be a power of two <= 1<<30.
     */
    static final int MAXIMUM_CAPACITY = 1 << 30;

    /**
     * The load factor used when none specified in constructor.
     */
    static final float DEFAULT_LOAD_FACTOR = 0.75f;

    /**
     * Associates the specified value with the specified key in this map.
     * If the map previously contained a mapping for the key, the old
     * value is replaced.
     *
     * @param key key with which the specified value is to be associated
     * @param value value to be associated with the specified key
     * @return the previous value associated with <tt>key</tt>, or
     *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
     *         (A <tt>null</tt> return can also indicate that the map
     *         previously associated <tt>null</tt> with <tt>key</tt>.)
     */
    public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

    /**
     * Implements Map.put and related methods
     *
     * @param hash hash for key
     * @param key the key
     * @param value the value to put
     * @param onlyIfAbsent if true, don't change existing value
     * @param evict if false, the table is in creation mode.
     * @return previous value, or null if none
     */
    final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;  // Node表示节点
        if ((tab = table) == null || (n = tab.length) == 0) // 数组为空,或长度为0
            n = (tab = resize()).length;// 数组需要扩容
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);  // 把一个新的节点存到数组中;
        else { // hash冲突
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k)))) // 键的值一样 ,临时存储到变量e
                e = p;
            else if (p instanceof TreeNode) // 二叉树的节点,
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {  // 表示 链表的节点
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);// 如果链表的数量大于8,就转换成二叉树
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value; // e的值不为空,将新的值覆盖掉旧的值;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }

两倍扩容

final Node<K,V>[] resize() {
……
else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
                     oldCap >= DEFAULT_INITIAL_CAPACITY)
                newThr = oldThr << 1; // double threshold

实现类的区别

HashMap

  1. 底层哈希表
  2. 可以存储空间和空值;
  3. 线程非安全的

HashTable,

  1. 线程安全的,
  2. 性能比较低,不建议使用;

顺序:LinkedHashMap:

  1. 链表和哈希表
  2. 链表维护次序;
  3. 添加的顺序来维护的

TreeMap:

  1. 底层结构是二叉树;
  2. 有序,可以按照自然顺序。
  3. 自定义顺序。

Map方法

package day17;

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

public class TestMap07 {
    public static void main(String[] args) {
        // Map
        Map<Integer,String> map = new HashMap<>();//
//        Set<String> set = new HashSet<>();
        // size 键值对的数目
        System.out.println(map.size());
        // 空的 true
        System.out.println(map.isEmpty());
        // 添加
        map.put(11,"aa");
        map.put(22,"bb");
        map.put(33,"cc");

        System.out.println(map);
        // 键是唯一的; 键的集合
        System.out.println(map.keySet());
        // 值得集合
        System.out.println(map.values());
        // 指定的参数的键的 对应的键值对信息 是否包含;包含true
        System.out.println(map.containsKey(11));
        System.out.println(map.containsValue("cc"));
        // 删除
        map.remove(33);
        System.out.println(map);
        // 替换,相当于修改
        map.replace(11,"hello");
        System.out.println(map);
        // 获取指定参数的键的 值;
        System.out.println(map.get(22));
        // 清空
        map.clear();
        System.out.println(map);
    }
}

Map遍历

package day17;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.function.BiConsumer;

public class TestMap08 {
    public static void main(String[] args) {
        HashMap<Integer,String> map = new HashMap<>();

        map.put(11,"aa");
        map.put(22,"bb");
        map.put(33,"cc");
        map.put(null,null);
        System.out.println(map);
        map.put(33,"hello");
        System.out.println(map);

        // 遍历
        // 1. 集合的foreach方法
        map.forEach(new BiConsumer<Integer, String>() {
            @Override
            public void accept(Integer integer, String s) {
                System.out.println(integer);
                System.out.println(s);
            }
        });

        map.forEach((integer, s) -> System.out.println(integer+","+s) );

        // 2. Iterator
        map.keySet().iterator().forEachRemaining(System.out::println);
        map.values().iterator().forEachRemaining(System.out::println);
        // 3. 键值对 遍历 Entry(键值对接口)
        System.out.println("---------------");
        Iterator<Map.Entry<Integer,String>> i = map.entrySet().iterator();
        while(i.hasNext()){
            Map.Entry<Integer,String> e = i.next();
            System.out.println(e.getKey()+"\t"+e.getValue());
        }

        // 4.
        map.entrySet().iterator().forEachRemaining(e-> System.out.println(e.getKey()+"\t"+e.getValue()));

        HashSet<String> set = new HashSet<>();
        set.add("aa");
    }

}

Stream 流

聚集操作。统计操作。
子类:IntSteam,DoubleStream,LongSteam
特点:速度快;但是只能使用一次,属于临时的统计型操作。

末端方法,

统计出一个最终的结果,流就被消耗掉了,(被释放了,不能再用了)

package day17;

import java.util.stream.IntStream;

public class TestStream10 {
    public static void main(String[] args) {
        // Steam
        // 创建一个IntStream流
        IntStream i = IntStream.builder().add(11).add(33).add(22).add(44).build();
        // 末端方法
        // 求最大数
//        System.out.println(i.max().getAsInt());
        // 求最小值
//        System.out.println(i.min().getAsInt());
        // 求总和
//        System.out.println(i.sum());
        //求平均值
//        System.out.println(i.average().getAsDouble());
        // Steam流中元素的个数
//        System.out.println(i.count());
        // 流中所有元素都满足条件,结果为true,
//        System.out.println(i.allMatch(value -> value > 22));
        // 流中只要有一个元素满足条件,结果为true;
        System.out.println(i.anyMatch(value -> value>33));

    }
}

中间方法

得到一个新的流,新的流可以继续调用其他方法进行操作;
对集合的数据的统计操作;

package day17;

import java.sql.Struct;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.function.ToIntFunction;

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

    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;
    }

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

    @Override
    public int compareTo(Student o) {
        return this.age-o.age;
    }
}
public class TestSteam12 {
    public static void main(String[] args) {
        // 中间方法
        List<Student> list = new ArrayList<>();
        Student guojing = new Student("郭靖", 22);
        Student yangkang = new Student("杨康", 33);
        Student huangrong = new Student("黄蓉", 20);
        Collections.addAll(list, guojing, yangkang, huangrong,guojing,yangkang);
        list.stream().forEach(System.out::println);
        // 中间方法 返回一个新的流
        System.out.println("--------");
        // 1. 过滤
        list.stream().filter(student -> student.getAge() > 20).forEach(System.out::println);
        // 2. 映射
        list.stream().map(new Function<Student, String>() {
            @Override
            public String apply(Student student) {
                return student.getName();
            }
        }).forEach(System.out::println);
        // 用年龄表示对象;
        list.stream().mapToInt(new ToIntFunction<Student>() {
            @Override
            public int applyAsInt(Student value) {
                return value.getAge();
            }
        }).forEach(System.out::println);
        // 3. 去除重复的元素
        list.stream().forEach(System.out::println);
        list.stream().distinct().forEach(System.out::println);
        // 4. 排序
        list.stream().sorted().forEach(System.out::println);
        // 5. peek 和 foreach功能一样,但是,peek是中间方法,foreach是末端方法;
        System.out.println("------------------");
//        list.stream().peek(System.out::println).forEach(System.out::println);
        System.out.println(list.stream().peek(System.out::println).count());
        // 6. 显示前几条数据
        list.stream().limit(2).forEach(System.out::println);
        // 7. 略过前几条数据
        System.out.println("--------------------");
        list.stream().skip(3).forEach(System.out::println);
    }
}

过滤器接口

定义一个方法,传递一个list集合,和Predicate p
循环list集合
i. 判断p.test(T)
ii. system.out.println 元素

package day17;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Predicate;

class Book {
    private String name;
    private double price;
    private String auther;

    public Book(String name, double price, String auther) {
        this.name = name;
        this.price = price;
        this.auther = auther;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getAuther() {
        return auther;
    }

    public void setAuther(String auther) {
        this.auther = auther;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", price=" + price +
                ", auther='" + auther + '\'' +
                '}';
    }
}

public class TestPredict13 {
    public int namePredict(List<Book> books, Predicate<Book> p) {
        int count = 0;
        for (Book book : books
        ) {
            if (p.test(book)) {
                System.out.println(book);
                count++;
            }
        }
        return count;
    }


    public void bookInfo(List<Book> books, Predicate<Book> p) {
        for (Book book : books
        ) {
            if (p.test(book)) {
                System.out.println(book);
            }

        }
    }

    public static void main(String[] args) {
        List<Book> books = new ArrayList<>();
        Book java = new Book("java", 90.2, "aa");
        Book python = new Book("python", 34.2, "bb");
        Book javaScript = new Book("javascript", 22.2, "an");
        Book go = new Book("go", 12.2, "cc");
        Book c = new Book("c", 53.2, "ee");
        Collections.addAll(books, java, python, javaScript, go, c);
        TestPredict13 t = new TestPredict13();
        System.out.println("包含java的图书个数");
        System.out.println(t.namePredict(books, book -> book.getName().contains("java")));

        t.bookInfo(books, book -> book.getName().length() > 5);

        System.out.println("------------");
        t.bookInfo(books, book -> book.getPrice() > 20 && book.getAuther().length() == 2);


    }
}

posted @ 2018-10-03 00:57  耳_东  阅读(113)  评论(0)    收藏  举报