黑马程序员--Java学习日记之集合(collection类与list接口)及泛型概述

时间:2021-12-03 17:59:08


                                        ------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


一,集合概念
  之前我们存储大量的对象,可以使用数组:
  但数组有两个缺陷:
  1.其长度一旦确定,后期不能更改;对于元素的新增、删除就十分的不方便;
  2.数组只能存储一种类型的数据。
  
  为了解决上述问题,也为了我们程序员更加方便的存储大量的对象,Java为我们提供了一种"类":集合类;
  1.集合:它的作用跟数组一样,就是存储大量对象的;
  2.跟数组不同的:
  1).使用集合可以是我们程序员不用关心"长度"的概念,"集合"对于我们来说,似乎像个"无底洞",可以存储无限数量的对象;
  2).集合可以存储任何的"对象";(但后期我们也是经常会存储一种对象)
public class Demo {
public static void main(String[] args) {
//1.定义容器:集合类:ArrayList
ArrayList list = new ArrayList();
//2.实例化若干多的Student对象
for(int i = 0;i < 10000; i++){
//直接实例化,并向集合中添加对象(注意:这里添加的也是对象的引用)
list.add( new Student("姓名:" + i,i + 10));//姓名:0,10
}

//经过上述的第2步后,集合中添加了10000个Student对象的引用;
//3.遍历集合
for(int i = 0;i < list.size();i++){
//从集合中取出Student引用
Student s = (Student)list.get(i);//跟数组差不多,这里调用的是get()方法,获取一个Student的引用.由于get方法返回的是Object类型,所以这里强转一下
System.out.println(s.name + "," + s.age);

}
//假如,原集合存储的对象有增加,这时可以直接向集合中继续添加元素
for(int i = 10000;i < 20000; i++){
//直接实例化,并向集合中添加对象(注意:这里添加的也是对象的引用)
list.add( new Student("姓名:" + i,i + 10));//姓名:0,10
}
}
}
                                                                                                                           
第二讲 Collection
一,Collection

      1.它是所有List和Set集合的跟接口;
      2.它内部定义了List和Set所应具有的方法;
      学习:从Collection接口开始;
      使用:从子类开始:ArrayList 
      Collection中定义的常用方法:
  
  1.添加:
  //大家以后看到某个方法的形参或返回值是E的话,那么就先把它视作:Object类型:
  boolean add(Object e):向集合中添加元素;如果此 collection 由于调用而发生更改,则返回 true
  boolean addAll(Collection c)
  2.删除:
  boolean remove(Object o):移除元素:此 collection 由于调用而发生更改),则返回 true 。
void clear():清空集合
boolean removeAll(Collection c)


  3.判断:
  boolean contains(Object o):判断参数在集合中是否存在;存在:返回true,否则返回false
boolean isEmpty():判断集合为空;
boolean containsAll(Collection c)


  4.获取:
  int size():获取集合内的元素的数量;
  boolean retainAll(Collection c)
二,Collection中的一些批量操作 的方法:
  添加
  boolean addAll(Collection c):指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
  删除
  boolean removeAll(Collection c):移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
  判断:
  boolean containsAll(Collection c):如果此 collection 包含指定 collection 中的"所有元素",则返回 true。
  boolean retainAll(Collection c):移除此 collection 中未包含在指定 collection 中的所有元素。 

代码:

import java.util.ArrayList;
import java.util.Collection;

