javaday12

目录

Day12--集合+泛型... 1

1       List接口... 1

1.1        概述... 1

1.2        特点... 1

1.3        常用方法... 1

1.4        练习1:测试常用方法... 3

2       ArrayList. 3

2.1        概述... 3

2.2        创建对象... 3

2.3        练习1:测试常用方法... 3

3       LinkedList. 4

3.1        概述... 4

3.2        创建对象... 4

3.3        常用方法... 4

3.4        练习1:测试常用方法... 4

4       Set接口... 5

4.1        概述... 5

4.2        特点... 5

4.3        常用方法... 5

4.4        练习1:测试常用方法... 5

5       HashSet. 5

5.1        概述... 5

5.2        练习1:测试常用方法... 6

6       Map接口... 6

6.1        概述... 6

6.2        特点... 6

6.3        继承结构... 7

6.4        常用方法... 7

6.5        练习1:测试常用方法... 7

7       HashMap.. 8

7.1        概述... 8

7.2        练习1:获取HashMap的数据... 8

7.3        练习2:字符串中的字符统计... 9

8       扩展... 9

8.1        了解栈和队列... 9

8.2................................................................................. Set存储属性相同的对象... 9

 

Day12--集合+泛型

1   List接口

1.1     概述

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

1.2     特点

1、 数据有序

2、 允许存放重复元素

1.3     常用方法

ListIterator<E> listIterator()

          返回此列表元素的列表迭代器(按适当顺序)。

 ListIterator<E> listIterator(int index)

          返回列表中元素的列表迭代器(按适当顺序),从列表的指定位置开始。

 void add(int index, E element)

          在列表的指定位置插入指定元素(可选操作)。

 boolean addAll(int index, Collection<? extends E> c)

          将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。

 List<E> subList(int fromIndex, int toIndex)

     返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。

E get(int index)

          返回列表中指定位置的元素。  

1.4     练习1:测试常用方法

package cn.tedu.collection;

 

import java.util.ArrayList;

import java.util.List;

import java.util.ListIterator;

 

//测试List接口

public class Test7_List {

 

    public static void main(String[] args) {

       //1、创建对象

       //List是接口

       List<Integer> list = new ArrayList<>();

      

       //2、常用方法

       list.add(100);

       list.add(101);

       list.add(102);

       list.add(103);

       list.add(102);

       list.add(105);

      

       System.out.println(list);

      

//     list.clear();

       System.out.println(list.contains(100));

       System.out.println(list.equals(101));

       System.out.println(list.hashCode() );

       System.out.println( list.isEmpty() );

       System.out.println(list.remove(2) );

       System.out.println(list.size() );

       System.out.println(list.toArray() );

      

       //特有方法

       System.out.println(list+"======");

       System.out.println( list.indexOf(105) );

       System.out.println(list.lastIndexOf(102) );

       list.add(3,105);

       System.out.println(list);

       System.out.println(list.get(3));

       System.out.println(list.set(0,99));

       System.out.println(list);

       System.out.println(list.subList(2, 4));//含头不含尾,类似于String.subString()

       System.out.println(list);

      

       //遍历集合中元素

       //ListIterator继承了Iterator,并提供了更加完善的功能,除了正常向后遍历还增加了向前遍历的功能

       ListIterator it = list.listIterator();

       while(it.hasNext()) {

           Object obj = it.next();

           System.out.println(obj);

       }

      

       //TODO 子接口提供的遍历方式-如:向前遍历

    }

}

 

 

2   ArrayList

2.1     概述

1)     存在于java.util包中。

2)     内部用数组存放数据,封装了数组的操作,每个对象都有下标。

3)     内部数组默认初始容量是10。如果不够会以1.5倍容量增长。

4)     查询快,增删数据效率会降低。

 

 

2.2     创建对象

ArrayList()

          构造一个初始容量为 10 的空列表。

