黑马程序员—集合

String类

-------------------------------------------------------------------------------------------------------------------------------------
 字符串是一个特殊的对象。

 字符串一旦初始化就不可以被改变。

 String str = “abc”;

 String str1 = new String(“abc”);

[java]  view plain copy
  1. class StringDemo   
  2. {  
  3.     public static void main(String[] args)   
  4.     {  
  5.         /* 
  6.         String s1 = "abc";//s1是一个类类型变量, "abc"是一个对象。 
  7.                         //字符串最大特点:一旦被初始化就不可以被改变。 
  8.  
  9.         String s2 = new String("abc"); 
  10.  
  11.         //s1和s2有什么区别? 
  12.         //s1在内存中有一个对象。 
  13.         //s2在内存中有两个对象。 
  14.          
  15.  
  16.  
  17.  
  18.  
  19.         System.out.println(s1==s2); 
  20.         System.out.println(s1.equals(s2));//String类复写了Object类中equals方法, 
  21.                                         //该方法用于判断字符串是否相同。 
  22.  
  23.         */  
  24.   
  25.         String s = "abcde";  
  26.         method_1(s);  
  27.     }  
  28.   
  29.     /* 
  30.     String类是对字符串事物的描述。 
  31.     该类定义了专门用于操作字符串的方法。 
  32.     "abc": 
  33.     */  
  34.   
  35.     public static void method_1(String s)  
  36.     {  
  37.         char ch = s.charAt(3);  
  38.   
  39.         System.out.println("ch="+ch);  
  40.         int num = s.codePointAt(3);  
  41.   
  42.         System.out.println("num="+num);  
  43.   
  44.         String s1 = "qq";  
  45.         s1 = s1.concat("mm");  
  46.   
  47.         System.out.println("s1="+s1);  
  48.         System.out.println("qq"+"mm");  
  49.   
  50.         String a = "opq";  
  51.         String b = "opq";  
  52.         System.out.println("a==b:"+(a==b));  
  53.   
  54.   
  55.     }  
  56. }  


 

有什么区别 ?

String类部分方法


 char charAt(int index)

 int length()

 char[] toCharArray();

 int indexOf(String str);

 boolean endsWith(String str);

 String[] split(String reg);

 String substring(int index);

 String(char[] arr);

StringBuffer

     字符串的组成原理就是通过该类实现的。


 StringBuffer可以对字符串内容进行增删。


 StringBuffer是一个容器。


 很多方法与String相同。


 StingBuffer是可变长度的。

StringBuffer特有方法

 

 StringBuffer append(int x);

 StringBuffer delete(int start, int end );

 StringBuffer insert(int index,String str);

 StringBuffer reverse();

 JDK1.5出现一个StringBuilder,区别是 StringBuffer是同步的,StringBuilder是非同步 的。

