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
方法
| 添加 | 删除 | 获取列表头元素 | 操作失败时 |
|---|---|---|---|
| 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
- 底层哈希表
- 可以存储空间和空值;
- 线程非安全的
HashTable,
- 线程安全的,
- 性能比较低,不建议使用;
顺序:LinkedHashMap:
- 链表和哈希表
- 链表维护次序;
- 添加的顺序来维护的
TreeMap:
- 底层结构是二叉树;
- 有序,可以按照自然顺序。
- 自定义顺序。
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
循环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);
}
}


浙公网安备 33010602011771号