ArrayList(int initialCapacity)

          构造一个具有指定初始容量的空列表。

2.3     练习1:测试常用方法

创建day12工程

创建cn.tedu.arraylist包

创建Test1_ArrayList.java

下标遍历,迭代器遍历

package cn.tedu.arraylist;

 

import java.util.ArrayList;

import java.util.Iterator;

 

//测试ArrayList常见方法

//总结:

//1, ArrayList 底层就是个数组的结构,数据默认初始容量是10

//2, ArrayList 元素都有下标 , 元素可重复 , 元素有序

//3, 遍历元素时可以使用 迭代器遍历 ,普通for循环遍历 ,增强for循环/foreach结构

//4, 默认的扩容方式是原来的1.5倍: int newCapacity = oldCapacity + (oldCapacity >> 1);

public class Test1_ArrayList {

      

       public static void main(String[] args) {

              //1、创建ArrayList对象

              //特点1:底层维护了Object[] , 初始容量是10

              ArrayList<String> list = new ArrayList<>();

             

              //2、常用方法

              //特点2:元素都有索引  + 元素可重复  + 有序数据

              list.add("张三");

              list.add("李四");

              list.add("如花");

              list.add("石榴姐");

              list.add("李四");

              list.add("张三");

             

              System.out.println(list);

             

              //遍历元素

              //用迭代器遍历

              Iterator it = list.iterator();

              while(it.hasNext()) {//判断,有元素的话返回true,去获取值

                     Object obj = it.next();

                     String str = (String) obj;

                     System.out.println(str);

              }

             

              System.out.println();

             

              //用下标遍历

              //list.size()  --  集合的长度(元素的个数)

              for(int i = 0 ; i < list.size() ; i++ ) {

                     //list.get(i)  -- 根据下标获取存着的Object对象

                     String str = list.get(i);

                     System.out.println(str);

              }

             

              System.out.println();

             

              //优化后的for循环--foreach结构

              //1  2  : 3,其中3是要遍历的数据   1是数据得到类型   2是数据的名字

              for(String  s : list) {

                     System.out.println(s);

              }

             

             

       }

      

}

3   LinkedList

3.1     概述

双向链表,两端效率高。底层就是数组和链表实现的。

 

3.2     创建对象

LinkedList()

          构造一个空列表。

3.3     常用方法

addFirst()  addLast()

getFirst()  getLast()

removeFirst()  removeLast()

void addFirst(E e)

          将指定元素插入此列表的开头。

 void addLast(E e)

          将指定元素添加到此列表的结尾。

 E getFirst()

          返回此列表的第一个元素。

 E getLast()

          返回此列表的最后一个元素。

boolean offer(E e)

          将指定元素添加到此列表的末尾(最后一个元素)。

 boolean offerFirst(E e)

          在此列表的开头插入指定的元素。

 boolean offerLast(E e)

          在此列表末尾插入指定的元素。

 E peek()

          获取但不移除此列表的头(第一个元素)。

 E peekFirst()

          获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。

 E peekLast()

          获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。

 E poll()

          获取并移除此列表的头(第一个元素)

 E pollFirst()

          获取并移除此列表的第一个元素;如果此列表为空,则返回 null。

 E pollLast()

          获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。

       E pop()

          从此列表所表示的堆栈处弹出一个元素。

 void push(E e)

          将元素推入此列表所表示的堆栈。         

 E removeFirst()

          移除并返回此列表的第一个元素。

 E removeLast()

          移除并返回此列表的最后一个元素。

    

3.4     练习1:测试常用方法

双向链表:下标遍历效率低,迭代器遍历效率高

package cn.tedu.arraylist;

 

import java.util.Iterator;

import java.util.LinkedList;

 

//测试LinkedList用法

//总结:

//1, 底层的数据结构是数组+链表

//2, 链表结构适合增加或者删除,并不适合查询

//3, 链表结构遍历元素推荐使用迭代器遍历,效率高!!!