[java]  view plain copy
  1. /* 
  2. StringBuffer是字符串缓冲区。 
  3.  
  4. 是一个容器。 
  5. 特点: 
  6. 1,长度是可变化的。 
  7. 2,可以字节操作多个数据类型。 
  8. 3,最终会通过toString方法变成字符串。 
  9.  
  10.  
  11.  
  12. C create U update R read D delete 
  13.  
  14. 1,存储。 
  15.     StringBuffer append():将指定数据作为参数添加到已有数据结尾处。 
  16.     StringBuffer insert(index,数据):可以将数据插入到指定index位置。 
  17.  
  18.  
  19. 2,删除。 
  20.     StringBuffer delete(start,end):删除缓冲区中的数据,包含start,不包含end。 
  21.     StringBuffer deleteCharAt(index):删除指定位置的字符。 
  22.      
  23. 3,获取。 
  24.     char charAt(int index)  
  25.     int indexOf(String str)  
  26.     int lastIndexOf(String str)  
  27.     int length()  
  28.     String substring(int start, int end)  
  29.   
  30. 4,修改。 
  31.     StringBuffer replace(start,end,string); 
  32.     void setCharAt(int index, char ch) ; 
  33.  
  34.  
  35. 5,反转。 
  36.     StringBuffer reverse(); 
  37.   
  38. 6, 
  39.     将缓冲区中指定数据存储到指定字符数组中。 
  40.     void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)  
  41.  
  42.      
  43. JDK1.5 版本之后出现了StringBuilder. 
  44.  
  45. StringBuffer是线程同步。 
  46. StringBuilder是线程不同步。 
  47.  
  48. 以后开发,建议使用StringBuilder 
  49.  
  50. 升级三个因素: 
  51. 1,提高效率。 
  52. 2,简化书写。 
  53. 3,提高安全性。 
  54.  
  55. */  
  56. class Demo  
  57. {  
  58. }  
  59.   
  60. class StringBufferDemo   
  61. {  
  62.     public static void main(String[] args)   
  63.     {  
  64.         //method_update();  
  65.   
  66.         StringBuilder sb = new StringBuilder("abcdef");  
  67.       
  68.         char[] chs = new char[6];  
  69.   
  70.   
  71.         sb.getChars(1,4,chs,1);//将  
  72.   
  73.         for(int x=0; x<chs.length; x++)  
  74.         {  
  75.             sop("chs["+x+"]="+chs[x]+";");  
  76.         }  
  77.   
  78.         draw(3,6);  
  79.         draw(8,9);  
  80.   
  81. //      StringBuilder sb1 = new StringBuilder();  
  82. //      sb1.append(new Demo()).append(new Demo());  
  83. //      sop("sb1="+sb1);  
  84.     }  
  85.     public static void method_update()  
  86.     {  
  87.         StringBuffer sb  = new StringBuffer("abcde");  
  88.   
  89. //      sb.replace(1,4,"java");  
  90.         sb.setCharAt(2,'k');  
  91.   
  92.   
  93.         sop(sb.toString());  
  94.       
  95.     }  
  96.     public static void method_del()  
  97.     {  
  98.         StringBuffer sb  = new StringBuffer("abcde");  
  99.           
  100. //      sb.delete(1,3);  
  101.         //清空缓冲区。  
  102.         //sb.delete(0,sb.length());  
  103.   
  104.         //sb.delete(2,3);  
  105.         sb.deleteCharAt(2);  
  106.   
  107.         sop(sb.toString());  
  108.     }  
  109.   
  110.     public static void method_add()  
  111.     {  
  112.         StringBuffer sb = new StringBuffer();  
  113.   
  114.   
  115.         //sb.append("abc").append(true).append(34);  
  116. //      StringBuffer sb1 = sb.append(34);  
  117. //      sop("sb==sb1:"+(sb==sb1));  
  118.   
  119.         sb.insert(1,"qq");  
  120.         sop(sb.toString());//abctrue34  
  121.         //sop(sb1.toString());  
  122.   
  123.           
  124.     }  
  125.   
  126.       
  127.     public static void sop(String str)  
  128.     {  
  129.         System.out.println(str);  
  130.     }  
  131.       
  132.     public static void draw(int row,int col)  
  133.     {  
  134.         StringBuilder sb = new StringBuilder();  
  135.         for(int x=0; x<row; x++)  
  136.         {  
  137.             for(int y=0; y<col; y++)  
  138.             {  
  139.                 sb.append("*");  
  140.             }  
  141.             sb.append("\r\n");  
  142.         }  
  143.   
  144.         sop(sb.toString());  
  145.     }  
  146.   
  147. }  


 

---------------------------------------------------------------------------------------------------------------------------------------------------------

基本数据类型对象包装类

 

 将基本数据类型封装成对象的好处在于可以在 对象中定义更多的功能方法操作该数据。

 常用的操作之一:用于基本数据类型与字符串 之间的转换。

 例:Integer的parseInt方法,intValue方法。

 例程

基本数据类型对象包装类新特性


 JDK1.5以后,简化了定义方式。

• Integer x = new Integer(4);可以直接写成

• Integer x = 4;//自动装箱。

• x = x + 5;//自动拆箱。通过intValue方法。

 需要注意:

• 在使用时,Integer x = null;上面的代码就会出 现NullPointerException。

