提交 e8aeaef4 编写于 作者: S SnailClimb

Update 更改文件路径

上级 dd44b7f4
......@@ -38,7 +38,7 @@
- [数据结构与算法](#数据结构与算法)
- [数据结构](#数据结构)
- [算法](#算法)
- [数据存储](#数据存储)
- [数据](#数据库)
- [MySQL](#mysql)
- [Redis](#redis)
- [系统设计](#系统设计)
......@@ -64,156 +64,156 @@
### 基础
* [Java 基础知识回顾](./Java/Java基础知识.md)
* [J2EE 基础知识回顾](./Java/J2EE基础知识.md)
* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md)
* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md)
* [Java 基础知识回顾](docs/java/Java基础知识.md)
* [J2EE 基础知识回顾](docs/java/J2EE基础知识.md)
* [Collections 工具类和 Arrays 工具类常见方法](./java/Basis/Arrays%2CCollectionsCommonMethods.md)
* [Java常见关键字总结:static、final、this、super](docs/java/Basis/final、static、this、super.md)
### 容器
* **常见问题总结:**
* [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md)
* [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md)
* [这几道Java集合框架面试题几乎必问](docs/java/这几道Java集合框架面试题几乎必问.md)
* [Java 集合框架常见面试题总结](docs/java/Java集合框架常见面试题总结.md)
* **源码分析:**
* [ArrayList 源码学习](./Java/ArrayList.md)
* [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md)
* [LinkedList 源码学习](./Java/LinkedList.md)
* [HashMap(JDK1.8)源码学习](./Java/HashMap.md)
* [ArrayList 源码学习](docs/java/ArrayList.md)
* [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](docs/java/ArrayList-Grow.md)
* [LinkedList 源码学习](docs/java/LinkedList.md)
* [HashMap(JDK1.8)源码学习](docs/java/HashMap.md)
### 并发
* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md)
* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md)
* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md)
* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md)
* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md)
* [并发容器总结](./Java/Multithread/并发容器总结.md)
* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](docs/java/synchronized.md)
* [并发编程面试必备:乐观锁与悲观锁](docs/EssentialContentForInterview/面试必备之乐观锁与悲观锁.md)
* [并发编程面试必备:JUC 中的 Atomic 原子类总结](docs/java/Multithread/Atomic.md)
* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](docs/java/Multithread/AQS.md)
* [BATJ都爱问的多线程面试题](docs/java/Multithread/BATJ都爱问的多线程面试题.md)
* [并发容器总结](docs/java/Multithread/并发容器总结.md)
### JVM
* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md)
* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md)
* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md)
* [可能是把Java内存区域讲的最清楚的一篇文章](docs/java/可能是把Java内存区域讲的最清楚的一篇文章.md)
* [搞定JVM垃圾回收就是这么简单](docs/java/搞定JVM垃圾回收就是这么简单.md)
* [《深入理解Java虚拟机》第2版学习笔记](docs/java/Java虚拟机(jvm).md)
### I/O
* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md)
* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md)
* [BIO,NIO,AIO 总结 ](docs/java/BIO%2CNIO%2CAIO%20summary.md)
* [Java IO 与 NIO系列文章](docs/Java/Java%20IO与NIO.md)
### Java 8
* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md)
* [Java 8 新特性总结](docs/java/What's%20New%20in%20JDK8/Java8Tutorial.md)
## 网络
* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md)
* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md)
* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md)
* [计算机网络常见面试题](docs/network/计算机网络.md)
* [计算机网络基础知识总结](docs/network/干货:计算机网络知识总结.md)
* [HTTPS中的TLS](docs/network/HTTPS中的TLS.md)
## 操作系统
### Linux相关
* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md)
* [Shell 编程入门](./操作系统/Shell.md)
* [后端程序员必备的 Linux 基础知识](docs/operating-system/后端程序员必备的Linux基础知识.md)
* [Shell 编程入门](docs/operating-system/Shell.md)
## 数据结构与算法
### 数据结构
- [数据结构知识学习与面试](./数据结构与算法/数据结构.md)
- [数据结构知识学习与面试](docs/dataStructures-algorithms/数据结构.md)
### 算法
- [算法学习与面试](./数据结构与算法/算法.md)
- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md)
- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md)
- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md)
- [算法学习与面试](docs/dataStructures-algorithms/算法.md)
- [算法总结——几道常见的子符串算法题 ](docs/dataStructures-algorithms/搞定BAT面试——几道常见的子符串算法题.md)
- [算法总结——几道常见的链表算法题 ](docs/dataStructures-algorithms/Leetcode-LinkList1.md)
- [常见安全算法(MD5、SHA1、Base64等等)总结](docs/dataStructures-algorithms/常见安全算法(MD5、SHA1、Base64等等)总结.md)
## 数据存储
## 数据
### MySQL
* [MySQL 学习与面试](./数据存储/MySQL.md)
* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md)
* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md)
* [MySQL 学习与面试](docs/database/MySQL.md)
* [【思维导图-索引篇】搞定数据库索引就是这么简单](docs/database/MySQL%20Index.md)
* [一千行MySQL学习笔记](docs/database/一千行MySQL命令.md)
### Redis
* [Redis 总结](./数据存储/Redis/Redis.md)
* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md)
* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md)
* [Redis 总结](docs/database/Redis/Redis.md)
* [Redlock分布式锁](docs/database/Redis/Redlock分布式锁.md)
* [如何做可靠的分布式锁,Redlock真的可行么](docs/database/Redis/如何做可靠的分布式锁,Redlock真的可行么.md)
## 系统设计
### 设计模式
- [设计模式系列文章](./Java/设计模式.md)
- [设计模式系列文章](docs/system-design/设计模式.md)
### 常用框架
#### Spring
- [Spring 学习与面试](./主流框架/Spring学习与面试.md)
- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md)
- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md)
- [Spring 学习与面试](docs/system-design/framework/Spring学习与面试.md)
- [Spring中bean的作用域与生命周期](docs/system-design/framework/SpringBean.md)
- [SpringMVC 工作原理详解](docs/system-design/framework/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md)
#### ZooKeeper
- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md)
- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md)
- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](docs/system-design/framework/ZooKeeper.md)
- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](docs/system-design/framework/ZooKeeper数据模型和常见命令.md)
### 数据通信
- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md)
- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md)
- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md)
- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md)
- [数据通信(RESTful、RPC、消息队列)相关知识点总结](docs/system-design/data-communication/数据通信(RESTful、RPC、消息队列).md)
- [Dubbo 总结:关于 Dubbo 的重要知识点](docs/system-design/data-communication/dubbo.md)
- [消息队列总结:新手也能看懂,消息队列其实很简单](docs/system-design/data-communication/message-queue.md)
- [一文搞懂 RabbitMQ 的重要概念以及安装](docs/system-design/data-communication/rabbitmq.md)
### 网站架构
- [一文读懂分布式应该学什么](./架构/分布式.md)
- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md)
- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md)
- [一文读懂分布式应该学什么](docs/system-design/website-architecture/分布式.md)
- [8 张图读懂大型网站技术架构](docs/system-design/website-architecture/8%20张图读懂大型网站技术架构.md)
- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](docs/system-design/website-architecture/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md)
## 面试指南
### 备战面试
* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md)
* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md)
* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md)
* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md)
* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md)
* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md)
* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md)
* [【备战面试1】程序员的简历就该这样写](docs/essential-content-for-interview/PreparingForInterview/程序员的简历之道.md)
* [【备战面试2】初出茅庐的程序员该如何准备面试?](docs/essential-content-for-interview/PreparingForInterview/interviewPrepare.md)
* [【备战面试3】7个大部分程序员在面试前很关心的问题](docs/essential-content-for-interview/PreparingForInterview/JavaProgrammerNeedKnow.md)
* [【备战面试4】Java程序员必备书单](docs/essential-content-for-interview/PreparingForInterview/books.md)
* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](docs/essential-content-for-interview/PreparingForInterview/JavaInterviewLibrary.md)
* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](docs/essential-content-for-interview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md)
* [【备战面试7】美团面试常见问题总结(附详解答案)](docs/essential-content-for-interview/PreparingForInterview/美团面试常见问题总结.md)
### 常见面试题总结
* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals)
* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......)
* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结)
* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。)
* [第一周(2018-8-7)](docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals)
* [第二周(2018-8-13)](docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......)
* [第三周(2018-08-22)](docs/java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结)
* [第四周(2018-8-30).md](docs/essential-content-for-interview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。)
### 面经
- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md)
- [5面阿里,终获offer(2018年秋招)](docs/essential-content-for-interview/BATJrealInterviewExperience/5面阿里,终获offer.md)
## 工具
### Git
* [Git入门](./Tools/Git.md)
* [Git入门](docs/tools/Git.md)
### Docker
* [Docker 入门](./Tools/Docker.md)
* [Docker 入门](docs/tools/Docker.md)
## 资料
### 书单
- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md)
- [Java程序员必备书单](docs/essential-content-for-interview//PreparingForInterview/books.md)
## 闲谈
......
<h1 align="center">Java 学习/面试指南</h1>
<p align="center">
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/logo - 副本.png" width=""/>
</p>
<p align="center">
<a href="#联系我"><img src="https://img.shields.io/badge/chat-微信群-blue.svg" alt="微信群"></a>
<a href="https://gitee.com/SnailClimb/JavaGuide"><img src="https://img.shields.io/badge/%E7%A0%81%E4%BA%91-SnailClimb-brightgreen.svg" alt="码云地址"></a>
<a href="#公众号"><img src="https://img.shields.io/badge/%E5%85%AC%E4%BC%97%E5%8F%B7-JavaGuide-lightgrey.svg" alt="公众号"></a>
<a href="#公众号"><img src="https://img.shields.io/badge/PDF-Java面试突击-important.svg" alt="公众号"></a>
<h2 align="center">Special Sponsors</h2>
</p>
<p align="center">
<a href="https://e.coding.net/?utm_source=JavaGuide" target="_blank">
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/Coding Devops.png" width=""/>
</a>
</p>
1. **码云地址:** 如果访问速度比较慢的话,可以考虑访问本仓库的码云地址:<https://gitee.com/SnailClimb/JavaGuide> ,Gitee 和 都是同步更新的。
1. **关于贡献者:** 对本仓库提过有价值的 issue 或 pr 的小伙伴将出现在 [Contributor](#Contributor) 这里。
1. **欢迎投稿:** 由于我个人能力有限,很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。**对于不错的原创文章我根据你的选择给予现金(50-300)、付费专栏或者任选书籍进行奖励!所以,快提 pr 或者邮件的方式(邮件地址在主页)给我投稿吧!** 当然,我觉得奖励是次要的,最重要的是你可以从自己整理知识点的过程中学习到很多知识。
## 目录
- [Java](#java)
- [基础](#基础)
- [容器](#容器)
- [并发](#并发)
- [JVM](#jvm)
- [I/O](#io)
- [Java 8](#java-8)
- [网络](#网络)
- [操作系统](#操作系统)
- [Linux相关](#linux相关)
- [数据结构与算法](#数据结构与算法)
- [数据结构](#数据结构)
- [算法](#算法)
- [数据存储](#数据存储)
- [MySQL](#mysql)
- [Redis](#redis)
- [系统设计](#系统设计)
- [设计模式](#设计模式)
- [常用框架](#常用框架)
- [数据通信](#数据通信)
- [网站架构](#网站架构)
- [面试指南](#面试指南)
- [备战面试](#备战面试)
- [常见面试题总结](#常见面试题总结)
- [面经](#面经)
- [工具](#工具)
- [Git](#git)
- [Docker](#Docker)
- [资料](#资料)
- [书单](#书单)
- [闲谈](#闲谈)
- [待办](#待办)
- [说明](#说明)
## Java
### 基础
* [Java 基础知识回顾](./Java/Java基础知识.md)
* [J2EE 基础知识回顾](./Java/J2EE基础知识.md)
* [Collections 工具类和 Arrays 工具类常见方法](./Java/Basis/Arrays%2CCollectionsCommonMethods.md)
* [Java常见关键字总结:static、final、this、super](./Java/Basis/final、static、this、super.md)
### 容器
* **常见问题总结:**
* [这几道Java集合框架面试题几乎必问](./Java/这几道Java集合框架面试题几乎必问.md)
* [Java 集合框架常见面试题总结](./Java/Java集合框架常见面试题总结.md)
* **源码分析:**
* [ArrayList 源码学习](./Java/ArrayList.md)
* [【面试必备】透过源码角度一步一步带你分析 ArrayList 扩容机制](./Java/ArrayList-Grow.md)
* [LinkedList 源码学习](./Java/LinkedList.md)
* [HashMap(JDK1.8)源码学习](./Java/HashMap.md)
### 并发
* [并发编程面试必备:synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比](./Java/synchronized.md)
* [并发编程面试必备:乐观锁与悲观锁](./EssentialContentForInterview/面试必备之乐观锁与悲观锁.md)
* [并发编程面试必备:JUC 中的 Atomic 原子类总结](./Java/Multithread/Atomic.md)
* [并发编程面试必备:AQS 原理以及 AQS 同步组件总结](./Java/Multithread/AQS.md)
* [BATJ都爱问的多线程面试题](./Java/Multithread/BATJ都爱问的多线程面试题.md)
* [并发容器总结](./Java/Multithread/并发容器总结.md)
### JVM
* [可能是把Java内存区域讲的最清楚的一篇文章](./Java/可能是把Java内存区域讲的最清楚的一篇文章.md)
* [搞定JVM垃圾回收就是这么简单](./Java/搞定JVM垃圾回收就是这么简单.md)
* [《深入理解Java虚拟机》第2版学习笔记](./Java/Java虚拟机(jvm).md)
### I/O
* [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md)
* [Java IO 与 NIO系列文章](./Java/Java%20IO与NIO.md)
### Java 8
* [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md)
## 网络
* [计算机网络常见面试题](./计算机网络与数据通信/计算机网络.md)
* [计算机网络基础知识总结](./计算机网络与数据通信/干货:计算机网络知识总结.md)
* [HTTPS中的TLS](./计算机网络与数据通信/HTTPS中的TLS.md)
## 操作系统
### Linux相关
* [后端程序员必备的 Linux 基础知识](./操作系统/后端程序员必备的Linux基础知识.md)
* [Shell 编程入门](./操作系统/Shell.md)
## 数据结构与算法
### 数据结构
- [数据结构知识学习与面试](./数据结构与算法/数据结构.md)
### 算法
- [算法学习与面试](./数据结构与算法/算法.md)
- [算法总结——几道常见的子符串算法题 ](./数据结构与算法/搞定BAT面试——几道常见的子符串算法题.md)
- [算法总结——几道常见的链表算法题 ](./数据结构与算法/Leetcode-LinkList1.md)
- [常见安全算法(MD5、SHA1、Base64等等)总结](./数据结构与算法/常见安全算法(MD5、SHA1、Base64等等)总结.md)
## 数据存储
### MySQL
* [MySQL 学习与面试](./数据存储/MySQL.md)
* [【思维导图-索引篇】搞定数据库索引就是这么简单](./数据存储/MySQL%20Index.md)
* [一千行MySQL学习笔记](./数据存储/一千行MySQL命令.md)
### Redis
* [Redis 总结](./数据存储/Redis/Redis.md)
* [Redlock分布式锁](./数据存储/Redis/Redlock分布式锁.md)
* [如何做可靠的分布式锁,Redlock真的可行么](./数据存储/Redis/如何做可靠的分布式锁,Redlock真的可行么.md)
## 系统设计
### 设计模式
- [设计模式系列文章](./Java/设计模式.md)
### 常用框架
#### Spring
- [Spring 学习与面试](./主流框架/Spring学习与面试.md)
- [Spring中bean的作用域与生命周期](./主流框架/SpringBean.md)
- [SpringMVC 工作原理详解](./主流框架/SpringMVC%20%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E8%AF%A6%E8%A7%A3.md)
#### ZooKeeper
- [可能是把 ZooKeeper 概念讲的最清楚的一篇文章](./主流框架/ZooKeeper.md)
- [ZooKeeper 数据模型和常见命令了解一下,速度收藏!](./主流框架/ZooKeeper数据模型和常见命令.md)
### 数据通信
- [数据通信(RESTful、RPC、消息队列)相关知识点总结](./计算机网络与数据通信/数据通信(RESTful、RPC、消息队列).md)
- [Dubbo 总结:关于 Dubbo 的重要知识点](./计算机网络与数据通信/dubbo.md)
- [消息队列总结:新手也能看懂,消息队列其实很简单](./计算机网络与数据通信/message-queue.md)
- [一文搞懂 RabbitMQ 的重要概念以及安装](./计算机网络与数据通信/rabbitmq.md)
### 网站架构
- [一文读懂分布式应该学什么](./架构/分布式.md)
- [8 张图读懂大型网站技术架构](./架构/8%20张图读懂大型网站技术架构.md)
- [【面试精选】关于大型网站系统架构你不得不懂的10个问题](./架构/[面试精选]关于大型网站系统架构你不得不懂的10个问题.md)
## 面试指南
### 备战面试
* [【备战面试1】程序员的简历就该这样写](./EssentialContentForInterview/PreparingForInterview/程序员的简历之道.md)
* [【备战面试2】初出茅庐的程序员该如何准备面试?](./EssentialContentForInterview/PreparingForInterview/interviewPrepare.md)
* [【备战面试3】7个大部分程序员在面试前很关心的问题](./EssentialContentForInterview/PreparingForInterview/JavaProgrammerNeedKnow.md)
* [【备战面试4】Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md)
* [【备战面试5】Github上开源的Java面试/学习相关的仓库推荐](./EssentialContentForInterview/PreparingForInterview/JavaInterviewLibrary.md)
* [【备战面试6】如果面试官问你“你有什么问题问我吗?”时,你该如何回答](./EssentialContentForInterview/PreparingForInterview/如果面试官问你“你有什么问题问我吗?”时,你该如何回答.md)
* [【备战面试7】美团面试常见问题总结(附详解答案)](./EssentialContentForInterview/PreparingForInterview/美团面试常见问题总结.md)
### 常见面试题总结
* [第一周(2018-8-7)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第一周(2018-8-7).md) (为什么 Java 中只有值传递、==与equals、 hashCode与equals)
* [第二周(2018-8-13)](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第二周(2018-8-13).md)(String和StringBuffer、StringBuilder的区别是什么?String为什么是不可变的?、什么是反射机制?反射机制的应用场景有哪些?......)
* [第三周(2018-08-22)](./Java/这几道Java集合框架面试题几乎必问.md) (Arraylist 与 LinkedList 异同、ArrayList 与 Vector 区别、HashMap的底层实现、HashMap 和 Hashtable 的区别、HashMap 的长度为什么是2的幂次方、HashSet 和 HashMap 区别、ConcurrentHashMap 和 Hashtable 的区别、ConcurrentHashMap线程安全的具体实现方式/底层具体实现、集合框架底层数据结构总结)
* [第四周(2018-8-30).md](./EssentialContentForInterview/MostCommonJavaInterviewQuestions/第四周(2018-8-30).md) (主要内容是几道面试常问的多线程基础题。)
### 面经
- [5面阿里,终获offer(2018年秋招)](./EssentialContentForInterview/BATJrealInterviewExperience/5面阿里,终获offer.md)
## 工具
### Git
* [Git入门](./Tools/Git.md)
### Docker
* [Docker 入门](./Tools/Docker.md)
## 资料
### 书单
- [Java程序员必备书单](./EssentialContentForInterview/PreparingForInterview/books.md)
## 闲谈
* [选择技术方向都要考虑哪些因素](./闲谈/选择技术方向都要考虑哪些因素.md)
* [结束了我短暂的秋招,说点自己的感受](./闲谈/2018%20%E7%A7%8B%E6%8B%9B.md)
* [Java项目 Github Trending 月榜](./闲谈/JavaGithubTrending/JavaGithubTrending.md)
***
## 待办
- [x] [Java 8 新特性总结](./Java/What's%20New%20in%20JDK8/Java8Tutorial.md)
- [ ] Java 8 新特性详解
- [ ] Java 多线程类别知识重构
- [x] [BIO,NIO,AIO 总结 ](./Java/BIO%2CNIO%2CAIO%20summary.md)
- [ ] Netty 总结
- [ ] 数据结构总结重构
## 说明
### 介绍
* **对于 Java 初学者来说:** 本文档倾向于给你提供一个比较详细的学习路径,让你对于Java整体的知识体系有一个初步认识。另外,本文的一些文章
也是你学习和复习 Java 知识不错的实践;
* **对于非 Java 初学者来说:** 本文档更适合回顾知识,准备面试,搞清面试应该把重心放在那些问题上。要搞清楚这个道理:提前知道那些面试常见,不是为了背下来应付面试,而是为了让你可以更有针对的学习重点。
本文档 Markdown 格式参考:[Github Markdown格式](https://guides.github.com/features/mastering-markdown/),表情素材来自:[EMOJI CHEAT SHEET](https://www.webpagefx.com/tools/emoji-cheat-sheet/)
### 关于转载
如果你需要转载本仓库的一些文章到自己的博客的话,记得注明原文地址就可以了。
### 如何对该开源文档进行贡献
1. 笔记内容大多是手敲,所以难免会有笔误,你可以帮我找错别字。
2. 很多知识点我可能没有涉及到,所以你可以对其他知识点进行补充。(**对于不错的原创文章我根据你的选择给予现金奖励、付费专栏或者书籍进行奖励!快提 pr 给我投稿吧!**)
3. 现有的知识点难免存在不完善或者错误,所以你可以对已有知识点的修改/补充。
### 为什么要做这个开源文档?
初始想法源于自己的个人那一段比较迷茫的学习经历。主要目的是为了通过这个开源平台来帮助一些在学习 Java 或者面试过程中遇到问题的小伙伴。
### 联系我
添加我的微信备注“Github”,回复关键字 **“加群”** 即可入群。
![我的微信](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-2/JavaGuide.jpg)
### Contributor
下面是笔主收集的一些对本仓库提过有价值的pr或者issue的朋友,人数较多,如果你也对本仓库提过不错的pr或者issue的话,你可以加我的微信与我联系。下面的排名不分先后!
<a href="https://github.com/fanofxiaofeng">
<img src="https://avatars0.githubusercontent.com/u/3983683?s=460&v=4" width="45px"></a>
<a href="https://github.com/Gene1994">
<img src="https://avatars3.githubusercontent.com/u/24930369?s=460&v=4" width="45px">
</a>
<a href="https://github.com/illusorycloud">
<img src="https://avatars3.githubusercontent.com/u/31980412?s=460&v=4" width="45px">
</a>
<a href="https://github.com/LiWenGu">
<img src="https://avatars0.githubusercontent.com/u/15909210?s=460&v=4" width="45px">
</a>
<a href="https://github.com/kinglaw1204">
<img src="https://avatars1.githubusercontent.com/u/20039931?s=460&v=4" width="45px">
</a>
<a href="https://github.com/jun1st">
<img src="https://avatars2.githubusercontent.com/u/14312378?s=460&v=4" width="45px">
</a>"
<a href="https://github.com/fantasygg">
<img src="https://avatars3.githubusercontent.com/u/13445354?s=460&v=4" width="45px">
</a>
<a href="https://github.com/debugjoker">
<img src="https://avatars3.githubusercontent.com/u/26218005?s=460&v=4" width="45px">
</a>
<a href="https://github.com/zhyank">
<img src="https://avatars0.githubusercontent.com/u/17696240?s=460&v=4" width="45px">
</a>
<a href="https://github.com/Goose9527">
<img src="https://avatars2.githubusercontent.com/u/43314997?s=460&v=4" width="45px">
</a>
<a href="https://github.com/yuechuanx">
<img src="https://avatars3.githubusercontent.com/u/19339293?s=460&v=4" width="45px">
</a>
### 公众号
如果大家想要实时关注我更新的文章以及分享的干货的话,可以关注我的公众号。
**《Java面试突击》:** 由本文档衍生的专为面试而生的《Java面试突击》V2.0 PDF 版本[公众号](#公众号)后台回复 **"Java面试突击"** 即可免费领取!
**Java工程师必备学习资源:** 一些Java工程师常用学习资源[公众号](#公众号)后台回复关键字 **“1”** 即可免费无套路获取。
![我的公众号](https://user-gold-cdn.xitu.io/2018/11/28/167598cd2e17b8ec?w=258&h=258&f=jpeg&s=27334)
# Java 并发基础知识
Java 并发的基础知识,可能会在笔试中遇到,技术面试中也可能以并发知识环节提问的第一个问题出现。比如面试官可能会问你:“谈谈自己对于进程和线程的理解,两者的区别是什么?”
**本节思维导图:**
![Java 并发基础知识](http://my-blog-to-use.oss-cn-beijing.aliyuncs.com/18-10-26/51390272.jpg)
## 一 进程和线程
进程和线程的对比这一知识点由于过于基础,所以在面试中很少碰到,但是极有可能会在笔试题中碰到。
常见的提问形式是这样的:**“什么是线程和进程?,请简要描述线程与进程的关系、区别及优缺点? ”**
### 1.1. 何为进程?
进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行一个程序即是一个进程从创建,运行到消亡的过程。
在Java中,当我们启动 main 函数时其实就是启动了一个 JVM 的进程,而 main 函数所在的线程就是这个进程中的一个线程,也称主线程。
如下图所示,在 windows 中通过查看任务管理器的方式,我们就可以清楚看到 window 当前运行的进程(.exe文件的运行)。
![进程](https://images.gitbook.cn/a0929b60-d133-11e8-88a4-5328c5b70145)
### 1.2 何为线程?
线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程。与进程不同的是同类的多个线程共享进程的**堆****方法区**资源,但每个线程有自己的**程序计数器****虚拟机栈****本地方法栈**,所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。
Java 程序天生就是多线程程序,我们可以通过 JMX 来看一下一个普通的 Java 程序有哪些线程,代码如下。
```java
public class MultiThread {
public static void main(String[] args) {
// 获取Java线程管理MXBean
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 不需要获取同步的monitor和synchronizer信息,仅获取线程和线程堆栈信息
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
// 遍历线程信息,仅打印线程ID和线程名称信息
for (ThreadInfo threadInfo : threadInfos) {
System.out.println("[" + threadInfo.getThreadId() + "] " + threadInfo.getThreadName());
}
}
}
```
上述程序输出如下(输出内容可能不同,不用太纠结下面每个线程的作用,只用知道 main 线程执行main方法即可):
```
[5] Attach Listener //添加事件
[4] Signal Dispatcher // 分发处理给JVM信号的线程
[3] Finalizer //调用对象finalize方法的线程
[2] Reference Handler //清除reference线程
[1] main //main线程,程序入口
```
从上面的输出内容可以看出:**一个 Java 程序的运行是 main 线程和多个其他线程同时运行**
### 1.3 从 JVM 角度说进程和线程之间的关系(重要)
#### 1.3.1 图解进程和线程的关系
下图是 Java 内存区域,通过下图我们从 JVM 的角度来说一下线程和进程之间的关系。如果你对 Java 内存区域(运行时数据区)这部分知识不太了解的话可以阅读一下我的这篇文章:[《可能是把Java内存区域讲的最清楚的一篇文章》](https://github.com/Snailclimb/JavaGuide/blob/master/Java相关/可能是把Java内存区域讲的最清楚的一篇文章.md)
![](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/JVM运行时数据区域.png)
从上图可以看出:一个进程中可以有多个线程,多个线程共享进程的**堆****方法区**资源,但是每个线程有自己的**程序计数器****虚拟机栈****本地方法栈**
下面来思考这样一个问题:为什么**程序计数器****虚拟机栈****本地方法栈**是线程私有的呢?为什么堆和方法区是线程共享的呢?
#### 1.3.2 程序计数器为什么是私有的?
程序计数器主要有下面两个作用:
1. 字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理。
2. 在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了。
需要注意的是,如果执行的是native方法,那么程序计数器记录的是undefined地址,只有执行的是Java代码时程序计数器记录的才是下一条指令的地址。
所以,程序计数器私有主要是为了**线程切换后能恢复到正确的执行位置**
#### 1.3.3 虚拟机栈和本地方法栈为什么是私有的?
- **虚拟机栈:**每个 Java 方法在执行的同时会创建一个栈帧用于存储局部变量表、操作数栈、常量池引用等信息。从方法调用直至执行完成的过程,就对应着一个栈帧在 Java 虚拟机栈中入栈和出栈的过程。
- **本地方法栈:**和虚拟机栈所发挥的作用非常相似,区别是: **虚拟机栈为虚拟机执行 Java 方法 (也就是字节码)服务,而本地方法栈则为虚拟机使用到的 Native 方法服务。** 在 HotSpot 虚拟机中和 Java 虚拟机栈合二为一。
所以,为了**保证线程中的局部变量不被别的线程访问到**,虚拟机栈和本地方法栈是线程私有的。
#### 1.3.4 一句话简单了解堆和方法区
堆和方法区是所有线程共享的资源,其中堆是进程中最大的一块内存,主要用于存放新创建的对象(所有对象都在这里分配内存),方法区主要用于存放已被加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
## 二 多线程并发编程
### 2.1 并发与并行
- **并发:** 同一时间段,多个任务都在执行(单位时间内不一定同时执行);
- **并行:**单位时间内,多个任务同时执行。
### 2.1 多线程并发编程详解
单CPU时代多个任务共享一个CPU,某一特定时刻只能有一个任务被执行,CPU会分配时间片给当前要执行的任务。当一个任务占用CPU时,其他任务就会被挂起。当占用CPU的任务的时间片用完后,才会由 CPU 选择下一个需要执行的任务。所以说,在单核CPU时代,多线程编程没有太大意义,反而会因为线程间频繁的上下文切换而带来额外开销。
但现在 CPU 一般都是多核,如果这个CPU是多核的话,那么进程中的不同线程可以使用不同核心,实现了真正意义上的并行运行。**那为什么我们不直接叫做多线程并行编程呢?**
**这是因为多线程在实际开发使用中,线程的个数往往多于CPU的个数,所以一般都称多线程并发编程而不是多线程并行编程。`**
### 2.2 为什么要多线程并发编程?
- **从计算机底层来说:**线程可以比作是轻量级的进程,是程序执行的最小单位,线程间的切换和调度的成本远远小于进程。另外,多核 CPU 时代意味着多个线程可以同时运行,这减少了线程上下文切换的开销。
- **从当代互联网发展趋势来说:**现在的系统动不动就要求百万级甚至千万级的并发量,而多线程并发编程正是开发高并发系统的基础,利用好多线程机制可以大大提高系统整体的并发能力以及性能。
## 三 线程的创建与运行
前两种实际上很少使用,一般都是用线程池的方式比较多一点。
### 3.1 继承 Thread 类的方式
```java
public class MyThread extends Thread {
@Override
public void run() {
super.run();
System.out.println("MyThread");
}
}
```
Run.java
```java
public class Run {
public static void main(String[] args) {
MyThread mythread = new MyThread();
mythread.start();
System.out.println("运行结束");
}
}
```
运行结果:
![结果](https://user-gold-cdn.xitu.io/2018/3/20/16243e80f22a2d54?w=161&h=54&f=jpeg&s=7380)
从上面的运行结果可以看出:线程是一个子任务,CPU以不确定的方式,或者说是以随机的时间来调用线程中的run方法。
### 3.2 实现Runnable接口的方式
推荐实现Runnable接口方式开发多线程,因为Java单继承但是可以实现多个接口。
MyRunnable.java
```java
public class MyRunnable implements Runnable {
@Override
public void run() {
System.out.println("MyRunnable");
}
}
```
Run.java
```java
public class Run {
public static void main(String[] args) {
Runnable runnable=new MyRunnable();
Thread thread=new Thread(runnable);
thread.start();
System.out.println("运行结束!");
}
}
```
运行结果:
![运行结果](https://user-gold-cdn.xitu.io/2018/3/20/16243f4373c6141a?w=137&h=46&f=jpeg&s=7316)
### 3.3 使用线程池的方式
使用线程池的方式也是最推荐的一种方式,另外,《阿里巴巴Java开发手册》在第一章第六节并发处理这一部分也强调到“线程资源必须通过线程池提供,不允许在应用中自行显示创建线程”。这里就不给大家演示代码了,线程池这一节会详细介绍到这部分内容。
## 四 线程的生命周期和状态
Java 线程在运行的生命周期中的指定时刻只可能处于下面6种不同状态的其中一个状态(图源《Java 并发编程艺术》4.1.4节)。
![Java线程的状态](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%E7%BA%BF%E7%A8%8B%E7%9A%84%E7%8A%B6%E6%80%81.png)
线程在生命周期中并不是固定处于某一个状态而是随着代码的执行在不同状态之间切换。Java 线程状态变迁如下图所示(图源《Java 并发编程艺术》4.1.4节):
![Java线程状态变迁](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/19-1-29/Java%20%E7%BA%BF%E7%A8%8B%E7%8A%B6%E6%80%81%E5%8F%98%E8%BF%81.png)
由上图可以看出:
线程创建之后它将处于 **NEW(新建)** 状态,调用 `start()` 方法后开始运行,线程这时候处于 **READY(可运行)** 状态。可运行状态的线程获得了 cpu 时间片(timeslice)后就处于 **RUNNING(运行)** 状态。
> 操作系统隐藏 Java虚拟机(JVM)中的 RUNNABLE 和 RUNNING 状态,它只能看到 RUNNABLE 状态(图源:[HowToDoInJava](https://howtodoinjava.com/):[Java Thread Life Cycle and Thread States](https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/)),所以 Java 系统一般将这两个状态统称为 **RUNNABLE(运行中)** 状态 。
![RUNNABLE-VS-RUNNING](https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-3/RUNNABLE-VS-RUNNING.png)
当线程执行 `wait()`方法之后,线程进入 **WAITING(等待)**状态。进入等待状态的线程需要依靠其他线程的通知才能够返回到运行状态,而 **TIME_WAITING(超时等待)** 状态相当于在等待状态的基础上增加了超时限制,比如通过 `sleep(long millis)`方法或 `wait(long millis)`方法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调用同步方法时,在没有获取到锁的情况下,线程将会进入到 **BLOCKED(阻塞)** 状态。线程在执行 Runnable 的` run() `方法之后将会进入到 **TERMINATED(终止)** 状态。
## 五 线程优先级
**理论上**来说系统会根据优先级来决定首先使哪个线程进入运行状态。当 CPU 比较闲的时候,设置线程优先级几乎不会有任何作用,而且很多操作系统压根不会不会理会你设置的线程优先级,所以不要让业务过度依赖于线程的优先级。
另外,**线程优先级具有继承特性**比如A线程启动B线程,则B线程的优先级和A是一样的。**线程优先级还具有随机性** 也就是说线程优先级高的不一定每一次都先执行完。
Thread类中包含的成员变量代表了线程的某些优先级。如**Thread.MIN_PRIORITY(常数1)****Thread.NORM_PRIORITY(常数5)**,**Thread.MAX_PRIORITY(常数10)**。其中每个线程的优先级都在**1****10** 之间,在默认情况下优先级都是**Thread.NORM_PRIORITY(常数5)**
**一般情况下,不会对线程设定优先级别,更不会让某些业务严重地依赖线程的优先级别,比如权重,借助优先级设定某个任务的权重,这种方式是不可取的,一般定义线程的时候使用默认的优先级就好了。**
**相关方法:**
```java
public final void setPriority(int newPriority) //为线程设定优先级
public final int getPriority() //获取线程的优先级
```
**设置线程优先级方法源码:**
```java
public final void setPriority(int newPriority) {
ThreadGroup g;
checkAccess();
//线程游戏优先级不能小于1也不能大于10,否则会抛出异常
if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
throw new IllegalArgumentException();
}
//如果指定的线程优先级大于该线程所在线程组的最大优先级,那么该线程的优先级将设为线程组的最大优先级
if((g = getThreadGroup()) != null) {
if (newPriority > g.getMaxPriority()) {
newPriority = g.getMaxPriority();
}
setPriority0(priority = newPriority);
}
}
```
## 六 守护线程和用户线程
**守护线程和用户线程简介:**
- **用户(User)线程:**运行在前台,执行具体的任务,如程序的主线程、连接网络的子线程等都是用户线程
- **守护(Daemon)线程:**运行在后台,为其他前台线程服务.也可以说守护线程是JVM中非守护线程的 **“佣人”**。一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作.
main 函数所在的线程就是一个用户线程啊,main函数启动的同时在JVM内部同时还启动了好多守护线程,比如垃圾回收线程。
**那么守护线程和用户线程有什么区别呢?**
比较明显的区别之一是用户线程结束,JVM退出,不管这个时候有没有守护线程运行。而守护线程不会影响 JVM 的退出。
**注意事项:**
1. `setDaemon(true)`必须在`start()`方法前执行,否则会抛出 `IllegalThreadStateException` 异常
2. 在守护线程中产生的新线程也是守护线程
3. 不是所有的任务都可以分配给守护线程来执行,比如读写操作或者计算逻辑
4. 守护(Daemon)线程中不能依靠 finally 块的内容来确保执行关闭或清理资源的逻辑。因为我们上面也说过了一旦所有用户线程都结束运行,守护线程会随JVM一起结束工作,所以守护(Daemon)线程中的finally语句块可能无法被执行。
## 参考
- 《Java并发编程之美》
- 《Java并发编程的艺术》
- https://howtodoinjava.com/java/multi-threading/java-thread-life-cycle-and-thread-states/
\ No newline at end of file
Stream API 旨在让编码更高效率、干净、简洁。
### 从迭代器到Stream操作
当使用 `Stream` 时,我们一般会通过三个阶段建立一个流水线:
1. 创建一个 `Stream`
2. 进行一个或多个中间操作;
3. 使用终止操作产生一个结果,`Stream` 就不会再被使用了。
**案例1:统计 List 中的单词长度大于6的个数**
```java
/**
* 案例1:统计 List 中的单词长度大于6的个数
*/
ArrayList<String> wordsList = new ArrayList<String>();
wordsList.add("Charles");
wordsList.add("Vincent");
wordsList.add("William");
wordsList.add("Joseph");
wordsList.add("Henry");
wordsList.add("Bill");
wordsList.add("Joan");
wordsList.add("Linda");
int count = 0;
```
Java8之前我们通常用迭代方法来完成上面的需求:
```java
//迭代(Java8之前的常用方法)
//迭代不好的地方:1. 代码多;2 很难被并行运算。
for (String word : wordsList) {
if (word.length() > 6) {
count++;
}
}
System.out.println(count);//3
```
Java8之前我们使用 `Stream` 一行代码就能解决了,而且可以瞬间转换为并行执行的效果:
```java
//Stream
//将stream()改为parallelStream()就可以瞬间将代码编程并行执行的效果
long count2=wordsList.stream()
.filter(w->w.length()>6)
.count();
long count3=wordsList.parallelStream()
.filter(w->w.length()>6)
.count();
System.out.println(count2);
System.out.println(count3);
```
### `distinct()`
去除 List 中重复的 String
```java
List<String> list = list.stream()
.distinct()
.collect(Collectors.toList());
```
### `map`
map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:
```java
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// 获取 List 中每个元素对应的平方数并去重
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
System.out.println(squaresList.toString());//[9, 4, 49, 25]
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册