public class Test2_LinkedList {

    public static void main(String[] args) {

       //1,创建对象

       LinkedList<String> list = new LinkedList<String>();

      

       //2,常用方法

       list.add("钢铁侠");

       list.add("美队");

       list.add("蜘蛛侠");

       list.add("灭霸");

      

       System.out.println(list);

      

//     //特有方法:

//     //特点1:首尾元素效率高

       list.addFirst("0");//添加

       list.addLast("99");

       System.out.println(list);

       System.out.println(list.getFirst());//获取

       System.out.println(list.getLast());

//    

       System.out.println(list.removeFirst());//移除

       System.out.println(list.removeLast());

       System.out.println(list);

      

      

       //遍历元素

       //用迭代器遍历 : 效率高!!!

       Iterator it = list.iterator();

       while(it.hasNext()) {

           Object obj = it.next();

           System.out.println(obj);

       }

      

       //用下标遍历:效率低!!!

       for(int i=0 ; i<list.size() ; i++) {

           System.out.println(list.get(i));

       }

      

       //增强for

       for(String s : list) {

           System.out.println(s);

       }

      

      

    }

   

}

 

4   Set接口

4.1     概述

一个不包含重复元素的 collection。

数据无序(因为set集合没有下标)。

由于集合中的元素不可以重复。常用于给数据去重。

4.2     特点

1、 数据不允许重复

2、 数据无序

3、 HashSet:底层是哈希表

4、 TreeSet:底层是TreeMap,也是红黑树的形式,便于查找数据。

4.3     常用方法

同Collection接口

4.4     练习1:测试常用方法

package cn.tedu.set;

 

import java.util.HashSet;

import java.util.Set;

 

//测试Set接口

public class Test3_Set {

       public static void main(String[] args) {

              //1,创建对象

              Set<String> s = new HashSet<>();

             

              //2,常用方法

              //同Collection接口,查字典使用

             

       }

}

5   HashSet

5.1     概述

底层是哈希表,包装了HashMap,相当于向HashSet中存入数据时,会把数据作为K,存入内部的HashMap中。其中,K不许重复。此类允许使用 null 元素。

 

5.2     练习1:测试常用方法

HashSet()

          构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。

 

package cn.tedu.set;

 

import java.util.HashSet;

import java.util.Iterator;

 

//测试HashSet使用

//特点1:元素无序  +  元素不可重复

//特点2:底层使用了HashMap来封装数据,默认的容量大小是16

//如果容量不够,会自动扩容,默认的扩容因子是增加0.75的容量

//default initial capacity (16) and load factor (0.75)

public class Test4_HashSet {

 

    public static void main(String[] args) {

       //1,创建对象

       HashSet<String> set = new HashSet<>();

      

       //2,常用方法

       set.add("熊大");

       set.add("熊二");

       set.add("光头强");

       set.add("熊大");

       set.add("熊二");

      

       //特点 : 元素无序     +  元素不可重复  

       System.out.println(set);

 

       //遍历set集合的元素

//     Iterator<E> iterator()  返回对此 set 中元素进行迭代的迭代器。

       Iterator it = set.iterator();

       while( it.hasNext() ) {

           Object obj = it.next();

           System.out.println(obj);

       }

      

    }

   

}

6   Map接口

6.1     概述

java.util接口 Map<K,V>

类型参数: K - 此映射所维护的键的类型V - 映射值的类型。

也叫哈希表、散列表。常用于存 键值对 结构的数据。其中的键不能重复,值可以重复.

 

6.2     特点

1、 可以根据键 提取对应的值 Object value = get(key)

2、 键不允许重复,如果重复值会被覆盖

3、 存放的都是无序数据

4、 初始容量是16,默认的加载因子是0.75

 

6.3     继承结构

 

6.4     常用方法