[java]  view plain copy
  1. /* 
  2. 基本数据类型对象包装类。 
  3.  
  4. byte    Byte 
  5. short   short 
  6. int     Integer 
  7. long    Long 
  8. boolean Boolean 
  9. float   Float 
  10. double  Double 
  11. char    Character 
  12.  
  13.  
  14.  
  15. 基本数据类型对象包装类的最常见作用, 
  16. 就是用于基本数据类型和字符串类型之间做转换 
  17.  
  18. 基本数据类型转成字符串。 
  19.  
  20.     基本数据类型+"" 
  21.  
  22.     基本数据类型.toString(基本数据类型值); 
  23.  
  24.     如: Integer.toString(34);//将34整数变成"34"; 
  25.  
  26.  
  27. 字符串转成基本数据类型。 
  28.  
  29.     xxx a = Xxx.parseXxx(String); 
  30.  
  31.     int a = Integer.parseInt("123"); 
  32.  
  33.     double b = Double.parseDouble("12.23"); 
  34.  
  35.     boolean b = Boolean.parseBoolean("true"); 
  36.  
  37.     Integer i = new Integer("123"); 
  38.  
  39.     int num = i.intValue(); 
  40.  
  41.      
  42.  
  43.  
  44. 十进制转成其他进制。 
  45.     toBinaryString(); 
  46.     toHexString(); 
  47.     toOctalString(); 
  48.  
  49.  
  50. 其他进制转成十进制。 
  51.     parseInt(string,radix); 
  52.  
  53.  
  54. */  
  55. class IntegerDemo   
  56. {  
  57.     public static void sop(String str)  
  58.     {  
  59.         System.out.println(str);  
  60.     }  
  61.       
  62.     public static void main(String[] args)   
  63.     {  
  64.         //整数类型的最大值。  
  65.         //sop("int max :"+Integer.MAX_VALUE);  
  66.   
  67. //      将一个字符串转成整数。  
  68.   
  69.         int num = Integer.parseInt("123");//必须传入数字格式的字符串。  
  70.         //long x = Long.parseLong("123");  
  71.   
  72. //      sop("num="+(num+4));  
  73.   
  74. //      sop(Integer.toBinaryString(-6));  
  75. //      sop(Integer.toHexString(60));  
  76.   
  77.         int x = Integer.parseInt("3c",16);  
  78.   
  79.         sop("x="+x);  
  80.   
  81.   
  82.     }  
  83. }  



------------------------------------------------------------------------------------------------------- 

集合类

 

集合的由来
 java是一种面向对象的语言,对现实世界中的事物均以对象体现,为了方便对多个对象进行操作(对象数组的局限性)
 为了方便我们对多个对象进行操作,java是提供了一种新的容器,就是集合类(框架)
   :用于存储对象的容器
  : 该容器的长度是可变的
   :集合中存储的对象可以是任意类型的
 
集合与数组的区别:
   集合
  长度是可变的
 集合只能存储对象类型
 集合可以存储多种引用数据类型的元素
   数组
 长度是固定的
 数组可以存储对象类型,也可以存储基本数据类型
 数组存储的多个元素是同一种数据类型

  由于数据在存储的时候,数据结构不一样,所以,就会出现多种类型的集合方便我们操作。
   不管你是哪种类型的集合,都是满足一些常见的操作

集合框架的由来:(理解)
  由于多种集合类的数据结构不同,通过不断的向上抽取,形成了集合的体系结构。

  学习和使用体系结构的方式。
  学习顶层,因为顶层定义的是共性的东西。
  使用底层,因为底层是具体实现的东西。
数据结构
 组织数据的方式。
 但是,操作的方式又不一样,这个时候,就要向上抽取,最终形成一个集合体系结构

Collection接口功能: (重点,能够把数据放到集合中,然后把数据从集合中遍历出来)
 1、添加元素:
  boolean add(Object obj);//添加单个元素
  boolean addAll(Collection c);添加多个元素
 2、判断元素:
  boolean contains(Object obj);判断元素是否存在。
  boolean containsAll(Collection c);判断一个集合的元素是否包含在当前集合中
  boolean isEmpty();判断集合是否为空
 3、删除元素:
  void clear();移除所有元素。这个方法太暴力了。
  boolean remove(Object o);移除单个元素。
  boolean removeALL(Collection c);移除多个元素。
 4、获取元素:
  Iterator iterator();返回集合上的一个迭代器
 5、交集:
  boolean  retainAll(Collection c)交集
 6、集合元素的个数:
   int size();元素个数
 7、把集合转成数组
  Object[] toArray();   建议不要使用此方法进行集合的遍历