public class CollectionMethod {
public static void main(String[] args) {
methodSingle();
System.out.println("====================");
methodAll();

}
public static void methodSingle(){
//使用子类ArrayList
Collection list = new ArrayList();
//向集合中添加引用(这里添加字符串)
list.add("刘若英");
list.add("刘德华");
list.add("刘诗诗");
list.add("刘惜君");

//打印集合:
System.out.println("原集合:" + list);
//测试:remove(Object o);
System.out.println("移除刘若英:" + list.remove("刘若英"));//true
System.out.println("移除后:" + list);

//4.void clear():清空集合
/*list.clear();
System.out.println("集合被清空了:" + list);*/

//5.boolean contains(Object o):判断参数在集合中是否存在;存在:返回true,否则返回false
System.out.println("判断刘若英是否存在:" + list.contains("刘若英"));
System.out.println("判断刘德华是否存在:" + list.contains("刘德华"));

//6.boolean isEmpty():判断集合为空;
/*System.out.println("集合是否为空:" + list.isEmpty());
list.clear();
System.out.println("清空后,判断是否为空:" + list.isEmpty());*/

//7.int size():获取集合内的元素的数量;
System.out.println("集合内元素的数量:" + list.size());
}
public static void methodAll(){
//集合1
Collection list1 = new ArrayList();
list1.add("刘若英");
list1.add("刘德华");
list1.add("刘诗诗");
list1.add("刘惜君");

//集合2
Collection list2 = new ArrayList();
list2.add("王心凌");
list2.add("王力宏");
list2.add("王光良");
list2.add("王菲");

//addAll()
list1.addAll(list2);//合班
System.out.println("合班之后list1中的元素:" + list1);
System.out.println("list2中的元素:" + list2);

//removeAll();
/* list1.removeAll(list2);//再分班
System.out.println("分班后,list1中的元素:" + list1);
System.out.println("list2中的元素:" + list2);
*/
//containsAll
System.out.println("list1中包含list2中的所有元素吗?" + list1.containsAll(list2));

Collection list3 = new ArrayList();
list3.add("毛爷爷");
list3.add("铁娘子");
list3.add("奥巴马");
list3.add("金正恩");
System.out.println("list1中包含list3中的所有元素吗?" + list1.containsAll(list3));

//retainAll()
list2.retainAll(list3);
System.out.println("移除list2中未包含在list3中的所有元素:" + list2);
System.out.println("list2中的元素;" + list2);
System.out.println("list3中的元素:" + list3);

Collection list4 = new ArrayList();
list4.add("aa");
list4.add("bb");

Collection list5 = new ArrayList();
list5.add("cc");
list5.add("dd");
list4.retainAll(list5);
System.out.println("list4 中的所有元素:" + list4);
System.out.println("list5 中的所有元素:" + list5);
}
}



 三,迭代器:java.util.Iterator(接口)
    成员方法:
      1.boolean hasNext():判断是否可以返回下一个元素;
      2.Object next():返回下一个元素;

两种遍历方式:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
*
*
*
*/
public class CollectionTraverse {
public static void main(String[] args) {
methodTraverseFirst();
System.out.println("===========");
methodTraverseSecond();
}
/*
* 方法一:
*
*/
public static void methodTraverseFirst() {
//实例化一个集合
Collection list = new ArrayList();
//填充集合
list.add("王心凌");
list.add("张韶涵");
list.add("辛晓琪");
list.add("蔡依林");

//获取数组
Object[] objArray = list.toArray();
//遍历数组
for(int i = 0;i < objArray.length ; i++){
//由于toArray()方法返回的是Object类型的数组,而我们存储的是String对象。可以将Object强制转换为String
String s =(String) objArray[i];
System.out.println("数组:"+s);
}
}
public static void methodTraverseSecond(){
//1.实例化一个集合
Collection list = new ArrayList();
//2.填充集合
list.add("王心凌");
list.add("张韶涵");
list.add("辛晓琪");
list.add("蔡依林");

//3.使用迭代器遍历:
Iterator it = list.iterator();
while(it.hasNext()){
Object o = it.next();
System.out.println("Iterator:" + o);
}
}
}



                                                                                                                               
第三讲 List
一,层次

Collection(接口):
     |--List(接口):
  |--ArrayList(类)
二,List接口的特点
  1.有序的;
  2.可以根据整数的索引访问元素(类似于数组的使用);
  3.允许重复的元素;
三,List接口中的特有方法:
  void add(int index,Object element):在index的位置上插入元素element,原索引上的元素依次后移;
  Object remove(int index):移除列表中指定位置的元素(可选操作)。将所有的后续元素向左移动(将其索引减 1)。返回从列表中移除的元素。
  Object get(int index):取index位置上的元素。(它就类似于数组的下标)
  Object set(int index,E element):将element替换原index位置上的元素; 
  LitsIterator listIterator():List接口特有的Iterator(),同样是用来遍历元素的。
四,|--List接口
  |--ArrayList类:内部数组实现;线程不安全的。效率高
  |--Vector类:内部数组实现;线程安全的。效率低;
  |--LinkedList类:链表实现:线程不安全的。效率高;                                                
五,Iterator接口:是单向的,只能向下遍历
  |--ListIterator接口:
  |--特有的方法:
  hasPrevious():如果可以向上遍历,返回true
  previous():获取前一个元素;

import java.util.ArrayList;
import java.util.List;

public class ListMethod {
public static void main(String[] args) {
//实例化一个集合
List list = new ArrayList();
//先使用Collection的add添加一些元素
list.add("紫薇");
list.add("尔康");
list.add("五阿哥");

//1.void add(int index,Object element)
//在ccc前面加一个XXX
list.add(2,"小燕子");
System.out.println("add方法之后的集合:" + list);

list.add(3,"漱芳斋");//OK的
System.out.println("add方法之后的集合:" + list);

//2.Object remove(int index):
list.remove(3);
System.out.println("移除掉之后的元素:" + list);

//3.Object get(int index)
System.out.println("获取索引为3的元素:" + list.get(3));

//4.Object set(int index,E element)
//将XXX改为YYY
list.set(3, "皇阿玛");
System.out.println("替换后为:" + list);
}
}1


     
六,Collection(接口)
  |--List(接口):特点:1.有序的;2.可以存储重复元素;
  |--ArrayList:
  1.数组实现:
  2.线程不安全,效率高;
  |--Vector:
  1.数组实现:
  2.线程安全,效率低;
  |--LinkedList:
  1.链表:
  2.线程不安全的,效率高;