void clear()

          从此映射中移除所有映射关系(可选操作)。

 boolean containsKey(Object key)

          如果此映射包含指定键的映射关系,则返回 true。

 boolean containsValue(Object value)

          如果此映射将一个或多个键映射到指定值,则返回 true。

 Set<Map.Entry<K,V>> entrySet()

          返回此映射中包含的映射关系的 Set 视图。

 boolean equals(Object o)

          比较指定的对象与此映射是否相等。

 V get(Object key)

          返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。

 int hashCode()

          返回此映射的哈希码值。

 boolean isEmpty()

          如果此映射未包含键-值映射关系,则返回 true。

 Set<K> keySet()

          返回此映射中包含的键的 Set 视图。

 V put(K key, V value)

          将指定的值与此映射中的指定键关联(可选操作)。

 void putAll(Map<? extends K,? extends V> m)

          从指定映射中将所有映射关系复制到此映射中(可选操作)。

 V remove(Object key)

          如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。

 int size()

          返回此映射中的键-值映射关系数。

 Collection<V> values()

          返回此映射中包含的值的 Collection 视图。

6.5     练习1:测试常用方法

package cn.tedu.map;

 

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

//测试map接口的用法

public class Test5_Map {

      

       public static void main(String[] args) {

              //1,创建对象

              Map<Integer,String> map = new HashMap<>();

             

              //2,常用方法

              //特点1, map中存放的都是有映射关系的数据,key=value

              map.put(9528,"如花");

              map.put(9527,"唐伯虎");//存数据

              //{9527=唐伯虎, 9528=如花}

              System.out.println(map);

             

              //特点2, map中元素的key不可以重复,如果发生了重复的key,这时value会被覆盖

              //{9527=唐伯虎, 9528=秋香姐}

              map.put(9528,"秋香姐");

              System.out.println(map);

             

              //特点3, 数据无序

              map.put(9000,"渣渣辉");

              //{9527=唐伯虎, 9528=秋香姐, 9000=渣渣辉} 与存放顺序不一致

              System.out.println(map);

             

              //特点4, 允许存放null键和null值

              map.put(null,null);

              System.out.println(map);

             

              //常用方法

              System.out.println( map.containsKey(9528) );

              System.out.println( map.containsValue("渣渣辉") );

              System.out.println( map.get(9527) );

              System.out.println( map.hashCode() );

              System.out.println( map.isEmpty() );

              System.out.println( map.remove(9528)  );

              System.out.println( map.size() );

             

              //遍历map中的元素:map转set

              //方式1, keySet()  --

              //a, 把map中的key取出来存入set  --  [null,9527,9000,9528]

              Set<Integer> set = map.keySet();

              //b, 遍历set集合

              Iterator it = set.iterator();

              while( it.hasNext() ) {//判断有元素就获取

                     //c,  分别获取set中存着的每个key值

                     Integer key = (Integer) it.next();

                    

                     //d,  拿着key去map中找映射着的value值

                     String value = map.get(key);

                    

                     System.out.println(key+"映射的值是:"+value);

              }

             

              //遍历map中的元素:map转set

              //方式2:Set<Map.Entry<K,V>> entrySet() --

              //a, 把map的映射关系形成Entry对象,多个Entry对象放入set集合

              Set<Entry<Integer, String>> set2 = map.entrySet();

             

              //b, 遍历set

              Iterator<Entry<Integer, String>> it2 = set2.iterator();

              while( it2.hasNext() ) {

                     //c, 获取每个Entry对象

                     Entry<Integer, String> entry = it2.next();

                    

                     //d, 分别获取Entry对象封装的K和V

                     Integer key = entry.getKey();

                     String value = entry.getValue();

                    

                     System.out.println(key+"对应的值:"+value);

              }

             

       }

      

      

}

7   HashMap

  • HashMap的键要同时重写hashCode()和equals()

hashCode()用来判断确定hash值是否相同

equals()用来判断属性的值是否相同

-- equals()判断数据如果相等,hashCode()必须相同