迭代器的使用:
   Iterator iterator();
         迭代器中的三个方法:
    boolean hasNext(); 判断是否还有元素
   Object next():获取元素,并且还可以自动指向下一个元素
   void remove(); 删除元素:
 原理: 每种集合的存储方式不一样,所以,它的取出方式也不一样
  但是,他们都应该有获取的功能,所以,进行了抽取
  当你遍历某种类型的集合的时候,就由该类型的集合自己去实现迭代器接口 
----------------------------------------------------------------------------------------------------------

集合操作的思路
 A:创建集合对象
 B:创建元素对象
 C:把元素添加到集合中
 D:遍历集体
  **通过集合对象获取迭代器对象
  **调用迭代器对象的hasNext()方法判断是否还有元素
  **调用迭代器对象的next()方法获取元素。

[java]  view plain copy
  1. <span style="font-size:14px;">class IteratorDemo   
  2. {  
  3.     public static void main(String[] args)   
  4.     {  
  5.         //创建集合对象  
  6.         Collection c=new ArrayList();  
  7.         //添加元素  
  8.         c.add("hello");  
  9.         c.add("world");  
  10.         c.add("itcast");  
  11.         System.out.println(c);  
  12.         //遍历  
  13.         //用数组实现的,这种不用Object[]  toArray()  
  14.         //迭代器的实现  
  15.         Iterator it=c.iterator(); //返回的是实现了迭代器接口的子类对象  
  16.         //获取元素  
  17.         while(it.hasNext())//判断是否还有元素  
  18.         {  
  19.             //  
  20.                Object obj=it.next()//可以直接由Object类的进行接收  
  21.             System.out.println(it.next()); //可以直接打印出来  
  22.   
  23.           
  24.           
  25.           
  26.         }  
  27.   
  28.     }  
  29. }</span>  
[java]  view plain copy
  1. <span style="font-size:14px;">例2:  
  2.   
  3. *  
  4.  * 集合存储自定义对象  
  5.  */  
  6. public class CollectionDemo {  
  7.     public static void main(String[] args) {  
  8.         // 创建集合对象  
  9.         Collection c = new ArrayList();  
  10.   
  11.         // 创建元素对象  
  12.         Student s1 = new Student("东方不败"20);  
  13.         Student s2 = new Student("林平之"18);  
  14.         Student s3 = new Student("岳不群"19);  
  15.   
  16.         // 添加元素  
  17.         c.add(s1);  
  18.         c.add(s2);  
  19.         c.add(s3);  
  20.   
  21.         // 遍历元素  
  22.         // 通过集合对象获取迭代器对象  
  23.         Iterator it = c.iterator();  
  24.         // 通过hasNext()方法判断  
  25.         while (it.hasNext()) {  
  26.             // 通过next()方获取元素  
  27.             // System.out.println(it.next().toString());  
  28.             Student s = (Student) it.next();  
  29.             // System.out.println(s);  
  30.             System.out.println(s.getName() + "***" + s.getAge());  
  31.         }  
  32.     }  
  33. }</span>  


-----------------------List------------------------------------------------------------------------------
Collection 
 |----List
  元素有序(存入顺序和取出顺序一致),元素可以重复

 |---Set
  元素是无序,元素要求唯一
List接口的功能
 1、添加元素
  void add(int index,Object obj);指定位置添加指定元素
 2、获取元素:
  Object get(int index):根据指定索引获取元素
 3、列表迭代器
  ListIterator  listIterator();
 4、删除元素:
  Object remove(int index);删除指定位置的元素
 5、修改元素:
  Object set(int index,Object element);修改指定位置的元素
size()方法,它可以获取集合的元素个数。
---------------------------------------------------------------------------------------------------------

[java]  view plain copy
  1. <span style="font-size:14px;">例:get方法可以根据指定的索引获取单个元素  
  2.    那么List体系的集合就多了一种遍历方式:  
  3.   我们想到了size()方法,它可以获取集合的元素个数  
  4. 这样的话,我们就可以从0开始获取每个元素的索引  
  5.  public class ListDemo2  
  6. {  
  7.   //创建集合对象  
  8. List list=new new ArrayList();  
  9.   //添加元素  
  10.      list.add();  
  11. //遍历  
  12.   for(int x=0;x<list.size();x++)  
  13. {  
  14.        //Stirng s=(String)lis.get(x);  
  15.      System.out.println(list.get(x));  
  16.   
  17. }  
  18. // 这种方法效率不高,可以优化  
  19. // list.size()每次循环,都去调用了方法计算集合的元素个数  
  20. // 如果元素过多,这种方式不好  
  21.   
  22. // int length = list.size();  
  23. // for (int x = 0; x < length; x++) {  
  24. // String s = (String) list.get(x);  
  25. // System.out.println(s);  
  26. // }  
  27.   
  28. 在集合元素比较多的时候 可以使用此方法  
  29.   
  30. }</span>  