七,Collection(接口)
  |--List(接口):
  |--Vector(类):
  1.数组实现。查询快,增删慢;
  2.线程安全,效率低;
    Vector是List的子类,所以:它具有List和Collection的所有功能;
   另外Vector又增加了一些特有的功能:
   public void addElement(Object obj):向集合添加一个obj,添加到集合的末尾;
   public Object elementAt(int index):获取index位置上的元素;作用等同于:List-->get(int index);
   
   public Enumeration elements():返回一个枚举;
八,LinkedList的特有方法:
  public void addFirst(E e)及addLast(E e)
  public E getFirst()及getLast()
  public E removeFirst()及public E removeLast()
 
  如果将LinkeList作为链表使用:
  1.使用addFirst()进行添加;
    使用get(int index)进行获取;
  2.使用addFirst()进行添加;
    使用getFirst()获取;
    使用removeFirst()移除第一个元素;
  3.使用add(Object o)进行添加;
    使用getLast()进行获取
    使用removeLast()移除最后的元素;
    
  如果将LinkedList作为普通的集合使用:
  1.使用add()添加;
  2.使用get()获取;
                                                                               第四讲 泛型
一,泛型概念

  1.集合就像仓库,可以装任何的引用类型;因为它的add()方法接收的是Object类型的。
  2.对于集合类,看似功能比较强大,可以添加任何类型的引用。
    但取出的时候,也比较费事,
  3.我们以后使用集合类,经常是向集合中添加一种类型的引用;
  4.这时,Java为我们提供了一种语法功能:可以将一个集合,在定义时,同时定义这个集合中只能存放
    什么类型的元素。这种功能就叫:泛型;
  5.例如:我们需要定义一个只存储"字符串"的集合
        ArrayList<String> list = new ArrayList<String>();
        或
        ArrayList<String> list = new ArrayList<>();(我会经常使用这种形式)
        或
        ArrayList<String> list = new ArrayList();
        
  6.通过JAD查看反编译的class文件,我们发现,泛型的信息已经没有了。
    所以:泛型只是在编译期所具有的一种行为,这种行为能够规范一个集合内只能存储我们定义的某种类型。
       如果向集合中存储其它类型,编译器会产生编译错误。
  7.泛型可以定义泛型类,泛型方法,泛型接口
二,泛型的通配符
    1.<?>:
  1).这种变量可以指向什么样的对象:具有任何泛型的集合。
  2).这种集合可以存储什么类型的数据:什么都不能存;
  3).这种集合获取时,可以用什么类型接收:只能用Object。因为使用了?,所以不确定里面存了什么类型;
  作用:这种声明的引用,只能获取,不能存入。它一般用于"方法的返回值"的声明;
    2.<? extends E>:
  1).这种变量可以指向什么样的对象:此声明的集合意味着此变量只能指向具有E或E的子类泛型的集合对象;
  2).这种集合可以存储什么类型的数据:因为某个具体的子类不确定,所以什么类型的对象都不能存;
  3).这种集合获取时,可以用什么类型接收:使用E及E的父类类型接收都可以;
  作用:这种声明的引用,只能获取,不能存入。它一般也是用于"方法的返回值"声明;
    3.<? super E>:
  1).这种变量可以指向什么样的对象:任何具有E及E的父类类型泛型的集合对象;
  2).这种集合可以存储什么类型的数据:任何的E及E的子类类型都可以;
  3).这种集合获取时,可以用什么类型接收:取出时只能用Object接收。
  作用:这种声明的引用,可以存入元素,但不能用除Object外的其它类型接收。这种声明的格式一般用在"方法的形参"
                                                                                                                               
 第五讲  增强for循环
一,格式:for(数据类型   变量名     :   集合对象名/数组名) 

  1.增强for不使用循环变量;
  2.根据自己的需要,如果需要使用循环变量,那么就使用普通的for循环;
    如果不需要循环变量,只是简单的遍历一下集合或数组,那么使用增强for的语法会简洁许多。
  3.增强for类似于迭代器,通过它对集合进行遍历时,仍然不能使用集合对象对集合内部进行修改,否则将抛出:并发修改异常:java.util.ConcurrentModificationException
                                                                               第六讲 Set(接口)