-- equals()判断数据如果不等,hashCode()尽量不同

7.1     概述

HashMap底层是一个Entry数组,当存放数据时会根据hash算法计算数据的存放位置。

算法:hash(key)%n,n就是数组的长度。

当计算的位置没有数据时,就直接存放

当计算的位置有数据时也就是发生hash冲突/hash碰撞时,采用链表的方式来解决的,在对应的数组位置存放链表的头结点。对链表而言,新加入的节点会从头结点加入。

 

7.2     练习1:获取HashMap的数据

package cn.tedu.map;

 

import java.util.HashMap;

import java.util.Iterator;

import java.util.Map;

import java.util.Map.Entry;

import java.util.Set;

 

//测试map接口的用法

public class Test5_Map {

      

       public static void main(String[] args) {

              //1,创建对象

              Map<Integer,String> map = new HashMap<>();

             

              //2,常用方法

              //特点1, map中存放的都是有映射关系的数据,key=value

              map.put(9528,"如花");

              map.put(9527,"唐伯虎");//存数据

              //{9527=唐伯虎, 9528=如花}

              System.out.println(map);

             

              //特点2, map中元素的key不可以重复,如果发生了重复的key,这时value会被覆盖

              //{9527=唐伯虎, 9528=秋香姐}

              map.put(9528,"秋香姐");

              System.out.println(map);

             

              //特点3, 数据无序

              map.put(9000,"渣渣辉");

              //{9527=唐伯虎, 9528=秋香姐, 9000=渣渣辉} 与存放顺序不一致

              System.out.println(map);

             

              //特点4, 允许存放null键和null值

              map.put(null,null);

              System.out.println(map);

             

              //常用方法

              System.out.println( map.containsKey(9528) );

              System.out.println( map.containsValue("渣渣辉") );

              System.out.println( map.get(9527) );

              System.out.println( map.hashCode() );

              System.out.println( map.isEmpty() );

              System.out.println( map.remove(9528)  );

              System.out.println( map.size() );

             

              //遍历map中的元素:map转set

              //方式1, keySet()  --

              //a, 把map中的key取出来存入set  --  [null,9527,9000,9528]

              Set<Integer> set = map.keySet();

              //b, 遍历set集合

              Iterator it = set.iterator();

              while( it.hasNext() ) {//判断有元素就获取

                     //c,  分别获取set中存着的每个key值

                     Integer key = (Integer) it.next();

                    

                     //d,  拿着key去map中找映射着的value值

                     String value = map.get(key);

                    

                     System.out.println(key+"映射的值是:"+value);

              }

             

              //遍历map中的元素:map转set

              //方式2:Set<Map.Entry<K,V>> entrySet() --

              //a, 把map的映射关系形成Entry对象,多个Entry对象放入set集合

              Set<Entry<Integer, String>> set2 = map.entrySet();

             

              //b, 遍历set

              Iterator<Entry<Integer, String>> it2 = set2.iterator();

              while( it2.hasNext() ) {

                     //c, 获取每个Entry对象

                     Entry<Integer, String> entry = it2.next();

                    

                     //d, 分别获取Entry对象封装的K和V

                     Integer key = entry.getKey();

                     String value = entry.getValue();

                    

                     System.out.println(key+"对应的值:"+value);

              }

             

       }

      

      

}

 

7.3     练习2:字符串中的字符统计

接收用户输入的一串字符串,统计出现的每个字符的个数

a=1 b=2 c=3

package cn.tedu.map;

 

import java.util.HashMap;

import java.util.Map;

import java.util.Scanner;

 

//统计字符出现的次数

public class Test6_Count {