list迭代器的使用

 Iterator
 hasNext()//判断是否有下一个元素
 next(); //读取下一个元素
----ListIterator  listIterator();列表迭代器遍历集合元素
    有自己的特殊功能,可以实现在逆向遍历
 1、Object previous();  //读取一个元素
  2、boolean hasPrevious();//判断是否有下一个元素

[java]  view plain copy
  1. <span style="font-size:14px;">例1:  
  2.    Iterator it=it.iterator();  
  3.    while(lit.hasPrevious())  
  4. {  
  5.   
  6.     String s=(String)lit.previous();  
  7.      System.out.println(s);  
  8.       
  9. }  
  10.   
  11.   
  12. 2:  
  13.   
  14.  * 要查找集合中有没有是zhangsan这个字符串。  
  15.  * 如果有,则在添加一个lisi进去。  
  16.  *   
  17.  * Exception in thread "main" java.util.ConcurrentModificationException:并发修改异常  
  18.  * 在使用迭代器迭代元素的时候,不能使用集合去操作元素,否则,就会出现并发修改异常。  
  19.  * 那么,请问如何解决这个问题,并能够让元素添加成功:  
  20.  * 1:在迭代器迭代的过程中,使用迭代器对象去添加元素。  
  21.  * 2:不用迭代器遍历,用普通for循环遍历,用集合添加元素  
  22.  */  
  23. public class ListDemo4 {  
  24.     public static void main(String[] args) {  
  25.         // 创建集合对象  
  26.         List list = new ArrayList();  
  27.   
  28.         list.add("zhaoliu");  
  29.         list.add("zhangsan");  
  30.         list.add("wangwu");  
  31.   
  32.         // 请问如何实现我的需求  
  33.           
  34.         ListIterator lit = list.listIterator();  
  35.         while (lit.hasNext()) {  
  36.             String s = (String) lit.next();  
  37.             // 判断  
  38.             if ("zhangsan".equals(s)) {  
  39.                 lit.add("lisi");  //只能使用迭代器进行数据的添加  
  40.                 // list.add("lisi");//用集合对象添加元素会出现并发异常  
  41.             }  
  42.         }  
  43.         /* 
  44.         //用普通for循环 
  45.         for(int x=0; x<list.size();x++){ 
  46.             String s = (String)list.get(x); 
  47.             if("zhangsan".equals(s)){ 
  48.                 list.add("lisi"); 
  49.             } 
  50.         } 
  51.         */  
  52.   
  53.         System.out.println("list:" + list);  
  54.     }  
  55. }</span>  


-----------------------List集合的使用-------------------------------------------------------------
list的儿子的特点:
        |---ArrayList
  底层数据结构是数组,查询快,增删慢
  线程不安全,效率高
 |---Vector
  底层数据结构是数组,查询快,增删慢
  线程安全,效率低
 |---LinkedList
  底层数据结构是链表,查询慢,增删快
  线程不安全,效率高