一,Collection(接口):
  |--List(接口):有序的,可以存储重复值;
      |--ArrayList(类):
  |--Vector(类):
   |--LinkedList(类):
  |--Set(接口):无序的(取出时跟存入的顺序不一致)。不能存储重复值
          它没有新增任何方法,我们使用Collection中的方法就可以操作Set集合了。
           |--HashSet(子类):
           
       注意:Set保证唯一性的方式:先判断hashCode,如果hashCode一致再判断equals()
二,LinkedHashSet类
    特点:
       1.由链表保证:有序(取出时跟存入的顺序一致);
       2.由哈希表保证元素唯一: 
       它没有特有的成员,都是继承下来的。
三,TreeSet类
   1.内部使用"树"结构:
   2."树"结构,存储数据的特点:将数据进行排序:
  这种排序会先进行比较,比较有两种方式
使用TreeSet存储元素,要求元素必须具有"比较的功能"
  我们怎么才能具有比较的功能:
  方式一:将我们的类实现:Comparable接口,重写compareTo()-->自然排序;
  方式二:我们的类不用实现任何接口,在实例化TreeSet时,给TreeSet传递一个"比较器对象",这个比较器
       对象一定要是:实现Comparator接口,重写compare()方法
                                                                                                                   
  第七讲 List接口和Set接口的小结
一,Collection:

  |--List:有序的;可以存储重复值;
  |--ArrayList:数组实现。线程不安全的,效率高;
  |--Vector:数组实现。线程安全,效率低;
  |--LinkedList:链表实现。线程不安全,效率高;
  |--Set:无序的;不能存储重复值;
  |--HashSet:哈希表实现。线程不安全的,效率高;
  判断重复元素:
  利用元素对象的:hashCode()和equals()
  两个方法如果都返回true,那么就认为是重复元素,不存储;
  |--LinkedHashSet:链表和哈希表实现。线程不安全的,效率高;
  利用链表保证"有序";
  利用哈希表保证"唯一";
  |--TreeSet:二叉树实现。线程不安全,效率高;
  可对元素排序。判断重复元素,以及对元素排序的方式:
  1.自然排序:我们自定义的类必须实现Comparable接口
  重写里面的compareTo()方法;
  2.比较器:我们的类不需要实现任何接口。
  在实例化TreeSet时,要为TreeSet传递一个比较器对象,这个对象必须实现Comparator接口
                       重写里面compare()方法;
               --比较器优先
                                                                                                                           
    第八讲 Map接口
一,1.Map接口跟Collection接口没有关系:

   2.Map接口是一个单独的接口,它使用另外的同Collection完全不同的方式存储、管理数据;
   3.Map集合存储元素的特点:使用"键值对";
   4.之前我们使用Collection集合,存入时,就是简单的向集合中存储;
    取出时:使用数组、迭代器、List集合中增加了一个带"索引"的
   5.有时候,我们存储一个对象,会给它"起个名字",获取对象时,用这个名字就可以取出这个对象。
    这时候,对于我们取出对象,非常的方便;
   6.使用Map存储对象:存储时,要给对象起个名字,存入时,连名字和对象一起存储。
    名字:键(key) 要存储的对象:值(Value);
二,Map接口的基本方法:
  1.添加:
  V put(K key,V value):向集合中添加元素;如果存储相同的键,不同的值,新值会替换旧值,键不变;
  2.删除:
  V remove(Object key):根据某个"键",删除元素;返回被删除的Value
  void clear():清空集合;
  3.判断:
 boolean containsKey(Object key):集合是否包含键key,包含返回true,否则返回false
 boolean containsValue(Object value):集合是否包含值value,包含返回true,否则返回false
 boolean isEmpty():判断集合是否为空。
 4.获取
 int size()
 V get(Object key)
 Set<K> keySet()
 Collection<V> values()
 Set<Map.Entry<K,V>> entrySet()
三,LinkedHashMap类
   1.内部使用链表结构,和哈希表结构;
   2.此Map是有序的;
四,TreeMap类:
  1.内部使用红黑树结构;
  2.树结构会对内部的"键"进行排序:
  1).自然排序:类要实现Comparable接口,重写compareTo()
  2).比较器排序:类要实现Comparator接口,重写compare()方法;
                             第九讲 Collections工具类
一,此类没有提供能使用的构造方法,内部包含了大量对Collection集合进行操作的一些"静态方法";
  
  public static <T> void sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序。
  public static <T> int binarySearch(List<?> list,T key):在集合list中查找key,使用二分查找:
   参数说明:
   list - 要搜索的列表。
   key - 要搜索的键。 
  public static <T> T max(Collection<?> coll):根据元素的自然顺序,返回给定 collection 的最大元素。
  public static void reverse(List<?> list):反转指定列表中元素的顺序。
  public static void shuffle(List<?> list):将内部的元素随机打乱