java基础-集合

以下为本人的学习笔记

1.集合框架概述

1.1集合框架 的作用

在实际开发中,我们经常会对一组相同类型的数据进行统一管理操作。到目前为止,我们可以使用数组结构,链表结构,二叉树来实现。

数组的最大问题在于数组中的元素个数是固定的,要实现动态数组,还是比较麻烦,

在JDK1.2版本后,java完整提供了类集合的概念,封装了一组强大的,非常方便的集合框架API,让我们在开发中大大的提高了效率。

集合中分为三大接口;

Collection、Map、Iterator

集合框架的接口和类在java.util包中

1.2 集合框架结构图:

注:虚线表示接口,实现表示实现类。

1.3 Collection接口

Collection 层次结构_中的根接口。Collection 表示一组对象,这些对象也称为 collection 的 _元素。一些 collection 允许有重复的元素,而另一些则不允许。一些 collection 是有序的,而另一些则是无序的。JDK 不提供此接口的任何 _直接_实现:它提供更具体的子接口(如 SetList)实现。此接口通常用来传递 collection,并在需要最大普遍性的地方操作这些 collection。

接口的定义:

public interface Collection extends Iterator

2集合框架List接口

2.1 List接口

public interface List extends Collection

有序的 collection(也称为 序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。

/**
Collection接口:用于存储单个对象的集合
List接口:
1.有序的,可重复
2.允许多个null元素
3.具体的实现类有常用的:ArrayList,LinkedList,Vector
Set接口
*/
public class ListDemo{
    private static  void arrayList(){
        //使用集合来存储多个不同类型的元素(对象),在处理时会比较麻烦,在实际开发中,不建议这样使用
     // List list = new ArrayList();
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x5728;&#x96C6;&#x5408;&#x4E2D;&#x5B58;&#x50A8;&#x76F8;&#x540C;&#x7C7B;&#x578B;&#x7684;&#x5BF9;&#x8C61;,&#x7B2C;&#x4E8C;&#x4E2A;<>&#x91CC;&#x5728;jdk1.8&#x53EF;&#x4EE5;&#x4E0D;&#x7528;&#x5199;&#x7C7B;&#x578B;Sting
List<string> list = new ArrayList<>();//&#x52A0;&#x6CDB;&#x578B;&#x7EA6;&#x675F;String&#x7C7B;&#x578B;
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x5C0F;&#x7C73;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x8C03;&#x5EA6;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x72D7;&#x86CB;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x4E8C;&#x6BDB;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x65FA;&#x8D22;");
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x904D;&#x5386;&#x96C6;&#x5408;
 &#xA0; &#xA0; &#xA0; &#xA0;//for(int i = 0;i<list.size() ;i++),局部变量size会进栈,调用栈会比调用方法快,性能高得多,局部变量size只求一次,而方法要一直调用    int size="list.size();"  for(int i="0;i<size" ;i++){  system.out.println(list.get(i)) list.get(int i),获取下标为i 的值 } system.out.println(list.contains("小米")) contains():list是否包含"小米"  list.remove("小米") 删除"小米"  string[] array="list.toArray(new" string[]{}); toarray(),转换成array数组,参数:定义数组类型  for(string s: array){  system.out.println(s);  public static void main(string[] args){  arraylist(); }< code></list.size()></string>

在实际开发中,我们如何选择list的具体实现?

1.安全性问题

2.是否频繁插入,删除操作(LinkedList)

3.是否是存储后遍历

面试题:怎么实现ArrayList,即ArrayList的原理?

2.2ArrayList

public class ArrayList extends AbstractList implements List ,RandomAccess,Cloneable,Serializable

List接口的大小可变数组的实现。实现了所有可选列表操作,并允许包括 null在内的所有元素。除了实现 List接口外,此类还提供一些方法来操作内部用来存储列表的数组的大小。(

/**ArrayList
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;1.&#x5B9E;&#x73B0;&#x539F;&#x7406;&#xFF0C;&#x91C7;&#x7528;&#x52A8;&#x6001;&#x5BF9;&#x8C61;&#x6570;&#x7EC4;&#x5B9E;&#x73B0;&#xFF0C;&#x9ED8;&#x8BA4;&#x6784;&#x9020;&#x65B9;&#x6CD5;&#x521B;&#x5EFA;&#x4E86;&#x4E00;&#x4E2A;&#x7A7A;&#x6570;&#x7EC4;
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;2.&#x7B2C;&#x4E00;&#x6B21;&#x6DFB;&#x52A0;&#x5143;&#x7D20;&#xFF0C;&#x6269;&#x5C55;&#x5BB9;&#x91CF;&#x4E3A;10&#xFF0C;&#x4E4B;&#x540E;&#x7684;&#x6269;&#x5145;&#x7B97;&#x6CD5;&#xFF1A;&#x539F;&#x6765;&#x6570;&#x7EC4;&#x5927;&#x5C0F;&#xFF0B;&#x539F;&#x6765;&#x6570;&#x7EC4;&#x7684;&#x4E00;&#x534A;
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;3.&#x4E0D;&#x9002;&#x5408;&#x8FDB;&#x884C;&#x5220;&#x9664;&#x6216;&#x63D2;&#x5165;&#x64CD;&#x4F5C;&#xFF0C;&#x5426;&#x5219;&#x5BFC;&#x81F4;&#x4F4D;&#x7F6E;&#x4F1A;&#x53D8;
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;4.&#x4E3A;&#x4E86;&#x9632;&#x6B62;&#x6570;&#x7EC4;&#x52A8;&#x6001;&#x6269;&#x5145;&#x6B21;&#x6570;&#x8FC7;&#x591A;&#xFF0C;&#x5EFA;&#x8BAE;&#x521B;&#x5EFA;ArrayList&#x65F6;&#xFF0C;&#x7ED9;&#x5B9A;&#x521D;&#x59CB;&#x5BB9;&#x91CF;
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;5.&#x591A;&#x7EBF;&#x7A0B;&#x4E2D;&#x4F7F;&#x7528;&#x4E0D;&#x5B89;&#x5168;&#xFF0C;&#x9002;&#x5408;&#x5728;&#x5355;&#x7EBF;&#x7A0B;&#x8BBF;&#x95EE;&#x65F6;&#x4F7F;&#x7528;&#xFF0C;&#x5728;&#x5355;&#x7EBF;&#x7A0B;&#x4E0B;&#x4F7F;&#x7528;&#x6548;&#x7387;&#x9AD8;
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;JDK1.2&#x5F00;&#x59CB;
&#x200B;
*/
&#x200B;
2.3 Vector

Vector类可以实现可增长的对象数组。与数组一样,它包含可以使用整数索引进行访问的组件。但是, Vector的大小可以根据需要增大或缩小,以适应创建 Vector后进行添加或移除项的操作。

private static void vector(){
/**
&#x200B;
Vector
&#x200B;
1.&#x5B9E;&#x73B0;&#x539F;&#x7406;&#xFF0C;&#x91C7;&#x7528;&#x52A8;&#x6001;&#x5BF9;&#x8C61;&#x6570;&#x7EC4;&#x5B9E;&#x73B0;&#xFF0C;&#x9ED8;&#x8BA4;&#x6784;&#x9020;&#x65B9;&#x6CD5;&#x521B;&#x5EFA;&#x4E86;&#x4E00;&#x4E2A;&#x5927;&#x5C0F;&#x4E3A;10&#x7684;&#x5BF9;&#x8C61;&#x6570;&#x7EC4;
&#x200B;
2.&#x6269;&#x5145;&#x7684;&#x7B97;&#x6CD5;&#xFF1A;&#x5F53;&#x589E;&#x91CF;&#x4E3A;0&#x65F6;&#xFF0C;&#x6269;&#x5145;&#x4E3A;&#x539F;&#x6765;&#x5927;&#x5C0F;&#x7684;2&#x500D;&#xFF0C;&#x5F53;&#x589E;&#x91CF;>0&#x65F6;&#xFF0C;&#x6269;&#x5145;&#x4E3A;&#x539F;&#x6765;&#x5927;&#x5C0F;&#xFF0B;&#x589E;&#x91CF;
&#x200B;
3.&#x4E0D;&#x9002;&#x5408;&#x5220;&#x9664;&#x6216;&#x63D2;&#x5165;&#x64CD;&#x4F5C;
&#x200B;
4.&#x4E3A;&#x4E86;&#x9632;&#x6B62;&#x6570;&#x7EC4;&#x52A8;&#x6001;&#x6269;&#x5145;&#x6B21;&#x6570;&#x8FC7;&#x591A;&#xFF0C;&#x5EFA;&#x8BAE;&#x521B;&#x5EFA;Vector&#x65F6;&#xFF0C;&#x7ED9;&#x5B9A;&#x521D;&#x59CB;&#x5BB9;&#x91CF;
&#x200B;
5.&#x7EBF;&#x7A0B;&#x5B89;&#x5168;&#xFF0C;&#x9002;&#x5408;&#x5728;&#x591A;&#x7EBF;&#x7A0B;&#x8BBF;&#x95EE;&#x65F6;&#x4F7F;&#x7528;&#xFF0C;&#x5728;&#x5355;&#x7EBF;&#x7A0B;&#x4E0B;&#x4F7F;&#x7528;&#x6548;&#x7387;&#x8F83;&#x4F4E;&#xFF0C;&#x56E0;&#x4E3A;&#x5185;&#x90E8;&#x65B9;&#x6CD5;&#x52A0;&#x4E86;synchronized&#x540C;&#x6B65;&#x9501;
&#x200B;
*/
&#x200B;
Vector<string> &#xA0;vector = new Vector<>();
 &#xA0; &#xA0;vector .add("&#x5C0F;&#x7C73;");
 &#xA0; &#xA0;vector .add("&#x8C03;&#x5EA6;");
 &#xA0; &#xA0;vector .add("&#x72D7;&#x86CB;");
 &#xA0; &#xA0;vector .add("&#x4E8C;&#x6BDB;");
 &#xA0; &#xA0;vector .add("&#x65FA;&#x8D22;");
for(int i = 0;i<v.size();i++){ ​ system.out.println(v.get(i)) }   public static void main(string[] args){  vector(); }< code></v.size();i++){></string>

面试题:Vector与ArrayLIst的区别?

2.4 LinkedList

public class LinkedList extends AbstractSequentialList implements List ,Deque ,Cloneable,Serializable

List接口的链接列表实现。实现所有可选的列表操作,并且允许所有元素(包括 null)。除了实现 List接口外, LinkedList类还为在列表的开头及结尾 getremoveinsert元素提供了统一的命名方法。

/**
 &#xA0;LinkedList
 &#xA0; &#xA0; &#xA0;1.&#x5B9E;&#x73B0;&#x539F;&#x7406;&#xFF0C;&#x91C7;&#x7528;&#x53CC;&#x5411;&#x94FE;&#x8868;&#x7ED3;&#x6784;&#x5B9E;&#x73B0;
 &#xA0; &#xA0; &#xA0;2.&#x9002;&#x5408;&#x63D2;&#x5165;&#xFF0C;&#x5220;&#x9664;&#x64CD;&#x4F5C;&#xFF0C;&#x6027;&#x80FD;&#x9AD8;

*/
private static void linkedList(){
&#x200B;
LinkedList<string> &#xA0;list = new LinkedList<>();
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x5C0F;&#x7C73;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x8C03;&#x5EA6;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x72D7;&#x86CB;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x4E8C;&#x6BDB;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add("&#x65FA;&#x8D22;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;//&#x904D;&#x5386;&#x96C6;&#x5408;
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;int size = list.size();
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;for(int i = 0;i<size ;i++){    system.out.println(list.get(i)); } }< code></size></string>

3集合框架Set接口

3.1 set接口

public interface Set extends Collection

一个不包含重复元素的 collection。更确切地讲,set 不包含满足 e1.equals(e2)的元素对 e1e2,并且最多包含一个 null 元素。正如其名称所暗示的,此接口模仿了数学上的 _set_抽象。

3.2HashSet
  • public class **HashSet<e>**extends AbstractSet<e>implements Set<e>, Cloneable, Serializable</e></e></e>

此类实现 Set接口,由哈希表(实际上是一个 HashMap实例)支持。它不保证 set 的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用 null元素。

/**
&#x200B;
Set&#x63A5;&#x53E3;
1.&#x65E0;&#x5E8F;&#x7684;&#xFF08;&#x4E0D;&#x4FDD;&#x8BC1;&#x987A;&#x5E8F;&#xFF09;
2.&#x4E0D;&#x5141;&#x8BB8;&#x91CD;&#x590D;&#x5143;&#x7D20;
&#x5B9E;&#x73B0;&#x7C7B;&#xFF1A;HashSet,TreeSet,LinkedHashSet&#xFF0C;&#x4E09;&#x8005;&#x5E95;&#x5C42;&#x5B9E;&#x73B0;&#x4E0E;Map&#x5173;&#x8054;
&#x200B;
&#x9009;&#x62E9;&#x4F7F;&#x7528;
&#x5982;&#x679C;&#x8981;&#x6392;&#x5E8F;&#xFF0C;&#x9009;&#x62E9;treeSet
&#x5982;&#x679C;&#x4E0D;&#x8981;&#x6392;&#x5E8F;&#xFF0C;&#x4E5F;&#x4E0D;&#x7528;&#x4FDD;&#x8BC1;&#x987A;&#x5E8F;&#x9009;&#x62E9;HashSet
&#x4E0D;&#x8981;&#x6392;&#x5E8F;&#xFF0C;&#x8981;&#x4FDD;&#x8BC1;&#x987A;&#x5E8F;&#xFF0C;&#x9009;&#x62E9;LinkedHashSet
&#x200B;
*/
&#x200B;
public class SetDemo{
&#x200B;
public static void main(Sting[] args){
&#x200B;
/**
HashSet
1.&#x5B9E;&#x73B0;&#x539F;&#x7406;&#xFF0C;&#x57FA;&#x4E8E;&#x54C8;&#x5E0C;&#x8868;&#xFF08;HashMap&#xFF09;&#x5B9E;&#x73B0;
2.&#x4E0D;&#x5141;&#x8BB8;&#x91CD;&#x590D;&#xFF0C;&#x53EF;&#x4EE5;&#x6709;&#x4E00;&#x4E2A;NULL&#x5143;&#x7D20;
3.&#x4E0D;&#x4FDD;&#x8BC1;&#x987A;&#x5E8F;&#x6052;&#x4E45;&#x4E0D;&#x53D8;&#xFF08;&#x4F8B;&#xFF1A;&#x6DFB;&#x52A0;&#x5143;&#x7D20;&#x540E;&#xFF0C;&#x8F93;&#x51FA;&#x987A;&#x5E8F;&#x4F1A;&#x53D8;&#xFF09;
4.&#x6DFB;&#x52A0;&#x5143;&#x7D20;&#x65F6;&#x628A;&#x5143;&#x7D20;&#x4F5C;&#x4E3A;HashMap&#x7684;key&#x5B58;&#x50A8;&#xFF0C;HashMap&#x7684;value&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x56FA;&#x5B9A;&#x7684;Object&#x5BF9;&#x8C61;
5.&#x6392;&#x9664;&#x91CD;&#x590D;&#x5143;&#x7D20;&#x662F;&#x901A;&#x8FC7;equals&#x6765;&#x68C0;&#x67E5;&#x5BF9;&#x8C61;&#x662F;&#x5426;&#x76F8;&#x540C;
6.&#x5224;&#x65AD;&#x4E24;&#x4E2A;&#x5BF9;&#x8C61;&#x662F;&#x5426;&#x76F8;&#x540C;&#xFF0C;&#x5148;&#x5224;&#x65AD;&#x4E24;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;hashCode&#x662F;&#x5426;&#x76F8;&#x540C;&#xFF0C;&#xFF08;&#x5982;&#x679C;&#x4E24;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;hashCode&#x76F8;&#x540C;&#xFF0C;&#x4E0D;&#x4E00;&#x5B9A;&#x662F;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x540C;&#xFF0C;&#x90A3;&#x4E00;&#x5B9A;&#x4E0D;&#x662F;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF1B;&#x6574;&#x6570;&#x8303;&#x56F4;&#x5C31;&#x8FD9;&#x4E48;&#x5927;&#xFF0C;&#x6709;&#x53EF;&#x80FD;&#x91CD;&#x590D;&#xFF09;&#xFF0C;&#x5982;&#x679C;&#x4E0D;&#x540C;&#xFF0C;&#x5219;&#x4E24;&#x4E2A;&#x5BF9;&#x8C61;&#x4E0D;&#x662F;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF0C;&#x5982;&#x679C;&#x76F8;&#x540C;&#xFF0C;&#x8FD8;&#x8981;&#x8FDB;&#x884C;equals&#x5224;&#x65AD;&#xFF0C;equals&#x76F8;&#x540C;&#x5219;&#x662F;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF0C;&#x4E0D;&#x540C;&#x5219;&#x4E0D;&#x662F;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#x3002;
7.&#x81EA;&#x5B9A;&#x4E49;&#x5BF9;&#x8C61;&#x8981;&#x8BA4;&#x4E3A;&#x5C5E;&#x6027;&#x503C;&#x90FD;&#x76F8;&#x540C;&#x65F6;&#x4E3A;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF0C;&#x6709;&#x8FD9;&#x79CD;&#x9700;&#x6C42;&#x65F6;&#xFF0C;&#x90A3;&#x4E48;&#x6211;&#x4EEC;&#x8981;&#x91CD;&#x5199;&#x5BF9;&#x8C61;&#x6240;&#x5728;&#x5B9E;&#x4F53;&#x7C7B;&#x7684;hashCode&#x548C;equals&#x65B9;&#x6CD5;
&#x200B;
&#x5C0F;&#x7ED3;
&#xFF08;1&#xFF09;&#x54C8;&#x5E0C;&#x8868;&#x7684;&#x5B58;&#x50A8;&#x7ED3;&#x6784;&#xFF1A;&#x6570;&#x7EC4;+&#x94FE;&#x8868;&#xFF0C;&#x6570;&#x7EC4;&#x91CC;&#x7684;&#x6BCF;&#x4E2A;&#x5143;&#x7D20;&#x4EE5;&#x94FE;&#x8868;&#x7684;&#x5F62;&#x5F0F;&#x5B58;&#x50A8;
&#xFF08;2&#xFF09;&#x5982;&#x4F55;&#x628A;&#x5BF9;&#x8C61;&#x5B58;&#x50A8;&#x5230;&#x54C8;&#x5E0C;&#x8868;&#x4E2D;&#xFF0C;&#x5148;&#x8BA1;&#x7B97;&#x5BF9;&#x8C61;&#x7684;hashCode&#x503C;&#xFF0C;&#x518D;&#x5BF9;&#x6570;&#x7EC4;&#x7684;&#x957F;&#x5EA6;&#x6C42;&#x4F59;&#x6570;&#xFF0C;&#x6765;&#x51B3;&#x5B9A;&#x5BF9;&#x8C61;&#x8981;&#x5B58;&#x50A8;&#x5728;&#x6570;&#x7EC4;&#x4E2D;&#x7684;&#x54EA;&#x4E2A;&#x4F4D;&#x7F6E;&#xFF08;&#x4E0D;&#x540C;&#x7684;&#x503C;&#x653E;&#x5230;&#x6570;&#x7EC4;&#x91CC;&#xFF0C;&#x76F8;&#x540C;&#x7684;&#x503C;&#x6309;&#x5148;&#x540E;&#x987A;&#x5E8F;&#x4F5C;&#x4E3A;&#x94FE;&#x8868;&#x653E;&#x5728;&#x4E00;&#x683C;&#x6570;&#x7EC4;&#x91CC;&#xFF0C;&#x5148;&#x653E;&#x8FDB;&#x53BB;&#x7684;&#x5C31;&#x662F;&#x6839;&#xFF0C;&#x540E;&#x8FDB;&#x53BB;&#x7684;&#x4F5C;&#x4E3A;&#x6839;&#x7684;next&#xFF09;
&#xFF08;3&#xFF09;&#x89E3;&#x51B3;hashSet&#x4E2D;&#x7684;&#x91CD;&#x590D;&#x503C;&#x4F7F;&#x7528;&#x7684;&#x65B9;&#x5F0F;&#x662F;&#xFF1A;&#x53C2;&#x8003;&#x7B2C;&#x516D;&#x70B9;
*/
&#x200B;
private static void hashSet(){
Set<string> set = new HashSet<>();
set.add("&#x5F20;&#x98DE;");
set.add("&#x5173;&#x7FBD;");
set.add("&#x5218;&#x5907;");
set.add("&#x8BF8;&#x845B;&#x4EAE;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;set.add("&#x66F9;&#x64CD;");
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;set.add("&#x8BF8;&#x845B;&#x4EAE;");//&#x628A;&#x4E0A;&#x9762;&#x7684;"&#x8BF8;&#x845B;&#x4EAE;"&#x66FF;&#x6362;&#x6389;,&#x6DFB;&#x52A0;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x4E0D;&#x540C;&#x5BF9;&#x8C61;&#xFF0C;&#x4E14;&#x76F8;&#x540C;&#x503C;&#x7684;&#x5BF9;&#x8C61;&#x65F6;&#x4E0D;&#x4F1A;&#x88AB;&#x66FF;&#x6362;
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;String[] names = set.toArray(new String[]{})
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;for(String s : names){
 &#xA0; &#xA0; &#xA0; &#xA0;   &#xA0;System.out.println(s);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;  }
&#x200B;
&#x200B;
}
&#x200B;
}
&#x200B;
}
&#x200B;
&#x200B;</string>
hashCode深入分析

hashCode()方法,在Object类中定义如下:

public native int hashCode();//native本地方法

hashCode是本地方法,它的实现是根据本地机器相关,当然我们可以在自己写的类中覆盖hashCode()方法,比如 String ,Integer,Double……等等这些类都是覆盖了hashCode()方法的。

  • 判断两个对象是否相同:先判断两个对象的hashCode是否相同,([重写hashCode(),根据值来计算hashCode,值相等判定为同一对象,]如果两个对象的hashCode相同,不一定是同一个对象,如果不同,那一定不是同一个对象;整数范围就这么大,有可能重复),如果不同,则两个对象不是同一个对象,如果相同,还要进行equals判断,equals相同则是同一个对象,不同则不是同一个对象。
  • 如何把对象存储到哈希表中:先计算对象的hashCode值,再对数组的长度求余数,来决定对象要存储在数组中的哪个位置(不同的值放到数组里,相同的值按先后顺序作为链表放在一格数组里,先放进去的就是根,后进去的作为根的next)
3.3 TreeSet(排序)
  • public class **TreeSet<e>**extends AbstractSet<e>implements NavigableSet<e>, Cloneable, Serializable</e></e></e>

基于 TreeMap的 NavigableSet实现。使用元素的自然顺序对元素进行 排序,或者根据创建 set 时提供的 Comparator 进行排序,具体取决于使用的构造方法。

/**
&#x6709;&#x5E8F;&#x7684;&#xFF0C;&#x57FA;&#x4E8E;TreeMap&#xFF08;&#x4E8C;&#x53C9;&#x6811;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF09;&#xFF0C;&#x5BF9;&#x8C61;&#x9700;&#x8981;&#x6BD4;&#x8F83;&#x5927;&#x5C0F;&#xFF0C;&#x901A;&#x8FC7;&#x5BF9;&#x8C61;&#x6BD4;&#x8F83;&#x5668;&#x6765;&#x5B9E;&#x73B0;&#xFF0C;
&#x5BF9;&#x8C61;&#x6BD4;&#x8F83;&#x5668;&#x8FD8;&#x53EF;&#x4EE5;&#x7528;&#x6765;&#x53BB;&#x9664;&#x91CD;&#x590D;&#x5143;&#x7D20;&#xFF0C;
&#x5982;&#x679C;&#x81EA;&#x5B9A;&#x4E49;&#x7684;&#x6570;&#x636E;&#x7C7B;&#xFF0C;&#x6CA1;&#x6709;&#x5B9E;&#x73B0;&#x6BD4;&#x8F83;&#x5668;&#x63A5;&#x53E3;&#xFF0C;&#x5C06;&#x65E0;&#x6CD5;&#x6DFB;&#x52A0;&#x5230;TreeSet&#x96C6;&#x5408;&#x4E2D;&#x3002;
&#x200B;
*/
&#x200B;
private static void treeSet(){
TreeSet<string> tree = new TreeSet<>(new CatComparetor());
 &#xA0; &#xA0;Cat c1 = new Cat("wanwan",2,1) //&#x53C2;&#x6570;&#xFF1A;&#x540D;&#x5B57;&#xFF0C;&#x5E74;&#x9F84;&#xFF0C;&#x7F16;&#x53F7;
 &#xA0; &#xA0;Cat c2 = new Cat("guanguan",3,2)
 &#xA0; &#xA0;Cat c3 = new Cat("wanwan",2,3)
 &#xA0; &#xA0;Cat c4 = new Cat("wanwan",2,1)
 &#xA0; &#xA0;tree.add(c1);
 &#xA0; &#xA0;tree.add(c2);
 &#xA0; &#xA0;tree.add(c3);
 &#xA0; &#xA0;tree.add(c4);
 &#xA0; &#xA0;System.out.println(tree.size() );//&#x5982;&#x679C;&#x521B;&#x5EFA;TreeSet&#x5B9E;&#x4F8B;&#x65F6;&#x6CA1;&#x6709;&#x4F20;&#x5165;new CatComparetor()&#x6BD4;&#x8F83;&#x5668;&#x7684;&#x8BDD;&#xFF0C;&#x5BF9;&#x8C61;&#x95F4;&#x65E0;&#x6CD5;&#x6BD4;&#x8F83;&#x6392;&#x5E8F;&#xFF0C;&#x62A5;&#x7C7B;&#x578B;&#x8F6C;&#x6362;&#x5F02;&#x5E38;&#x9519;&#x8BEF;

 &#xA0; &#xA0;for(Cat c : tree){
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(c);
 &#xA0;  }
 &#xA0; &#xA0;
}
&#x200B;
public class CatComparetor implements Comparator<cat>{
 &#xA0; &#xA0;public int compare(Cat o1,Cat o2){
 &#xA0; &#xA0; &#xA0; // return o1.getAge()-o2.getAge()//&#x6839;&#x636E;&#x5E74;&#x9F84;&#x6765;&#x6BD4;&#x8F83;,&#x76F8;&#x540C;&#x5E74;&#x9F84;&#x4F1A;&#x88AB;&#x5224;&#x5B9A;&#x4E3A;&#x540C;&#x4E00;&#x5BF9;&#x8C61;&#xFF0C;&#x5B58;&#x4E0D;&#x8FDB;&#x53BB;
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0;  }
}</cat></string>
3.4LinkedHashSet(顺序)
  • public class **LinkedHashSet<e>**extends HashSet<e>implements Set<e>, Cloneable, Serializable</e></e></e>

具有可预知迭代顺序的 Set接口的哈希表和链接列表实现。此实现与 HashSet的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序( 插入顺序)进行迭代。注意,插入顺序 _不_受在 set 中 _重新插入的_元素的影响。(如果在 s.contains(e)返回 true后立即调用 s.add(e),则元素 e会被重新插入到 set s中。)

/** &#xA0;
&#x54C8;&#x5E0C;&#x8868;&#x548C;&#x94FE;&#x63A5;&#x5217;&#x8868;&#x5B9E;&#x73B0;
&#x7EF4;&#x62A4;&#x7740;&#x4E00;&#x4E2A;&#x8FD0;&#x884C;&#x4E8E;&#x6240;&#x6709;&#x6761;&#x76EE;&#x7684;&#x53CC;&#x91CD;&#x94FE;&#x63A5;&#x5217;&#x8868;&#x3002;&#x6B64;&#x94FE;&#x63A5;&#x5217;&#x8868;&#x5B9A;&#x4E49;&#x4E86;&#x8FED;&#x4EE3;&#x987A;&#x5E8F;&#xFF0C;&#x5373;&#x6309;&#x7167;&#x5C06;&#x5143;&#x7D20;&#x63D2;&#x5165;&#x5230; set  &#x4E2D;&#x7684;&#x987A;&#x5E8F;&#xFF08;*&#x63D2;&#x5165;&#x987A;&#x5E8F;*&#xFF09;&#x8FDB;&#x884C;&#x8FED;&#x4EE3;
*/
private static void linkedHashSet(){
LinkedHashSet<string> set = new LinkedHashSet<>();//&#x94FE;&#x8868;&#x6765;&#x8BB0;&#x5F55;&#x4F4D;&#x7F6E;
Cat c1 = new Cat("wanwan",2,1) //&#x53C2;&#x6570;&#xFF1A;&#x540D;&#x5B57;&#xFF0C;&#x5E74;&#x9F84;&#xFF0C;&#x7F16;&#x53F7;
 &#xA0; &#xA0;Cat c2 = new Cat("guanguan",3,2)
 &#xA0; &#xA0;Cat c3 = new Cat("wanwan",2,3)
 &#xA0; &#xA0;Cat c4 = new Cat("wanwan",2,1)
 &#xA0; &#xA0;set.add(c1);
 &#xA0; &#xA0;set.add(c2);
 &#xA0; &#xA0;set.add(c3);
 &#xA0; &#xA0;set.add(c4);
 &#xA0; &#xA0;
 &#xA0; &#xA0;for(Cat c : set){
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(c);
 &#xA0;  }
&#x200B;
}</string>

4.集合框架Iterator接口

4.1 集合输出

前面我们已经学习了集合的基本操作,很多情况下,我们需要把集合的内容进行输出,也就是遍历集合

遍历集合的方式有一下几种:

  1. Iterator
  2. ListIterator(一般用得很少)
  3. Enumeration(枚举迭代接口)
  4. foreach(最方便,用得也多)

其中Iterator的使用率最高,在JDK1.5后新增了foreach,也被大量使用。有了Iterator迭代器,不同的集合也可以用相同的方式来迭代,而内部隐藏了不同的具体实现

4.2 Iterator
  • public interface **Iterator<e>**</e>

对 collection 进行迭代的迭代器。迭代器取代了 Java Collections Framework 中的 Enumeration。
类型说明 boolean[hasNext() &#x5982;&#x679C;&#x4ECD;&#x6709;&#x5143;&#x7D20;&#x53EF;&#x4EE5;&#x8FED;&#x4EE3;&#xFF0C;&#x5219;&#x8FD4;&#x56DE;true。 Enext() 返回迭代的下一个元素。 voidremove() 从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。

4.3 ListIterator
  • public interface **ListIterator<e>**extends Iterator<e></e></e>

系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。
类型说明 void[add(E e) 将指定的元素插入列表(可选操作)。 booleanhasPrevious() &#x5982;&#x679C;&#x4EE5;&#x9006;&#x5411;&#x904D;&#x5386;&#x5217;&#x8868;&#xFF0C;&#x5217;&#x8868;&#x8FED;&#x4EE3;&#x5668;&#x6709;&#x591A;&#x4E2A;&#x5143;&#x7D20;&#xFF0C;&#x5219;&#x8FD4;&#x56DE;true。 intnextIndex() &#x8FD4;&#x56DE;&#x5BF9;next 的后续调用所返回元素的索引。 Eprevious() 返回列表中的前一个元素。 intpreviousIndex() &#x8FD4;&#x56DE;&#x5BF9;previous的后续调用所返回元素的索引。voidset(E e)用指定元素替换nextprevious 返回的最后一个元素(可选操作)。

4.4 Enumeration
  • public interface **Enumeration<e>**</e>

实现 Enumeration 接口的对象,它生成一系列元素,一次生成一个。连续调用 nextElement方法将返回一系列的连续元素。

注:此接口的功能与 Iterator 接口的功能是重复的。此外,Iterator 接口添加了一个可选的移除操作,并使用较短的方法名。新的实现应该优先考虑使用 Iterator 接口而不是 Enumeration 接口。
类型说明 booleanhasMoreElements() 测试此枚举是否包含更多的元素。 EnextElement() 如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素。

/**
&#x200B;
&#x200B;&#x96C6;&#x5408;&#x8F93;&#x51FA;&#xFF0C;&#x8FED;&#x4EE3;
&#x200B;
*/
public class IteratorDemo{
//foreach,JDK1.5&#x540E;&#x624D;&#x6709;
private static void foreach(Collection<cat>){
for(Cat cat :c ){
System.out.println(cat);
}

}

//iterator&#xFF0C;JDK1.5&#x4E4B;&#x524D;&#x7EDF;&#x4E00;&#x7684;&#x8FED;&#x4EE3;&#x96C6;&#x5408;&#x65B9;&#x5F0F;
private static void iterator(Collection<cat>){
Iterator<cat> iter = c.iterator();//iterator()&#x4EE5;&#x6B63;&#x786E;&#x7684;&#x987A;&#x5E8F;&#x8FD4;&#x56DE;&#x8BE5;&#x5217;&#x8868;&#x4E2D;&#x7684;&#x5143;&#x7D20;&#x7684;&#x8FED;&#x4EE3;&#x5668;
while(iter.hasNext()){
System.out.println(iter.next());
}
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; //Enumeration,&#x5E38;&#x642D;&#x914D;Vector&#x4F7F;&#x7528;
 &#xA0; &#xA0;private static void enumeration(Collection<cat>){
 &#xA0; Vector<stirng> vs = new Vector<>();
 &#xA0; &#xA0; &#xA0; &#xA0;vs.add("tom");
 &#xA0; &#xA0; &#xA0; &#xA0;vs.add("job");
 &#xA0; &#xA0; &#xA0; &#xA0;vs.add("jack");
 &#xA0; &#xA0; &#xA0; &#xA0;vs.add("lily");
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;Enumeration<string> es = vs.elements();
while(es.hasMoreElements()){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(es.nextElement());
 &#xA0; &#xA0; &#xA0;  }

 &#xA0; &#xA0; &#xA0; // ListIterator&#x63D0;&#x4F9B;&#x5411;&#x4E0A;&#x904D;&#x5386;&#x7684;&#x65B9;&#x6CD5;previous()
}
&#x200B;
public static void main(String[] args){
List<cat> list = new ArrayList<>();
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;Cat c1 = new Cat("wanwan",2,1) //&#x53C2;&#x6570;&#xFF1A;&#x540D;&#x5B57;&#xFF0C;&#x5E74;&#x9F84;&#xFF0C;&#x7F16;&#x53F7;
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;Cat c2 = new Cat("guanguan",3,2)
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;Cat c3 = new Cat("wanwan",2,3)
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;Cat c4 = new Cat("wanwan",2,1)
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add(c1);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add(c2);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add(c3);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;list.add(c4);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;foreach(list);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;iterator(list);//&#x8F93;&#x51FA;&#x904D;&#x5386;
 &#xA0; &#xA0; &#xA0;  enumeration();
}
}</cat></string></stirng></cat></cat></cat></cat>
4.5 foreach

在前面中,我们使用foreach来输出数组的内容,那么也可以输出集合中的内容。在使用foreach输出时候要注意:创建集合时要指定操作泛型的类型。

List numbers = new ArrayList<>();

JDK1.8新特性:(lambda表达式)

forEach(Consumer<? super String> &#xA0;action)//&#x53C2;&#x6570;+&#x64CD;&#x4F5C;,&#x64CD;&#x4F5C;&#x7ED3;&#x5408;lambda&#x8868;&#x8FBE;&#x5F0F;

//no.1

numbers.forEach((Integer integer) – > {System.out.prinlnt(integer);});

//no.2

numbers.forEach( integer – > {System.out.prinlnt(integer);});

//no.3

numbers.forEach( integer – > System.out.prinlnt(integer));

//no.4

numbers.forEach(System.out :: prinlnt );

//no.5

numbers.forEach(new MyConsumer());

/**
JDK1.8&#x65B0;&#x65B9;&#x6CD5;z
&#x200B;
*/
public
    public static void foreach(){
    List<string> list = new ArrayList<>();
    list.add("ss");
 &#xA0; &#xA0;list.add("jg");
    list.add("er");
    list.add("vb");
&#x200B;
    //Consumer,&#x4E00;&#x4E2A;&#x4E00;&#x4E2A;
        list.forEach(s->System.out.println(s););
        list.forEach(System.out::println);//::&#x8868;&#x793A;&#x8C03;&#x7528;&#xFF0C;System.out&#x9759;&#x6001;&#x5C5E;&#x6027;&#x8C03;&#x7528;&#x65B9;&#x6CD5;println
    }
&#x200B;
    //foreach(Consumer<? super String>,action);Consumer<? super String>&#x662F;String&#x7684;&#x5B50;&#x7C7B;   </string>

5.JDK1.8新特性

Comsumer 接口 消费者接口, foreach()有用到

Function 表示接收一个参数并产生结果的函数,T代表类型,R代表返回值

Supplier 接口 代表结果供应商,返回一个结果

Predicate 接口 断言接口,用于测试

//&#x8868;&#x793A;&#x63A5;&#x6536;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x5E76;&#x8FD4;&#x56DE;&#x7ED3;&#x679C;&#x7684;&#x51FD;&#x6570;
private static void functionTest(){
    String s = strToUpp("dfdfds",(str)->{str.toUpperCase();})//str&#x662F;Function&#x7B2C;&#x4E00;&#x4E2A;&#x4F20;&#x8FDB;&#x53BB;&#x7684;&#x53C2;&#x6570;&#xFF08;&#x503C;&#x662F;"dfdfds"&#xFF09;&#xFF0C;str.toUpperCase()&#x662F;&#x91CD;&#x5199;&#x4E86;Function&#x7684;apply()&#x3002;
 &#xA0; &#xA0;System.out.println(s);
}
&#x200B;
public static String strToUpp(String str,Function<string,string> f){
 &#xA0; &#xA0;//Function<string,string>,&#x7B2C;&#x4E00;&#x4E2A;String&#x662F;&#x4F20;&#x8FDB;&#x53BB;&#x53C2;&#x6570;&#x7684;&#x7C7B;&#x578B;&#xFF0C;&#x89C4;&#x5B9A;&#x4E86;strToUpp()&#x7684;&#x7B2C;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x7C7B;&#x578B;&#xFF0C;&#x7B2C;&#x4E8C;&#x4E2A;String&#x662F;&#x8FD4;&#x56DE;&#x503C;&#x7684;&#x7C7B;&#x578B;&#x3002;
 &#xA0; &#xA0;//&#x5728;Function&#x91CC;apply&#x662F;&#x62BD;&#x8C61;&#x65B9;&#x6CD5;&#xFF1B;&#x88AB;&#x8C03;&#x7528;&#x65F6;&#x7528;lambda&#x91CD;&#x5199;
 &#xA0; &#xA0;return f.apply(str);
}
//-----------------------------------------------------------------------
//Supplier&#x4EE3;&#x8868;&#x7ED3;&#x679C;&#x4F9B;&#x5E94;&#x5546;&#xFF0C;&#x8981;&#x4EC0;&#x4E48;&#x7ED9;&#x4EC0;&#x4E48;&#x3002;&#xFF08;&#x81EA;&#x5DF1;&#x63D0;&#x524D;&#x7ED9;&#xFF09;
private static void supplierTest(){
 &#xA0; &#xA0; List<integer> list = getNums(10,()->{(int)(Math.random()*100);});
 &#xA0; &#xA0;list.forEach(System.out::println);
 &#xA0; &#xA0;
}
private static List<integer> getNums(int num,Supplier<integer> sup){
 &#xA0; &#xA0;List<integer> list = new ArrayList<>();
 &#xA0; &#xA0;for(int i = 0;i<num;i++){    list.add(sup.get()); 把结果装进list }  return list; ​ --------------------------------------- 断言接口,作测试 private static void predicatetest(){ list<string> list = ArrayList.asList("tom","carry","curly","larry");
 &#xA0;      List<sting> result = filter(list,(s)->s.contains("o"));
        return forEach(System.out::println);
}
private static List<sring> filter(List<string> list,Predicate<string> p ){
 &#xA0; &#xA0;List<string> results = new AraryList<>();
 &#xA0; &#xA0;for(String s : list){
 &#xA0; &#xA0; &#xA0; &#xA0;if(p.test(s){//&#x6D4B;&#x8BD5;&#x662F;&#x5426;&#x7B26;&#x5408;&#x8981;&#x6C42;
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;results.add(s);
 &#xA0; &#xA0; &#xA0;  }
 &#xA0;  }
 &#xA0; &#xA0;
}
&#x200B;</string></string></string></sring></sting></num;i++){></integer></integer></integer></integer></string,string></string,string>
5.1JDK1.8新特性之Stream

什么是Stream?

Stream是元素的集合,这点让Stream看起来有些类似Iterator

可以支持顺序和并行的对原Stream进行汇聚的操作;

我们可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如”过滤掉长度大于10的字符串”,”获取每个字符串的首字母”等,具体这些操作如何应用到每个元素上,就给Stream就好了!(stream流)

Stream接口提供了强大的集合处理功能,相比较于Iterator迭代器一个一个的处理元素,要好用太多了。

JDK1.8可以在接口添加类方法,成员方法,静态方法

/**
Stream&#x63A5;&#x53E3;&#xFF1A;&#x4E0D;&#x662F;&#x5B58;&#x50A8;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF0C;&#x6570;&#x636E;&#x6E90;&#x53EF;&#x4EE5;&#x662F;&#x4E00;&#x4E2A;&#x96C6;&#x5408;&#xFF0C;&#x4E3A;&#x4E86;&#x51FD;&#x6570;&#x5F0F;&#x7F16;&#x7A0B;&#x521B;&#x9020;&#xFF0C;
&#x60F0;&#x5F0F;&#x6267;&#x884C;&#xFF08;&#x7528;&#x5230;&#x6570;&#x636E;&#x624D;&#x6267;&#x884C;&#xFF09;&#xFF0C;&#x6570;&#x636E;&#x53EA;&#x80FD;&#x88AB;&#x6D88;&#x8D39;&#x4E00;&#x6B21;&#xFF08;&#x4ECE;&#x96C6;&#x5408;&#x4E2D;&#x5173;&#x8054;&#x6570;&#x636E;&#xFF0C;&#x4F7F;&#x7528;&#x4E00;&#x6B21;&#x6570;&#x636E;&#x5C31;&#x6CA1;&#x4E86;&#xFF09;
&#x200B;
&#x4E24;&#x79CD;&#x7C7B;&#x578B;&#x7684;&#x64CD;&#x4F5C;&#x65B9;&#x6CD5;&#xFF1A;
1.&#x4E2D;&#x95F4;&#x64CD;&#x4F5C;&#xFF08;&#x751F;&#x6210;&#x4E00;&#x4E2A;Stream&#xFF09;
2.&#x7ED3;&#x675F;&#x64CD;&#x4F5C;&#xFF08;&#x6267;&#x884C;&#x8BA1;&#x7B97;&#x64CD;&#x4F5C;&#xFF09;
*/
&#x200B;
public class StreamDemo{
 &#xA0; &#xA0;public Static void main(String[] args){
 &#xA0; &#xA0; &#xA0; &#xA0;//foreach&#x65B9;&#x6CD5;,Collection&#x63A5;&#x53E3;&#x6709;stream&#xFF08;&#xFF09;&#xFF0C;
 &#xA0; &#xA0; &#xA0; Streams<string> stream = &#xA0;Stream.of("well","done","yep","yep","study")//&#x751F;&#x6210;&#x4E00;&#x4E2A;Stream
 &#xA0; &#xA0; &#xA0; &#xA0;//forEach&#x5C5E;&#x4E8E;&#x7ED3;&#x675F;&#x64CD;&#x4F5C;
 &#xA0; &#xA0; &#xA0; &#xA0;stream.forEach((str)->{System.out.println(str);})
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//filter&#x8FC7;&#x6EE4;,&#x5C5E;&#x4E8E;&#x4E2D;&#x95F4;&#x64CD;&#x4F5C;,&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x6D41;
 &#xA0; &#xA0; &#xA0; &#xA0;stream.filter((s)->s.length()>3).forEach(System.out::println);
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//distinct&#x53BB;&#x91CD;&#x590D;
 &#xA0; &#xA0; &#xA0; &#xA0;stream.distinct().forEach(s->System.out.println(s));
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;//map&#x6620;&#x5C04;,&#x5C5E;&#x4E8E;&#x4E2D;&#x95F4;&#x64CD;&#x4F5C;,&#x8FD4;&#x56DE;&#x4E00;&#x4E2A;&#x6D41;
 &#xA0; &#xA0; &#xA0; &#xA0;stream.map(s->s.toUpperCase()).forEach(System.out::println);
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;//flatMap&#x5E73;&#x644A;&#xFF0C;&#x7EC4;&#x5408;&#x591A;&#x4E2A;&#x4E0D;&#x540C;&#x96C6;&#x5408;&#x7684;&#x6570;&#x636E;&#x6E90;
 &#xA0; &#xA0; &#xA0; &#xA0;Stream<list<integer>> ss = Stream.of(Arrays.asList(1,2),Arrays.asList(3,4,5))
 &#xA0; &#xA0; &#xA0; &#xA0;ss.flatMap(list->list.stream()).forEach(System.out::println);
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;//reduce&#xFF0C;&#x6C42;&#x805A;&#x5408;&#x7684;&#x64CD;&#x4F5C;&#x90FD;&#x7528;&#x5B83;
 &#xA0; &#xA0; &#xA0; &#xA0;Optional<stream> &#xA0;opt = stream.reduce((s1,s2)->s1.length()>=s2.length()?s1:s2);//&#x6BD4;&#x8F83;&#x51FA;&#x6700;&#x957F;&#x7684;&#x5143;&#x7D20;
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(opt.get());//&#x8F93;&#x51FA;&#xFF1A;study
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//collect,&#x914D;&#x5408;Collectors&#x5DE5;&#x5177;&#x7C7B;&#x751F;&#x6210;&#x4E0D;&#x540C;&#x7684;&#x96C6;&#x5408;
 &#xA0; &#xA0; &#xA0; &#xA0;//Collectors&#x91CC;&#x6709;toList(),toMap,toSet()...&#x65B9;&#x6CD5;
 &#xA0; &#xA0; &#xA0; List<string> list = &#xA0;stream.collect(Collectors.toList());
 &#xA0; &#xA0; &#xA0; &#xA0;list.forEach(s->System.out.println(s));
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//:: &#x2192;&#x65B9;&#x6CD5;&#x7684;&#x5F15;&#x7528;
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x5F15;&#x7528;&#x9759;&#x6001;&#x65B9;&#x6CD5;     Integer::valueOf
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x5F15;&#x7528;&#x5BF9;&#x8C61;&#x7684;&#x65B9;&#x6CD5;   list::add,&#x4E0D;&#x7528;&#x52A0;&#x53C2;&#x6570;&#xFF0C;&#x4F1A;&#x4ECE;lambda&#x8868;&#x8FBE;&#x5F0F;&#x91CC;&#x63A8;&#x65AD;
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x5F15;&#x7528;&#x6784;&#x9020;&#x65B9;&#x6CD5;     ArrayList::new     &#x9ED8;&#x8BA4;&#x6784;&#x9020;&#x65B9;&#x6CD5;
 &#xA0;  }
}</string></stream></list<integer></string>

stream.map()图解:

java基础-集合

stream.flatMap()图解:

6.集合框架Map接口

6.1 Map接口(映射接口)

*

public interface Map<k,v></k,v>

映射键到值的对象。一张Map不能包含重复的键,每个键可以映射到至多一个值。(一对一关系)

Map接口很常用,尤其在复杂数据存储上优势明显

6.2 HashMap

*

public class HashMap<k,v>
extends AbstractMap<k,v>
implements Map<k,v>, Cloneable, Serializable</k,v></k,v></k,v>

基于哈希表的 Map接口的实现。这种实现提供了所有可选的Map操作,并允许 null值和 null键。(除了它是不同步的,允许使用null之外, HashMap类与 Hashtable大致相同 。)此类不保证映射的顺序,特别是它不保证该顺序恒久不变

/**
Map&#x63A5;&#x53E3;
1.&#x952E;&#x503C;&#x5BF9;&#x5B58;&#x50A8;&#x4E00;&#x7EC4;&#x5BF9;&#x8C61;     &#xFF08;collection&#x662F;&#x5B58;&#x50A8;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF09;
2.Key&#x4E0D;&#x80FD;&#x91CD;&#x590D;&#xFF08;&#x552F;&#x4E00;&#xFF09;&#xFF0C;Value&#x53EF;&#x4EE5;&#x91CD;&#x590D;
3.&#x5177;&#x4F53;&#x5B9E;&#x73B0;&#x7C7B;&#xFF1B;HashMap&#xFF0C;TreeMap Hashtable LinkedHashMap
4.HashMap&#x4E0E;Hashtable&#x7684;&#x533A;&#x522B;&#xFF1F;
5.&#x5982;&#x4F55;&#x9009;&#x62E9;&#x4F7F;&#x7528;&#x54EA;&#x4E2A;&#xFF1F;
&#x6392;&#x5E8F;&#x4E14;&#x8981;&#x4E8C;&#x53C9;&#x6811;&#x5C31;&#x7528;TreeMap&#xFF0C;
&#x591A;&#x7EBF;&#x7A0B;&#x4E0B;&#x7528;Hashtable&#xFF08;&#x7528;&#x7684;&#x5C11;&#xFF09;&#xFF0C;HashMap&#xFF08;&#x4E5F;&#x53EF;&#x4EE5;&#x6784;&#x5EFA;&#x51FA;&#x540C;&#x6B65;&#x7684;&#xFF09;
&#x5355;&#x7EBF;&#x7A0B;&#x4E0B;&#x7528;HashMap
&#x5728;HashMap&#x4E0A;&#x8981;&#x4FDD;&#x8BC1;&#x987A;&#x5E8F;&#xFF0C;&#x5C31;&#x7528;LinkedHashMap
6.&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF1A;&#x6570;&#x7EC4;&#x3001;&#x94FE;&#x8868;&#x3001;&#x4E8C;&#x53C9;&#x6811;&#xFF08;&#x7EA2;&#x9ED1;&#x6811;&#xFF09;&#x3001;&#x54C8;&#x5E0C;&#x8868;&#xFF08;&#x6570;&#x7EC4;+&#x94FE;&#x8868;&#xFF09;&#x3001;&#x6808;&#x3001;&#x961F;&#x5217;
*/
public class MapDemo{

 &#xA0; &#xA0;/**
 &#xA0; &#xA0;HashMap&#x7684;&#x5B9E;&#x73B0;&#x539F;&#x7406;&#xFF1A;
 &#xA0; &#xA0;1.&#x57FA;&#x4E8E;&#x54C8;&#x5E0C;&#x8868;&#xFF08;&#x6570;&#x7EC4;+&#x94FE;&#x8868;+&#x4E8C;&#x53C9;&#x6811;(&#x7EA2;&#x9ED1;&#x6811;&#xFF0C;&#x4FDD;&#x8BC1;&#x6811;&#x5DE6;&#x53F3;&#x4E24;&#x7AEF;&#x5E73;&#x8861;)&#xFF09;[JDK1.8&#x54C8;&#x5E0C;&#x8868;&#x65B0;&#x589E;&#x4E8C;&#x53C9;&#x6811;]
 &#xA0; &#xA0;2.&#x9ED8;&#x8BA4;&#x52A0;&#x8F7D;&#x56E0;&#x5B50;&#x4E3A;0.75 (0.75&#x5C31;&#x662F;&#x6570;&#x7EC4;&#x5B58;&#x5230;&#x4E86;&#x5927;&#x5C0F;&#x4E3A;75%&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x5C31;&#x8BF4;&#x660E;&#x6570;&#x7EC4;&#x5FEB;&#x5B58;&#x6EE1;&#x4E86;&#xFF0C;&#x662F;&#x4E00;&#x4E2A;&#x6807;&#x51C6;&#x7EA2;&#x7EBF;&#xFF0C;&#x8981;&#x91CD;&#x65B0;&#x6563;&#x5217;&#xFF08;&#x91CD;&#x65B0;&#x6563;&#x5217;&#x5C31;&#x662F;&#x91CD;&#x65B0;&#x521B;&#x5EFA;&#x6570;&#x7EC4;&#xFF0C;&#x6216;&#x6269;&#x5145;&#x6570;&#x7EC4;&#xFF09;) ,&#x9ED8;&#x8BA4;&#x6570;&#x7EC4;&#x5927;&#x5C0F;&#x4E3A;16(&#x6570;&#x7EC4;&#x4F4D;&#x7F6E;0-15)
 &#xA0; &#xA0;3.&#x628A;&#x5BF9;&#x8C61;&#x5B58;&#x50A8;&#x5230;&#x54C8;&#x5E0C;&#x8868;&#x4E2D;&#xFF0C;&#x5982;&#x4F55;&#x5B58;&#x50A8;&#xFF1F;
 &#xA0; &#xA0;&#x628A;key&#x5BF9;&#x8C61;&#x901A;&#x8FC7;hash()&#x65B9;&#x6CD5;&#x8BA1;&#x7B97;hash&#x503C;&#xFF0C;&#x7136;&#x540E;&#x7528;&#x8FD9;&#x4E2A;hash&#x503C;&#x5BF9;&#x6570;&#x7EC4;&#x957F;&#x5EA6;&#x53D6;&#x4F59;&#xFF08;&#x9ED8;&#x8BA4;16&#xFF09;&#xFF0C;&#x6765;&#x51B3;&#x5B9A;&#x8BE5;KEY&#x5BF9;&#x8C61;&#x5728;&#x6570;&#x7EC4;&#x4E2D;&#x5B58;&#x50A8;&#x7684;&#x4F4D;&#x7F6E;&#xFF0C;&#x5F53;&#x8FD9;&#x4E2A;&#x4F4D;&#x7F6E;&#x6709;&#x591A;&#x4E2A;&#x5BF9;&#x8C61;&#x65F6;&#xFF0C;&#x4EE5;&#x94FE;&#x8868;&#x7ED3;&#x6784;&#x5B58;&#x50A8;&#xFF0C;JDK1.8&#x540E;&#xFF0C;&#x5F53;&#x94FE;&#x8868;&#x957F;&#x5EA6;&#x5927;&#x4E8E;8&#x65F6;&#xFF0C;&#x94FE;&#x8868;&#x5C06;&#x8F6C;&#x6362;&#x4E3A;&#x7EA2;&#x9ED1;&#x6811;&#x7ED3;&#x6784;&#x5B58;&#x50A8;&#x3002;
 &#xA0; &#xA0;&#x8FD9;&#x6837;&#x7684;&#x76EE;&#x7684;&#xFF0C;&#x662F;&#x4E3A;&#x4E86;&#x53D6;&#x503C;&#x66F4;&#x5FEB; &#xFF0C;&#x5B58;&#x50A8;&#x7684;&#x6570;&#x636E;&#x91CF;&#x8D8A;&#x5927;&#xFF0C;&#x6027;&#x80FD;&#x7684;&#x8868;&#x73B0;&#x8D8A;&#x660E;&#x663E;
 &#xA0; &#xA0;
 &#xA0; &#xA0;4.&#x6269;&#x5145;&#x539F;&#x7406;&#xFF1A;&#x5F53;&#x6570;&#x7EC4;&#x7684;&#x5BB9;&#x91CF;&#x8D85;&#x8FC7;&#x4E86;75%&#xFF0C;&#x90A3;&#x4E48;&#x8868;&#x793A;&#x8BE5;&#x6570;&#x7EC4;&#x9700;&#x8981;&#x6269;&#x5145;&#xFF0C;&#x5982;&#x4F55;&#x6269;&#x5145;&#xFF1F;
 &#xA0; &#xA0;&#x6269;&#x5145;&#x7684;&#x7B97;&#x6CD5;&#x662F;&#xFF1A;&#x5F53;&#x524D;&#x6570;&#x7EC4;&#x5BB9;&#x91CF;<<1(相当于是乘2),扩大1倍,扩充次数过多,会影响性能,每次扩充表示哈希表重新散列(重新计算每个对象的存储位置),我们在开发中,尽量要减少扩充次数带来的性能问题。    5.线程不安全,适合在单线程中使用  * private static void hashmap(){ map<integer,string> map = new HashMap<>();
        map.put(1,"Tom");//1&#x548C;"Tom"&#x5B9E;&#x9645;&#x5B58;&#x50A8;&#x5728;map&#x5185;&#x90E8;new&#x7684;entry&#x5BF9;&#x8C61;
        map.put(2,"Jack");
        map.put(3,"Vince");
        map.put(4,"Bin");
        map.put(5,"Lily");
&#x200B;
        System.out.println("size="+map.size());
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x4ECE;Map&#x4E2D;&#x53D6;&#x503C;
 &#xA0; &#xA0; &#xA0; System.out.println( map.get(1));//&#x901A;&#x8FC7;key&#x53D6;value
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//map&#x7684;&#x904D;&#x5386;,&#x65B9;&#x5F0F;&#x4E00;&#xFF1A;&#x904D;&#x5386;key&#x548C;value
 &#xA0; &#xA0; &#xA0; &#xA0;Set<entry<integer,string>> entrySet = map.entrySet();//&#x5C06;entry&#x8F6C;&#x4E3A;set
 &#xA0; &#xA0; &#xA0; &#xA0;for(Entry e : entrySet){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;Sysetem.out.println(e.getKey() + "->" + e.getValue());
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x65B9;&#x5F0F;&#x4E8C;&#xFF1A;&#x904D;&#x5386;&#x952E;key
 &#xA0; &#xA0; &#xA0; &#xA0;Set<integer> keys = map.keySet();
 &#xA0; &#xA0; &#xA0; &#xA0;for(Integer i ; keys){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;String value = map.get(i);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(i+"->"+value);
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x65B9;&#x5F0F;&#x4E09;&#xFF1A;&#x904D;&#x5386;&#x503C;value
 &#xA0; &#xA0; &#xA0; &#xA0;Collection<string> values = map.values();
 &#xA0; &#xA0; &#xA0; &#xA0;for(String s : values){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(values);
 &#xA0; &#xA0; &#xA0;  }
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x65B9;&#x5F0F;&#x56DB;&#xFF1A;foreach
 &#xA0; &#xA0; &#xA0; &#xA0;map.forEach((key,value)->System.out.println(key+"->"+value);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(map.containsKey(7));//false
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//hash      15& 1434 &#x76F8;&#x5F53;&#x4E8E; 1434 % 16
 &#xA0; &#xA0; &#xA0; &#xA0;Integer key = 1434;
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println((key.hashCod()) ^ ((key.hashCod()) >>> 16 ));
    }
&#x200B;
&#x200B;
    public static void main(String [] args){
        hashMap();
    }
&#x200B;
}
&#x200B;</string></integer></entry<integer,string></1(相当于是乘2),扩大1倍,扩充次数过多,会影响性能,每次扩充表示哈希表重新散列(重新计算每个对象的存储位置),我们在开发中,尽量要减少扩充次数带来的性能问题。>
额外补充:

<

  • <

数学意义:在数字没有溢出的前提下,对于正数和负数,左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。

计算:3 << 2

3 << 2,则是将数字3左移2位

1、首先把3转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0011

2、然后把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,最后在低位(右侧)的两个空位补零。

3、则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1100,则转换为十进制是12。

  • 是一个”有符号”右移位运算符;它会将运算符左边的运算对象向右移动运算符右侧指定的位数。>>运算符使用了”符号扩展”:若值为正,则在高位插入0;若值为负,则在高位插入1

计算 : 11 >>2(11为int型)

1)、11的二进制形式为:0000 0000 0000 0000 0000 0000 0000 1011

2)、把低位的最后两个数字移出,因为该数字是正数,所以在高位补零。

3)、最终结果是0000 0000 0000 0000 0000 0000 0000 0010。

4)、转换为十进制是3。

6.3Hashtable

  • public class **Hashtable<k,v>**extends Dictionary<k,v>implements Map<k,v>, Cloneable, Serializable</k,v></k,v></k,v>

此类实现一个哈希表,该哈希表将键映射到相应的值。任何非 null对象都可以用作键或值。

为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode方法和 equals方法。

 &#xA0; /**
 &#xA0; &#xA0; JDK1.0&#x5F00;&#x59CB;
 &#xA0; &#xA0; &#x57FA;&#x4E8E;&#x54C8;&#x5E0C;&#x8868;&#x5B9E;&#x73B0;&#xFF08;&#x6570;&#x7EC4;+&#x94FE;&#x8868;&#xFF09;
 &#xA0; &#xA0; &#x9ED8;&#x8BA4;&#x6570;&#x7EC4;&#x5927;&#x5C0F;&#x4E3A;11&#xFF0C;&#x52A0;&#x8F7D;&#x56E0;&#x5B50;0&#x3002;75
 &#xA0; &#xA0; &#x6269;&#x5145;&#x65B9;&#x5F0F;&#xFF1B;&#x539F;&#x6570;&#x7EC4;&#x5927;&#x5C0F;<<1(即*2)+1   线程安全的(加了synchronized锁),用在多线程访问时 * private static void hashtable(){ ​ map<string,string> table = new Hashtable<>();
table.put("one","Lily");
table.put("two","Tom");
table.put("three","Bin");
&#x200B;
table.forEach((key,value)->System.out.println(key+"->"+value);
}
&#x200B;
&#x200B;</1(即*2)+1>

面试题:HashtMap与Hashtable的区别?

6.4LinkedHashMap
  • public class **LinkedHashMap<k,v>**extends HashMap<k,v>implements Map<k,v></k,v></k,v></k,v>

Map接口的哈希表和链接列表实现,具有可预知的迭代顺序。此实现与 HashMap的不同之处在于,后者维护着一个运行于所有条目的双重链接列表。

(因为HashMap顺序不可控,所以加入LinkedHashMap控制顺序)

 &#xA0;/**
 &#xA0; &#xA0;LinkedHashMap&#x662F;HashMap&#x7684;&#x5B50;&#x7C7B;&#xFF0C;&#x7531;&#x4E8E;HashMap&#x4E0D;&#x80FD;&#x4FDD;&#x8BC1;&#x987A;&#x5E8F;&#x6052;&#x4E45;&#x4E0D;&#x53D8;&#xFF0C;LinkedHashMap&#x4F7F;&#x7528;&#x4E00;&#x4E2A;&#x53CC;&#x91CD;&#x94FE;&#x8868;&#x6765;&#x7EF4;&#x62A4;&#x5143;&#x7D20;&#x6DFB;&#x52A0;&#x7684;&#x987A;&#x5E8F;
 &#xA0; &#xA0;*/
private static void LinkedHashMap(){
 &#xA0; &#xA0;Map<string,string> table = new LinkedHashMap<>();
 &#xA0; &#xA0;table.put("one","Lily");
    table.put("two","Tom");
    table.put("three","Bin");
}</string,string>
6.5TreeMap
  • public class **TreeMap<k,v>**extends AbstractMap<k,v>implements NavigableMap<k,v>, Cloneable, Serializable</k,v></k,v></k,v>

基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator进行排序,具体取决于使用的构造方法。

/**
    &#x57FA;&#x4E8E;&#x4E8C;&#x53C9;&#x6811;&#x7684;&#x7EA2;&#x9ED1;&#x6811;&#x5B9E;&#x73B0;
    */
private static void treeMap(){
    Map<string,string> map = new TreeMap<>();
    map.put("one","Lily");
    map.put("two","Tom");
    map.put("three","Bin");
    map.forEach((key,value)->System.out.println(key+"->"+value);
&#x200B;
 &#xA0; &#xA0;Map<dog,string> dogs = new TreeMap<>();
 &#xA0; &#xA0;dogs.put(new Dog(1,"2ha",3),"dog1");
 &#xA0; &#xA0;dogs.put(new Dog(2,"wangwang",2),"dog2");
 &#xA0; &#xA0;dogs.put(new Dog(3,"hsq",4),"dog3");
 &#xA0; &#xA0;//Dog&#x5B9E;&#x4F53;&#x7C7B;&#x8981;&#x5B9E;&#x73B0;Comparable<dog>&#x63A5;&#x53E3;&#xFF0C;&#x518D;&#x91CD;&#x5199;compareTo&#x65B9;&#x6CD5;&#xFF08;this.id-o.id)&#x7528;ID&#x505A;&#x6392;&#x5E8F;&#x4F9D;&#x636E;&#xFF0C;&#x624D;&#x80FD;&#x8F93;&#x51FA;&#xFF0C;&#x6CE8;&#x610F;&#xFF1A;&#x5F53;&#x4E24;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;key&#x76F8;&#x540C;&#x65F6;&#xFF0C;&#x7B2C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#x4E0E;&#x7B2C;&#x4E8C;&#x4E2A;&#x5BF9;&#x8C61;&#x88AB;&#x770B;&#x505A;&#x540C;&#x4E00;&#x4E2A;&#x5BF9;&#x8C61;&#xFF0C;&#x8F93;&#x51FA;&#x7684;value&#x4F1A;&#x662F;&#x7B2C;&#x4E8C;&#x4E2A;&#x5BF9;&#x8C61;&#x7684;value&#xFF0C;&#x5373;key&#x6CA1;&#x53D8;&#xFF0C;value&#x4F1A;&#x88AB;&#x66FF;&#x6362;
 &#xA0; &#xA0;dogs.forEach((key,value)->System.out.println(key+"->"+value);
&#x200B;
&#x200B;
}</dog></dog,string></string,string>

未来想用红黑树来存储,单个对象就用TreeSet,键值对对象就用TreeMap

6.6 Map接口JDK1.8新特性

在JDK1.8中Map接口提供了一些新的便利的方法。因为在文本中我所提到的所有Map方法都是以默认值方法的方式实现的,所以现有的Map接口的实现可以直接拥有这些在默认值方法中定义的默认行为,而不需要新增一行代码
Method getOrDefault(Object,v)putIfAbsent(k,v)remove(Object key , Object value)replace(k,v)replace(k,v,v)compute(k key,BiFunctionremappingFunction)computeIfPresent(k key,BiFunctionremappingFunction)merge(k key,v value,BiFunction remappingFunction)

public class MapNewMethodDemo{
&#x200B;
    public static void main(String[] args){

    Map<integer,string> map = new HashMap<>();
     map.put("one","Lily");
    map.put("two","Tom");
    map.put("three","Bin");

    //getOrDefault,&#x83B7;&#x53D6;&#x4E0D;&#x5230;&#x503C;&#x5C31;&#x8FD4;&#x56DE;&#x9ED8;&#x8BA4;&#x503C;&#x5B57;&#x7B26;&#x4E32;"null"&#xFF0C;&#x6CA1;&#x6709;&#x8FD9;&#x4E2A;&#x65B9;&#x6CD5;&#x7684;&#x8BDD;&#xFF0C;&#x8981;&#x52A0;&#x4E2A;&#x5224;&#x65AD;&#x5176;&#x662F;&#x5426;&#x4E3A;null
    String value = map.getOrDefault(4,"null");

 &#xA0; &#xA0;String val = map.put(3."vince");//&#x4F1A;&#x8986;&#x76D6;&#x65E7;&#x503C;&#xFF0C;&#x5E76;&#x8FD4;&#x56DE;&#x65E7;&#x503C;
 &#xA0; &#xA0;System&#xFF0C;out.println(val);
    String val = map.putIfAbsent(3,"vince");//putIfAbsent&#x6839;&#x636E;key&#x67E5;&#x627E;value&#xFF0C;&#x5982;&#x679C;value&#x6709;&#x503C;&#xFF0C;&#x5C31;&#x4E0D;put&#xFF0C;&#x5373;&#x4E0D;&#x8986;&#x76D6;&#x65E7;&#x503C;&#xFF0C;&#x5E76;&#x8FD4;&#x56DE;&#x67E5;&#x5230;&#x7684;value&#x503C;&#x3002;&#x53EA;&#x4F1A;&#x6DFB;&#x52A0;&#x4E0D;&#x5B58;&#x5728;&#x76F8;&#x540C;key&#x7684;&#x503C;

 &#xA0; &#xA0;//&#x6839;&#x636E;&#x952E;&#x548C;&#x503C;&#x90FD;&#x5339;&#x914D;&#x65F6;&#x624D;&#x5220;&#x9664;
 &#xA0; &#xA0;map.remove(key,value);
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0;
 &#xA0; &#xA0;map.replace(3,"vince");
 &#xA0; &#xA0;map.replace(2,"Lily","vince");
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0;map.compute(1,(k,v1)->v1+"1");
 &#xA0; &#xA0;map.computeIfAbsent(5,(value)->val+"test");
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0;//&#x5408;&#x5E76;
 &#xA0; &#xA0;map.merge(1,"888",(oldVal,newVal)->oldVal.concat(newVal));//"888"&#x662F;&#x65B0;&#x503C;
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0;map.forEach((k,v)->System.out.println(k+"-."+v));
    }
&#x200B;
}</integer,string>

7.Collections工具类

7.1排序查找(主要针对List接口相关)

Method 说明reverse(List list)反转指定List集合中元素的顺序shuffle(List list)对List中的元素进行随机排序(洗牌)sort(List list )对List里的元素根据自然升序排序sort(List list,Comprarator c)自定义比较器进行排序swap(List list,int i,int j)将指定List集合中 i 处元素和 j 处元素进行交换rotate(List list,int distance)将所有元素向右移位指定长度,如果distance等于size那么结果不变

public class collectionsDemo{
&#x200B;
        public &#xA0;static void main(String[] args){
&#x200B;
        List<string> &#xA0;list &#xA0;= new ArrayList<>();
        list.add("jack");
        list.add("tom");
        list.add("lily");
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x53CD;&#x8F6C;
        Collections.reverse(list);
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x6253;&#x4E71;&#x987A;&#x5E8F; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;Collections.shuffle(list);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x5347;&#x5E8F;&#xFF0C;&#x6392;&#x5E8F; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;Collections.sort(list);
 &#xA0; &#xA0; &#xA0; // Collections.sort(list,c);//&#x4F20;&#x6BD4;&#x8F83;&#x5668;
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x4EA4;&#x6362;
 &#xA0; &#xA0; &#xA0; &#xA0;Collections.swap(list,0,2);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x65CB;&#x8F6C; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;Collections.rotate(list,1);
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
        System.out.println(list);
&#x200B;
}
&#x200B;
}</string>
7.2查找和替换(主要针对Collection接口相关)

Method 说明binarySearch(LIst list,Object key)使用二分搜索法,以获取指定对象在List中的索引,前提是集合已经排序max(Collection coll)返回最大元素max(Collection coll , Comparator comp)根据自定义比较器,返回最大元素min(Collection coll)返回最小元素min(Collection coll, Comparator comp)根据自定义比较器,返回最小元素fill(List list , Object obj)使用指定对象填充frequency(Collection Object o)返回指定集合中指定对象出现的次数replaceAll(List list,Object old,Object new)替换

public class collectionsDemo{
    public &#xA0;static void main(String[] args){
 &#xA0; &#xA0; &#xA0; &#xA0;Collections.binarySearch(list,"tom");
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(Collections.max(list));
 &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(Collections.min(list));
 &#xA0; &#xA0; &#xA0; &#xA0;//&#x586B;&#x5145;
 &#xA0; &#xA0; &#xA0; &#xA0;Collections.fill(list,"bin");
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(Collections.frequency(list,"lily"));
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;Collections.replaceAll(list,"lily","bin");
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(list);
&#x200B;
 &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0;  }
} &#xA0; &#xA0;
7.3同步控制

Collections工具类中提供了多个synchronizedXxx方法,该方法返回指定集合对象对应的同步对象,从而解决多线程并发访问时线程的安全问题。HashSet、ArrayList、HashMap都是线程不安全的,如果需要考虑同步,则使用这些方法。这些方法主要有:synchronizedSet , synchronizedSortedSet, synchronizedList, synchronizedMap, synchronizedSorteMap.

特别需要指出的是,在使用迭代方法遍历集合时需要手工同步返回的集合。

public class collectionsDemo{ &#xA0; &#xA0;
    public &#xA0;static void main(String[] args){ &#xA0; &#xA0; &#xA0;
 &#xA0;      List<string> syncList = Collections.synchronizedList(new ArrayList<string>());
 &#xA0; &#xA0;
 &#xA0;  }
} &#xA0; &#xA0;</string></string>
7.4 设置不可变

Collections有三类方法可返回一个不可变集合:

emptyXxx():返回一个空的不可变的集合对象

singletonXxx():返回一个只包含指定对象的,不可变的集合对象

unmodifiableXxx():返回指定集合对象的不可变范围

List<string> &#xA0;sList = &#xA0;Collections.emptyList();
&#x200B;
    sList.add("bin");//&#x4F1A;&#x62A5;&#x9519;&#xFF0C;&#x4E0D;&#x80FD;&#x6DFB;&#x52A0;&#xFF0C;&#x56E0;&#x4E3A;&#x5B83;&#x662F;&#x4E00;&#x4E2A;&#x7A7A;&#x7684;list</string>
7.5 其他

Method 说明disjoint(Collecition c1,Collection c2)如果两个指定collection中没有相同的元素,则返回true。addAll(Collection c,T…a)一种方便的方式,将所有指定元素添加到指定collection中。Comparator reverseOrder(Comparator cmp)返回一个比较器,它强行反转指定比较器的顺序。如果指定比较器为null,则此方法等同于reverseOrder()(换句话说,它返回一个比较器,该比较器将强行反转实现Comparable接口那些东西collection的自然顺序。

/&#x53CD;&#x8F6C;&#x987A;&#x5E8F;
Collections.sort(list,Collections.reverseOrder());
7.6 Optional容器类(JDK1.8)

Optional容器类(只能放一个对象),主要解决的问题是臭名昭著的空指针异常

例:当一个返回值要作为另一个方法的参数,但是不知道这个返回值是否为空,可以使用Optional解决。

这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
Method 说明of()为非null的值创建一个Optional。ofNullable()为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional isPresent()如果值存在返回true,否则返回false get()如果Optional有值则将其返回,否则抛出NoSuchElementException ifPresent()如果Optional实例有值则为其调用consumer,否则不做处理orElse()如果有值则将其返回,否则返回指定的其他值orElseGet()orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值orElseThrow()如果有值则将其返回,否则抛出supplier接口创建的异常map 如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional flatMap 如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。flatMap与map(Function)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装filter 如果有值并且满足断言条件返回包含该值的Optional,封装返回空Optional

//&#x521B;&#x5EFA;Optional&#x5BF9;&#x8C61;&#x7684;&#x65B9;&#x5F0F;
Optional<string> optional = Optional.of("bin");
Optional<string> optional2 = Optional.ofNullable("bin");
Optional<string> optional3 = Optional.empty("bin");
&#x200B;
System.out.println(optoinal.isPresent());
System.out.println(optoinal.get());
&#x200B;
optional.ifPresent((value)->System.out.println(value));
&#x200B;
System.out.println(optoinal.orElse("&#x65E0;&#x503C;"));
&#x200B;
System.out.println(optional.orElseGet(()->"default");
&#x200B;
 &#xA0; &#xA0; &#xA0;try{
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; optional3.orElseThrow(Exception::new); &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0;  } catch (Exception e){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;e.printStackTrace();
 &#xA0; &#xA0;  }
&#x200B;
 &#xA0; &#xA0; &#xA0;Optional<string> optional4 = optional.map((value)->value.toUppercase());
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0;System.out.println(optional4.orElse("no found"));
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0;Optional<string> optional5 = optional.flatMap((value) >Optional.of(value.toUpperCase));
 &#xA0; &#xA0; &#xA0;System.out.println(optional5.orElse("no found"));
&#x200B;
 &#xA0; &#xA0; &#xA0;Optional<string> optional6 = optional.filter((value)->value.length>3); &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; System.out.println(optional6.orElse("&#x8FD9;&#x4E2A;&#x503C;&#x7684;&#x957F;&#x5EA6;&#x5C0F;&#x4E8E;3"));
 &#xA0; </string></string></string></string></string></string>

8.Queue、Deque接口

队列是一种特殊的线性表,是一种 先进先出(FIFO)的数据结构。它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。
返回值Method和说明 boolean add(E e)将指定的元素插入到此队列中,(如果可以立即执行此操作且不会违反容量限制), 成功后返回 true, 如果当前没有可用空间,则抛出IllegalStateException。 E element()检索,但不删除,这个队列的头。 boolean offer(E e)将指定的元素插入到此队列( 如果立即执行且不违反容量限制),当使用有容量限制的队列时,此方法通常要优于add(E),后者可能无法插入元素,而只是抛出一个异常 E peek()检索但不删除此队列的头,如果此队列为空,则返回 nullE poll()检索并删除此队列的头,如果此队列为空,则返回 nullE remove()检索并删除此队列的头。

/**
Queue&#x63A5;&#x53E3;&#xFF1A;&#x961F;&#x5217;&#xFF0C;&#x662F;&#x4E00;&#x79CD;&#x5148;&#x8FDB;&#x5148;&#x51FA;&#x7684;&#x7EBF;&#x6027;&#x6570;&#x636E;&#x7ED3;&#x6784;&#xFF08;&#x6392;&#x961F;&#xFF09;
LinkedList&#x7C7B;&#x5B9E;&#x73B0;&#x4E86;queue&#x63A5;&#x53E3;
&#x8BF7;&#x6C42;&#x961F;&#x5217;&#xFF0C;&#x6D88;&#x606F;&#x961F;&#x5217;&#xFF0C;&#x4EFB;&#x52A1;
&#x200B;
*/
&#x200B;
private static void queue(){
    Queue<string> queue = new LinkedList<>();
    queue.add("&#x5C0F;&#x82B1;");
    queue.add("&#x5C0F;&#x9ED1;");
    queue.add("&#x5C0F;&#x7EA2;");
    queue.add("&#x5C0F;&#x9EC4;");
    queue.add("&#x5C0F;&#x7D2B;");
    queue.add("&#x5C0F;&#x7EFF;");

    System.out.println(queue.size());
    System.out.println(queue.peek());
    System.out.println(queue.size());
    System.out.println(queue.poll());
    System.out.println(queue.size());
&#x200B;

&#x200B;
}</string>

Deque:一个线性collection,支持在两端插入和移除元素。此接口既支持有容量限制的双端对列,也支持没有固定大小限制的双端对列。接口定义在双端对列两端访问元素的方法。提供插入、移除和检查元素的方法。

/**
Deque&#x63A5;&#x53E3;&#xFF1A;&#x53CC;&#x7AEF;&#x5BF9;&#x5217;
Stack&#xFF1A;&#x5806;&#x6808;&#xFF1A;&#x5148;&#x8FDB;&#x540E;&#x51FA;
*/
public static void deque(){
 &#xA0; &#xA0;Deque<string> deque = new LinkedList<>();
 &#xA0; &#xA0; &#xA0; &#xA0;Deque.add("&#x5C0F;&#x82B1;");
 &#xA0; &#xA0; &#xA0; &#xA0;Deque.add("&#x5C0F;&#x9ED1;");
 &#xA0; &#xA0; &#xA0; &#xA0;Deque.add("&#x5C0F;&#x7EA2;");
 &#xA0; &#xA0; &#xA0; &#xA0;Deque.add("&#x5C0F;&#x9EC4;");
 &#xA0; &#xA0; &#xA0; &#xA0;Deque.add("&#x5C0F;&#x7D2B;");
 &#xA0; &#xA0; &#xA0; &#xA0;Deque.add("&#x5C0F;&#x7EFF;");
    System.out.println(deque.getFirst());
    System.out.println(deque.getLast());
}
&#x200B;
private static void stack(){
    Stack<string> s = new Stack<>();
    //&#x538B;&#x6808;
    s.push("Bin");
    s.push("TOm");
    s.push("Lily");
    System.out.println(s.peek());
    System.out.println(s.pop());
&#x200B;

}</string></string>

9.对象一对多与多对多关系

可以使用集合来表示实际开发中对象的一对多关系和多对多关系

public class Teacher{
//&#x4E00;&#x4E2A;&#x8001;&#x5E08;&#x5BF9;&#x5E94;&#x591A;&#x4E2A;&#x5B66;&#x751F;
......

private HashSet<student> students = new HashSet<>();
&#x200B;
......

}
&#x200B;
public class Student{
//&#x4E00;&#x4E2A;&#x5B66;&#x751F;&#x5BF9;&#x5E94;&#x4E00;&#x4E2A;&#x8001;&#x5E08;
......

private Teacher teacher;
&#x200B;
......

}
&#x200B;
public class OneToManyDemo{
    public static void main(String[] args){

    Teacher t1 = new Teacher("&#x5F20;&#x8001;&#x5E08;",18,"&#x5973;");
    Student s1 = new Student("&#x5C0F;&#x674E;",10);
    Student s2 = new Student("&#x5C0F;&#x738B;",12);
    Student s3 = new Student("&#x5C0F;&#x8D75;",13);

    //&#x5173;&#x8054;&#x5173;&#x7CFB;
    t1.getStudents().add(s1);
    t1.getStudents().add(s2);
    t1.getStudents().add(s3);
&#x200B;
    s1.setTeacher(t1);
    s2.setTeacher(t1);
    s3.setTeacher(t1);
    print(t1);
    }
&#x200B;
    private static void print(Teacher t1){
    System.out.println(t1.getName());
    for(Studend s : t1.getStudents()){
        System.out.pritln(s);
    }
    }
}</student>

多对多关系一般拆成两个一对多关系,找个中间件做两个一对多关系中的多

10.迭代器设计模式

提供一个方法按顺序遍历一个集合内的元素,而又不需要暴露该对象 的内部表示。

应用场景

1.访问一个聚合的对象,而不需要暴露对象的内部表示

2.支持对聚合对象的多种遍历

3.对遍历不同的对象, 提供统一的接口

迭代器模式的角色构成

1.迭代器角色(Iterator);定义遍历元素所需要的方法,一般来说会有这么三个方法,取得下一个元素的方法next(),判断是否遍历结束的方法hasNext(),移出当前对象的方法remove()

2.具体迭代器角色(Concrete Iterator):实现迭代器接口中定义的方法,完成集合的迭代

3.容器角色(Aggregate):一般是一个接口,提供一个Iterator()方法,例如java中的Collection接口,List接口,Set接口等

4.具体容器角色(ConcreteAggregate):就是抽象容器的具体实现类,比如List接口的有序列表实现ArrayList,List接口的链表实现LinkedList,Set接口的哈希列表的实现HashSet等。

11.Guava对集合的支持

版本下载:https://repo1.maven.org/maven2/com/google/guava/guava/

下载路径:../→22.0/→guava-22.0-javadoc.jar(解压一下,一个文档)、guava-22.0-sources.jar(源代码)、guava-22.0-jar(要用的,导入项目去)

Guava(番石榴)工程包含了若干被Google的java项目广泛依赖的核心库,例如:集合、缓存、原生类型支持、并发库、通用注解、字符串处理、I/O等等。所有这些工具每天都在被Google的工程师应用在产品服务中。

Guava对JDK集合的扩展,这是Guava最成熟和为人所知的部分。

  1. 不可变集合:用不变的集合进行防御性编程和性能提升。
  2. 新集合类型:multisets,multimaps,tables等
  3. 强大的集合工具类:提供java.util.Collections中没有的集合工具
  4. 扩展工具类:让实现和扩展集合类变得跟容易,比如创建Collection的装饰器,或实现迭代器

  5. 只读设置

  6. 函数式编程:过滤器
  7. 函数式编程:转换
  8. 组合式函数编程
  9. 加入约束:非空、长度验证
  10. 集合操作:交集、差集、并集
  11. Multiset:无序可重复
  12. Multimap key 可以重复
  13. BiMap:双向Map(bidirectional Map)键与值不能重复
  14. 双键的Map—>Table—>rowKey+columnkey + value

使用JUnit组件测试,在方法上写注解@Test,就可以通过JUnit而不用再写main方法来调用

/**
&#x53EA;&#x8BFB;&#x8BBE;&#x7F6E;    ImmutableList.of()
*/
@Test
public void testGuava1(){
    System.out.println("test guava");
    //&#x5728;JDK&#x91CC;&#x63D0;&#x4F9B;&#x7684;&#xFF0C;&#x521B;&#x5EFA;&#x56FA;&#x5B9A;&#xFF0C;&#x4E0D;&#x53EF;&#x53D8;&#x96C6;&#x5408;
    /**
    List<string> list = Arrays.asList("jack","tom");
    List.add("bin");//&#x62A5;&#x9519;
    */
    List<string> list = new ArrayList<>();
 &#xA0; &#xA0;list.add("jack");
 &#xA0; &#xA0;list.add("tom");
 &#xA0; &#xA0;list.add("bin");
 &#xA0; &#xA0;list.add("lily");
 &#xA0; &#xA0;//&#x4F9D;&#x7136;&#x4E0D;&#x80FD;&#x6DFB;&#x52A0;&#x7684;&#xFF0C;&#x5B9E;&#x73B0;&#x53EA;&#x8BFB;&#x96C6;&#x5408;
    List<string> readList = collections.unmodifiableList(list);
 &#xA0; &#xA0;
 &#xA0; &#xA0;//guava&#x63D0;&#x4F9B;&#x7684;&#x53EA;&#x8BFB;
 &#xA0; &#xA0;ImmutableList<string> iList = &#xA0;ImmutableList.of("jack","tom","lily","bin")
}</string></string></string></string>
/**
&#x8FC7;&#x6EE4;&#x5668; Collections2.filter()
*/
@Test
public void testGuava2(){
 &#xA0; &#xA0;//guava&#x63D0;&#x4F9B;&#x7684;&#x521B;&#x5EFA;ArrayList
 &#xA0; &#xA0;List<string> list = Lists.newArrayList("java","php","jack","ham");
 &#xA0; &#xA0;//guava&#x63D0;&#x4F9B;&#x7684;&#x8FC7;&#x6EE4;&#x5668;
 &#xA0; &#xA0;Collections<sting> result = &#xA0;Collections2.filter(list,(e)->e.startsWith("j"));
 &#xA0; &#xA0;result.forEach(System.out::println);
}</sting></string>
/**
&#x8F6C;&#x6362;  Collections2.transform()
*/
@Test
public void testGuava3(){
    Set<long> timeSet = Sets.newHashSet(20180201L,20190515L,20201221L);
    Collections<string> timeCollect = Collections2.transform(timeSet,(e)->new SimpleDateFormat("yyyy-MM-dd").format(e));
    timeCollect.forEach(System.out::println);
}</string></long>
/**
&#x7EC4;&#x5408;&#x5F0F;&#x51FD;&#x6570;   Functions.compose()
*/
@Test
public void testGuava4(){
 &#xA0; &#xA0;List<string> list = Lists.newArrayList("java","php","jack","ham");
 &#xA0; &#xA0;
    Function<stirng,string> f1 = new Function<string,string>(){
 &#xA0; &#xA0; &#xA0; &#xA0;public String apply(String t){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;return t.length()>4?t.substring(0,4):t;
 &#xA0; &#xA0; &#xA0;  }
 &#xA0;  };
 &#xA0; &#xA0;Function<stirng,string> f2 = new Function<string,string>(){
 &#xA0; &#xA0; &#xA0; &#xA0;public String apply(String t){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;return t.toUpperCase();
 &#xA0; &#xA0; &#xA0;  }
 &#xA0;  };
 &#xA0; &#xA0;Function<string,string> f = Functions.compose(f1,f2);
 &#xA0; &#xA0;Collections<string> coll = Collections2.transfrom(list,f);
    coll.forEach(System.out::println);
}</string></string,string></string,string></stirng,string></string,string></stirng,string></string>
/**
&#x52A0;&#x5165;&#x7EA6;&#x675F;&#xFF1A;&#x975E;&#x7A7A;&#x3001;&#x957F;&#x5EA6;&#x9A8C;&#x8BC1;
*/
@Test
public void testGuava5(){
    Set<long> timeSet = Sets.newHashSet();
    //14&#x7248;&#x672C;&#x53EF;&#x7528;&#xFF0C;14&#x540E;&#x7528;&#x4E0D;&#x4E86;
 &#xA0; &#xA0;Constraint<string> constraint = new Constraint<>(){
 &#xA0; &#xA0; &#xA0; &#xA0;public String checkElement(String element){
 &#xA0; &#xA0; &#xA0; &#xA0; &#xA0; &#xA0;
 &#xA0; &#xA0; &#xA0;  }
 &#xA0;  }
 &#xA0; &#xA0;//&#x8FD9;&#x4E24;&#x4E2A;&#x8FD8;&#x53EF;&#x4EE5;&#x7528;
 &#xA0; &#xA0;Preconditions.checkArgument(expression);
 &#xA0; &#xA0;Preconditions.checkNotNUll(reference);
}</string></long>
/**
&#x96C6;&#x5408;&#x64CD;&#x4F5C;&#xFF1A;&#x4EA4;&#x96C6;&#x3001;&#x5DEE;&#x96C6;&#x3001;&#x5E76;&#x96C6;
*/
@Test
public void testGuava6(){
 &#xA0; &#xA0;Set<integer> set1 = Sets.newHashSet(1,2,3);
 &#xA0; &#xA0;Set<integer> set2 = Sets.newHashSet(3,4,5);
&#x200B;
 &#xA0; &#xA0;//&#x4EA4;&#x96C6;
 &#xA0; &#xA0;SetView<inter> v1 = Sets.intersection(set1,set2);
 &#xA0; &#xA0;v1.forEach(System.out::println);
 &#xA0; &#xA0;
 &#xA0; &#xA0;//&#x5DEE;&#x96C6;,&#x4EE5;set1&#x4E3A;&#x4E3B;&#xFF0C;&#x627E;&#x5DEE;&#x5F02;
 &#xA0; &#xA0;SetView<inter> v2 = Sets.difference(set1,set2);
 &#xA0; &#xA0;v2.forEach(System.out::println);
&#x200B;
 &#xA0; &#xA0;//&#x5E76;&#x96C6;,&#x53BB;&#x91CD;
 &#xA0; &#xA0;SetView<inter> v3 = Sets.union(set1,set2);
 &#xA0; &#xA0;v3.forEach(System.out::println);
}</inter></inter></inter></integer></integer>
/**
Multiset&#xFF1A;&#x65E0;&#x5E8F;&#x53EF;&#x91CD;&#x590D;
*/
@Test
public void testGuava7(){
    String s = "good good study day day up";
    String[] s2 = s.split(" ");
    HashMultiset<string> set = HashMultiset.create();
    for(String str :s2){
        set.add(str);
    }
    Set<string> set2 = set.elementSet();
    for(String str :set2){
        System.out.println(str+":"+set.count(str));
    }
}</string></string>
/**
Multimap  key &#x53EF;&#x4EE5;&#x91CD;&#x590D;
*/
@Test
public void testGuava8(){
    Map<string,string> map = new HashMap<>();
    map.put("&#x897F;&#x6E38;&#x8BB0;","&#x5434;&#x627F;&#x6069;");
    map.put("&#x7EA2;&#x697C;&#x68A6;","&#x66F9;&#x96EA;&#x82B9;");
    map.put("&#x6C34;&#x6D52;&#x4F20;","&#x65BD;&#x8010;&#x5EB5;");
 &#xA0; &#xA0;map.put("xxx","&#x65BD;&#x8010;&#x5EB5;");
&#x200B;
    Multimap<string,string> mmap = ArrayListMultimap.create();
 &#xA0; &#xA0;Iterator<map.entry<string,string> iter = map.entrySet().iterator();
 &#xA0; &#xA0;while(iter.hashNext()){
 &#xA0; &#xA0; &#xA0; &#xA0;Map.Entry<string,string> entry = iter.next();
 &#xA0; &#xA0; &#xA0; &#xA0;mmap.put(entry.getValue(),entry.getKey());
 &#xA0;  }
 &#xA0; &#xA0;Set<string> keySet = mmap.keySet();
 &#xA0; &#xA0;for(String key : keySet){
 &#xA0; &#xA0; &#xA0; &#xA0;Collection<string> values = mmap.get(key);
 &#xA0; &#xA0; &#xA0; &#xA0;System.out.println(key+"->"+values);
 &#xA0;  }
}</string></string></string,string></map.entry<string,string></string,string></string,string>
/**
BiMap&#xFF1A;&#x53CC;&#x5411;Map&#xFF08;bidirectional Map&#xFF09;&#x952E;&#x4E0E;&#x503C;&#x4E0D;&#x80FD;&#x91CD;&#x590D;
*/
@Test
public void testGuava9(){
    BigMap<string,string> map = HashBiMap.create();
    map.put("finally_test","15112315478");
    map.put("bin_test","15178784545");
    String name = map.inverse().get("15112315478");
    System.out.println(name);
}</string,string>
/**
&#x53CC;&#x952E;&#x7684;Map--->Table--->rowKey+columnkey + value
*/
@Test
public void testGuava10(){
    Table<string,string,integer> table = HashBasedTable.create();
    table.put("jack","java",80);
    table.put("tom","php",84);
    table.put("bin","java",60);
    table.put("lily","c++",89);

    Set<cell<string,string,integer>> cells = table.cellSet();
    for(Cell c: cells){
        System.out.println(c.getRowKey()+"-"+c.getColumnKey()+"-"+c.getVatlue());
    }
&#x200B;
}</cell<string,string,integer></string,string,integer>

参考资料:

JDK1.8帮助文档

■免责申明
⒈ 本站是纯粹个人学习网站,与朋友交流共赏,不存在任何商业目的。
⒉ 本站利用了部分网络资源,版权归原作者及网站所有,如果您对本站所载文章及作品版权的归属存有异议,请立即通知我们,我们将在第一时间予以删除,同时向你表示歉意!

Original: https://www.cnblogs.com/lyh1024/p/16738857.html
Author: 逝去の年华
Title: java基础-集合

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/615907/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • validform学习

    1 说明 validform非常实用,可以用来进行表单验证,是基于jquery框架的,一共就导出两个文件,一个css文件,一个js文件。启动也只需一句js语句即可,相当方便。 可以…

    Java 2023年6月7日
    050
  • Spring框架完整学习!!!

    1.Spring 1.1、简介 1.2、优点 1.3、组成 1.4、拓展 2.IOC思想解析 2.1、场景模拟 2.2、概念解析 2.3、总结 3.初涉Spring 3.1、 基础…

    Java 2023年6月8日
    0117
  • 线程通信和8锁问题

    线程通信 1、场景:生产者和消费者问题 ==仓库、生产者、消费者 ====仓库只能存放一个产品,生产者将生产出来的产品放入仓库,消费者将仓库中产品取走 ====如果仓库中没有产品,…

    Java 2023年6月5日
    084
  • 转载:Error:(1, 1) java: 非法字符: ‘ufeff’

    https://www.cnblogs.com/diffx/p/10000123.html 一、问题 用IDEA打开eclipse java项目编译时,出现以下错误: Error:…

    Java 2023年5月29日
    090
  • nginx转发https协议

    内网需要访问github.com,并且是按照https://github.com这样的访问方式进行访问。 因为使用了npm install git+https://github.c…

    Java 2023年5月30日
    073
  • 观察线程的状态

    public class ThreadState { public static void main(String[] args) { // 定义一个线程 Thread threa…

    Java 2023年6月13日
    099
  • Golang多线程垂直输出字符串

    [本文出自天外归云的博客园] 三个字符串,abc,def,ghi,请用多线程顺序输出:adg,beh,cfi 抛砖引玉,我的代码如下: go;gutter:true; packag…

    Java 2023年5月29日
    075
  • SpringBoot自动装配初步浅理解

    Created time: May 15, 2022 6:36 PMDone: DoingLast edited time: May 25, 2022 6:13 PMTags: S…

    Java 2023年6月8日
    086
  • PgSQL-||-连字符

    (PgSQL)连字符 || — 22.22& select 22.22||’%’ as 值; Original: https://www.cnblogs.com/a999…

    Java 2023年6月9日
    091
  • 类加载的机制及过程

    5个步骤:加载–>验证–>准备–>解析–>初始化 加载:读取二进制文件,根据路径找到对应的class文件然后…

    Java 2023年6月14日
    064
  • 空闲时间研究一个小功能:winform桌面程序如何实现动态更换桌面图标

    今天休息在家,由于天气热再加上疫情原因,就在家里呆着,空闲时想着,在很早以前(约3年前),产品人员跟我提了一个需求,那就是winform桌面程序的图标能否根据节日动态更换,这种需求…

    Java 2023年6月9日
    0120
  • 字符串转为JSON对象

    经常写字符串转为JSON对象,但是每次没有说一次就成功的,老是搞错属于哪个包的方法,遂记录一下 JSONObject.parseObject(str);这个方法需要导入包 com….

    Java 2023年6月8日
    094
  • Tomcat无法启动:报出Server Tomcat v8.5 Server at localhost failed to start

    昨天晚上写Javaweb练习,突然Tomcat报错(Server Tomcat v8.5 Server at localhost failed to start),启动失败 用to…

    Java 2023年6月9日
    070
  • rocketmq总结

    1:角色关系 2:顺序消息 消费消息的顺序要同収送消息的顺序一致,在 RocketMQ 中,主要挃的是局部顺序,即一类消息为满足顺序性,必须 Producer 单线程顺序収送,丏収…

    Java 2023年5月30日
    092
  • javaweb学生管理系统 第一次总结

    JavaWeb 学生管理系统 第一次总结 ; 具备的知识 java se 高级数据库jsselvetEl表达式jsp 项目 目录结构 [外链图片转存失败(img-dfQq8aOt-…

    Java 2023年6月8日
    093
  • 浅谈JWT

    JWT 常见的认证机制 HTTP Basic Auth HTTP Basic Auth简单点说明就是每次请求API时都提供用户的username和password,简言之,Basi…

    Java 2023年6月5日
    093
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球