使用总结:
 我们开发中到底使用哪个子类呢
   是否考虑线程安全问题 
    考虑:
  使用Vector
   不考虑:
  使用ArrayList 或者LinkedList
   如果查询多,增删少,用ArrayList
   如果查询少,增删少,用LinkedList
  如果你还是不知道 ,用ArrayList
 
 
 // 方式3
  //注意:如果使用列表迭代器,我们虽然说了它可以逆序遍历。
  //但前提是先正向遍历到结尾了。然后才能逆序遍历。
  ListIterator lit = array.listIterator();
  while (lit.hasPrevious()) {
  String s = (String) lit.previous();
   System.out.println(s);  
Vector的特殊方法:
 1:添加元素
 *  void addElement(Object obj) -- JDK1.2 后改为了 add(Object obj)
2: 获取元素
 *  Object elementAt(int index) -- JDK1.2后就改为了 get(int index)
3:遍历元素
   Enumeration elements() -- JDK1.2后就改为了 Iterator iterator()
   boolean hasMoreElements() --   JDK1.2后就改为了 boolean hasNext()
  Object nextElement() -- JDK1.2后就改为了 Object next()

 

LinkedList的特殊方法:
  1:添加元素
    void addFirst(Object obj)
    void addLast(Object obj)
 
   2:删除元素
     Object removeFirst()
   Object removeLast()

   3:获取元素
   Object getFirst()
  
    Object getLast()

例:
public class LinkedListDemo {
 public static void main(String[] args) {
  // 创建集合对象
  LinkedList link = new LinkedList();

  // 添加元素
  link.add("hello");
  link.add("world");
  // 特殊添加方法
  link.addFirst("itcast");
  // 和add方法一样
  link.addLast("over");
  link.add("java");

  // 删除元素
  // System.out.println("removeFirst:" + link.removeFirst());
  // // NoSuchElementException
  // System.out.println("removeLast:" + link.removeLast());

  // 获取元素
  System.out.println("getFirst:" + link.getFirst());
  System.out.println("getLast:" + link.getLast());

  // 遍历
  Iterator it = link.iterator();
  while (it.hasNext()) {
   String s = (String) it.next();
   System.out.println(s);
  }
 }
}

---------------------------Set集合----------------------------------------------------------------
1:Set(掌握)
 (1)Set集合的特点:元素无序,唯一(掌握)
 (2)Set的体系结构(掌握):默认是按照字典顺序排列。
  Set
   |--HashSet
    底层数据结构是哈希表。
    
首先判断哈希值是否相同:
不同:就把元素添加到集合中。
相同:继续进入equals方法比较
返回true,说明元素重复,不存。
返回false,就把元素添加到集合中

[java]  view plain copy
  1. <span style="font-size:14px;">如何保证元素的唯一性呢?  
  2.     它依赖两个方法:hashCode()和equals()  
  3.     @Override                         
  4.     public int hashCode() {  
  5.         // return 10;  
  6.         // 把所有成员(引用类型,基本类型)引用类型的哈希值+基本类型的值返回即可  
  7.         return this.name.hashCode() + this.age * 17;  
  8.     }  
  9.   
  10.     @Override  
  11.     public boolean equals(Object obj) {  
  12.         // System.out.println(this + "***" + obj);  
  13.         if (this == obj) {  
  14.             return true;  
  15.         }  
  16.         if (!(obj instanceof Person)) {  
  17.             return false;  
  18.         }  
  19.   
  20.         Person p = (Person) obj;  
  21.         return this.name.equals(p.name) && this.age == p.age;  
  22.     }</span>  


|--TreeSet
 底层数据结构是二叉树。
 可以让集合中的元素排序。
 如何保证元素的唯一性的呢?
 它是根据比较返回的值是0,说明元素是重复的,就不添加。
有两种实现方案:

[java]  view plain copy
  1. <span style="font-size:14px;">A:让自定义对象具备比较性  
  2.     实现Comparable接口  
  3.     public class Person implements Comparable<Person> {  
  4.     @Override  
  5.     public int compareTo(Person p) {  
  6.         // 成员属性相同的元素为同一对象。我想让元素按照年龄从大到小排序。  
  7.         // this对象,p对象  
  8.         // return p.age - this.age;  
  9.         // 排序的时候,一定要分清楚主次要条件  
  10.         int num = p.age - this.age;  
  11.         // // 当年龄相同的时候,你还得比较姓名是否相同  
  12.         int num2 = (num == 0) ? this.name.compareTo(p.name) : num;  
  13.         return num2;  
  14.         // return -1;  
  15.     }  
  16. B:让集合具备比较性  
  17.     实现Comparator接口  
  18.   
  19.     public class MyComparator implements Comparator<Person> {  
  20.   
  21.     @Override  
  22.     public int compare(Person p1, Person p2) {  
  23.         // return 0;  
  24.         // 我按照年龄从小到大的顺序比较  
  25.         int num = p1.getAge() - p2.getAge();  
  26.         int num2 = (num == 0) ? p1.getName().compareTo(p2.getName()) : num;  
  27.         return num2;  
  28.     }  
  29.   
  30. }</span>  
[java]  view plain copy
  1. <span style="font-size:14px;">例如:                 
  2. 需求:我认为成员属性相同对象即为同一个对象。  
  3.  *   
  4.  * 我们重写了equals方法,发现没有达到效果。  
  5.  * 通过测试,发现根本没有执行equals方法。  
  6.  * 那么,问题出现在了什么地方呢?  
  7.  * 通过思考,我们估计问题是出现在了add方法上。  
  8.  * 所以,我们要研究add方法的源码。  
  9.  * 通过查看源码,我们发现这个add方法和hashCode()及equals()有关。  
  10.  * 而且是当哈希值相同的时候,采取执行equals方法。  
  11.  *   
  12.  * HashSet是如何保证元素的唯一性的呢?  
  13.  *      底层数据结构是哈希表。  
  14.  *      哈希表依赖的是哈希值存储数据的。  
  15.  *      这个集合首先会根据hashCode方法去判断哈希值是否相同,  
  16.  *      如果不同,则认为是不同的元素,就添加到集合中。  
  17.  *      如果相同,就会走equals方法,这样就可以实现根据自己的需求进行比较。  
  18.  *      如果返回值是true,说明该元素在集合中存在,就不添加。  
  19.  *      如果返回值是false,直接添加元素。  
  20.  */  
  21. public class HashSetDemo {  
  22.     public static void main(String[] args) {  
  23.         // 创建集合对象  
  24.         HashSet<Person> hs = new HashSet<Person>();  
  25.   
  26.         // 创建元素对象  
  27.         Person p1 = new Person("林青霞"25);  
  28.         Person p2 = new Person("张曼玉"28);  
  29.   
  30.         // 添加元素  
  31.         hs.add(p1);  
  32.         hs.add(p2);  
  33.           
  34.   
  35.         // 遍历  
  36.         Iterator<Person> it = hs.iterator();  
  37.         while (it.hasNext()) {  
  38.             Person p = it.next();  
  39.             System.out.println(p.getName() + "***" + p.getAge());  
  40.         }  
  41.     }  
  42. }  
  43.   
  44.   
  45. 例如:  
  46. 我们的TreeSet集合是用于保证元素排序和唯一的。  
  47.  * 而我们现在的这种操作,并没有让集合中的元素进行排序。  
  48.  * 通过运行时期的异常,我们可以知道解决  
  49.  * 方案1:让自定义对象实现Comparable接口  
  50.  public int compareTo(Person p) {  
  51.         // 小-大 (this - p)  
  52.         // 大-小(p - this)  
  53.         // 按照姓名的从短到长,年龄从大到小顺序排序,并去掉重复元素(姓名和年龄相同即为重复元素)。  
  54.         // 谁调用this代表谁  
  55.         int num = this.name.length() - p.name.length();  
  56.         int num2 = (num == 0) ? (p.age - this.age) : num;  
  57.         // 追加条件,这个条件是需要我们自己思考的  
  58.         int num3 = (num2 == 0) ? (this.name.compareTo(p.name)) : num2;  
  59.         return num3;  
  60.     }</span>  


 

[java]  view plain copy
  1. <span style="font-size:14px;">方案2:让集合具备比较性  
  2.  *          使用TreeSet带比较器的构造方法  
  3.               
  4.  *   
  5.  * 当Person类具备比较性的时候,是指Person类实现Comparable接口  
  6.  * 集合也具备比较性的时候,是指TreeSet接受了实现Comparator接口的子类对象  
  7.  * 以集合具备比较性为主。这个时候,也就是说自定义对象没有必要再去实现比较性的接口。  
  8.  *   
  9.  * TreeMap -- put  
  10.  *   
  11.  * 需求:成员属性相同的元素为同一对象。我想让元素按照年龄从大到小排序。  
  12.  *     
  13.  * TreeSet保证元素唯一性的原理?  
  14.  *      根据比较方法返回的值是否是0来确定该元素是否是重复元素。  
  15.  *   
  16.  * 在用TreeSet保证元素唯一的时候,我们还得考虑元素的排序。  
  17.  * 而排序的时候,  
  18.     一定要注意排序的主次要条件。  
  19. public class TreeSetDemo3 {  
  20.     public static void main(String[] args) {  
  21.         // 创建集合对象  
  22.         // 以后注意,如果一个方法的参数是一个接口类型的  
  23.         // 那么,你肯定传递的是一个实现了接口的子类对象  
  24.         // 匿名对象的使用  
  25.         TreeSet<Person> ts = new TreeSet<Person>(new MyComparator());  
  26.         // 创建元素对象  
  27.         Person p1 = new Person("陆毅"30);  
  28.         // 添加元素  
  29.         ts.add(p1);  
  30.         // 遍历元素  
  31.         Iterator<Person> it = ts.iterator();  
  32.         while (it.hasNext()) {  
  33.             Person p = it.next();  
  34.             System.out.println(p.getName() + "***" + p.getAge());  
  35.         }  
  36.     }  
  37. }  
  38.   
  39.   
  40. 如果两种情况都存在,以B为主。  
  41.   
  42.     (4)LinkedHashSet(了解)  
  43.         底层数据结构是由哈希表和链表组成。  
  44.         特点:  
  45.             有序,唯一</span>  

-----------------------------Map(掌握)------------------------------------------------------------
 (1)Map:存储的是键值对形式的数据的集合。(了解)
 (2)Map的特点:(了解)
  数据是以键值对形式存在
  键不能是重复的
  值可以重复
 (3)Map接口的功能:(掌握)
  A:添加元素
   V put(K key,V value)
  B:判断元素
   boolean containsKey(K key)
   boolean containsValue(V value)
   boolean isEmpty()
  C:删除元素
   V remove(K key)
  D:长度
   int size()
  E:获取
   V get(k key)
   Set<K> keySet()
   Collection<V> values()
   Set<Map.Entry<K,V>> entrySet()
 (4)Map案例:(掌握)
  Map存储字符串并遍历:
   
   Map<String,String> map = new HashMap<String,String>();

   map.put("it001","zhangsan");
   map.put("it002","lisi");
   map.put("it003","wangwu");

   //遍历
   //方式1:丈夫找妻子
   Set<String> set = map.keySet();
   for(String key : set)
   {
    String value = map.get(key);
    System.out.println(key+"***"+value);
   }
    
   //方式2:通过结婚证找丈夫和妻子
   Set<Map.Entry<String,String>> entrySet = map.entrySet();
   for(Map.Entry<String,String> me : entrySet)
   {
    String key = me.getkey();
    String value = me.getValue();
    System.out.println(key+"***"+value);
   }

  Map存储自定义对象并遍历:(自己补齐)
   键是字符串
   值是学生对象
 (5)Map的体系结构(掌握)
  Map:(Map体系的数据结构对键有效,跟值无关)
   |--HashMap
    底层数据结构是哈希表。
    如何保证键的唯一性呢?
    依赖hashCode()和equals()方法
    线程不安全,效率高。允许null键和值。
   |--Hashtable
    底层数据结构是哈希表。
    如何保证键的唯一性呢?
    依赖hashCode()和equals()方法
    线程安全,效率低。不允许null键和值。
   |--TreeMap
    底层数据结构是二叉树。
    如何保证键的唯一性呢?
    两种方式:
     自定义元素具备比较性
     集合具备比较性
    线程不安全,效率高。允许null值,不允许null键。
   
   那么,我们一般使用谁?
   如果有排序需求,用TreeMap,否则全部使用HashMap。
 (6)案例:
  统计字符串中每个字符出现的次数(掌握)
  czbk集合的数据存储和遍历(理解)

2:总结集合的使用规律:
 是否是键值对形式:
  是:Map体系
   是否需要排序:
    是:TreeMap
    不是:HashMap
    不知道:HashMap

  不是:Collection体系
   是否要保证元素唯一:
    是:Set
     是否要排序:
      是:TreeSet
      不是:HashSet
      不知道:HashSet
    不是:List
     查询多:ArrayList
     增删多:LinkedList
     不知道:ArrayList    
3:遍历方式
 Collection:
  List:
   普通for
   增强for
   //迭代器
  Set:
   增强for
   //迭代器
 Map:没有直接遍历方式,需要通过转换。
  方式1:丈夫找妻子
  //方式2:通过结婚证找丈夫和妻子

4:集合的底层数据结构规律:
 ArrayXxx:底层数据结构是数组,查询快,增删慢。
 LinkXxx:底层数据结构是链表,查询慢,增删快。
 HashXxx:底层数据结构是哈希表。
  依赖hashCode()方法和equals()方法
 TreeXxx:底层数据结构是二叉树
  两种方式实现排序:
   自定义元素具备比较性
   集合具备比较性
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值