       public static void main(String[] args) {

              //1, 接收键盘输入字符串

              String input = new Scanner(System.in).nextLine();

             

              //2, 遍历字符串

              //创建map -- {a=3,b=2,c=1}

              Map<Character,Integer> map = new HashMap<>();

             

              for(int i = 0 ; i < input.length() ; i++) {

                     //3, 获取到每个字符

                     char key = input.charAt(i);

                    

                     //4, 拿着key去map里查

                     Integer value = map.get(key);

                    

                     //5, 如果没有存过(也就是默认值null的话),就存1

                     if( value == null) {

                            map.put(key, 1);

                     }else {

                            //6, 如果存过,就在原有value基础+1

                            map.put(key, value+1);

                     }

              }

             

              System.out.println(map);

             

       }

}

 

8   扩展

8.1  了解栈Stack和队列Queue

8.2  Set存储属性相同的对象

需求:我们假设相同属性的两个人是同一个人

1、按照以前的经验,这种需求只需要重写equals()方法就可以实现。

2、但是我们提供以后,equals()根本就没有执行。问题出现在新增功能。

3、查找新增的源码发现,其实在添加时只是计算对象的hash值。

4、由于每次创建对象时hash值都不一样,所以每次都会当做新对象存起来。

5、所以,现在我们必须保证两个对象的hash值相同,重写hashCode()。

 

package cn.tedu.map;

 

import java.util.HashSet;

import java.util.Iterator;

 

//总结:

//1, 如果使用HashSet对Java中相同属性的对象去重,要求:在类中同时提供重写的equals()和hashCode()

public class Test7 {

    public static void main(String[] args) {

       HashSet<Student> set = new HashSet<>();

       //创建元素

       Student s1 = new Student("西门庆",20);

       Student s2 = new Student("武大郎",19);

       Student s3 = new Student("潘金莲",21);

       Student s4 = new Student("小龙女",23);

      

       Student s5 = new Student("武大郎",19);

       Student s6 = new Student("潘金莲",21);

       //添加时,新元素会和老元素比

       set.add(s1);

       set.add(s2);

       set.add(s3);

       set.add(s4);

       //默认:添加时查找对象的hash值,没有查到就存起来

       //所以必须让hash值一致才可以

       set.add(s5);

       set.add(s6);

        //问题1:属性相同时还是认为是两个对象,存两次???...

       System.out.println(set);

      

      

    }

}

 

//创建Student类

 

class Student {

    private String name;

    private int age;

   

    public Student(String name, int age) {

       this.name = name;

       this.age = age;

    }

    public Student() {

    }

    public String getName() {

       return name;

    }

    public void setName(String name) {

       this.name = name;

    }

    public int getAge() {

       return age;

    }

    public void setAge(int age) {

       this.age = age;

    }

   

    @Override

    public String toString() {

       return "Student [name=" + name + ", age=" + age + "]";

    }

   

    //默认是使用了Object提供的hashCode(),底层会自动运算分配一个hashCode值

    //现在的需求:如果属性值相同,产生一个相同的hashCode值,希望根据属性的值产生hashCode值

    @Override

    public int hashCode() {

       final int prime = 31;

       int result = 1;

       result = prime * result + age;

       result = prime * result + ((name == null) ? 0 : name.hashCode());

       return result;

    }

   

   

    //默认是使用了Object提供的equals(),是比较两个对象的地址值,如果new了两次返回false

    //现在的问题是:虽然new了两次,但是属性值完全一样,还是想要按照是同一个对象处理

    //重写equals()的目的就是为了让equals()比较两个对象的属性值是否相同,而不再比较地址值

    @Override

    public boolean equals(Object obj) {

       if (this == obj)

           return true;

       if (obj == null)

           return false;

       if (getClass() != obj.getClass())

           return false;

       Student other = (Student) obj;

       if (age != other.age)

           return false;

       if (name == null) {

           if (other.name != null)

              return false;

       } else if (!name.equals(other.name))

           return false;

       return true;

    }

   

   

   

}

 

posted @ 2020-05-25 16:13  白驼山庄庄主  阅读(103)  评论(0编辑  收藏  举报