一.泛型
--1,概念
作用就类似于项目经理检查学员是这个班的吗?--做出类型检查.泛型的标志 <元素的类型>,英文是Generics.是JDK1.5 的一个新特性,其实就是一个『语法糖』,本质上就是编译器为了提供更好的可读性而提供的一种小手段,小技巧,虚拟机层面是不存在所谓『泛型』的概念的。
--2,作用
--通过泛型的语法定义,约束集合元素的类型,进行安全检查,把错误显示在编译期
--代码通用性更强,后面有案例
--泛型可以提升程序代码的可读性,但它只是一个语法糖(编译后这样的东西就被删除, 不出现在最终的源代码中),对于JVM运行时的性能是没有任何影响的。
--3,泛型使用的位置
--类/接口上 -- public class Student<E>{}
--方法上 --public <E> void eat(E e){}
--4,测试
package cn.tedu.collection;
import java.util.ArrayList;
import java.util.List;
// 测试 泛型
public class Test2_Generics {
public static void main(String[] args) {
//泛型来是想要模拟数组--统一数据类型--编译期就报错
// String[] a = {"1","c","av",123,1.1};
//泛型的作用--检查集合中的元素类型 --如果类型不对,编译期报错
List list = new ArrayList();
//集合中可以添加任意类型的数据!!!---太自由!!!
list.add(1.1);
list.add(10);
list.add(true);
list.add("jack");
System.out.println(list);
//想要约束集合中的元素类型?--泛型
List<String> list2 = new ArrayList();
list2.add("jack");
//添加失败,因为元素的类型,没有通过泛型的类型String检查
// list2.add(1.1);
// list2.add(5);
// list2.add(false);
//泛型里约束的元素的类型,必须是引用类型,不能是基本类型
List<Integer> list3 = new ArrayList<>();
list3.add(1);
list3.add(2);
list3.add(3);
}
}
二 集合
--1,概述
目前程序中,如果出现了多个数据需要存储.解决方案就是数组.但是数组有缺点.
--长度固定,数组一旦创建长度不可改变
--数组里元素的类型太单调,都是统一的
--数组的遍历方式太单一,用下标遍历
--如果有大量的数据需要存储,可以使用集合.
--集合工具类,都在java.util.*包里
--2,继承结构
--Collection是顶级接口
--List接口:
--ArrayList实现类
--LinkedList实现类
--Set接口:
--HashSet实现类
--TreeSet实现类
--Map接口:
三.Collection接口
--1,概述
Collection 层次结构 中的根接口。Collection 表示一组对象,这些对象也称为collection 的元素。一些 collection 允许有重复的元素,而另一些则不允许。一些collection 是有序的,而另一些则是无序的。
package cn.tedu.collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
//测试 集合
public class Test3_Collection {
public static void main(String[] args) {
//1,创建对象
Collection<Integer> c = new ArrayList<>();
//2,常用方法
c.add(1);
c.add(2);
c.add(3);
c.add(5);
c.add(4);
// c.clear();//清空集合
System.out.println(c.contains(1) );//判断是否包含指定元素
System.out.println(c.equals(1) );//判断集合是否和指定元素相等
System.out.println(c.hashCode() );//获取集合在内存中的哈希码值
System.out.println(c.isEmpty() );//判断集合是否为空
System.out.println(c.remove(2) );//移除指定元素
System.out.println(c.size() );//获取集合的长度
Object[] os = c.toArray() ;//把元素存入数组
//[1, 3, 5, 4]
System.out.println( Arrays.toString(os) );
//----------集合间的操作
Collection<Integer> c2 = new ArrayList<>();
c2.add(1);
c2.add(2);
c2.add(3);
System.out.println( c.addAll(c2) );//把c2添加到c里面
System.out.println( c.containsAll(c2) );//判断c中是否包含c2
//System.out.println( c.removeAll(c2) );//删除交集元素
System.out.println( c.retainAll(c2) );//取差集
System.out.println(c);
//TODO 迭代/循环/遍历 集合
// Iterator<E> iterator() --返回可以迭代集合的迭代器
Iterator<Integer> it = c.iterator() ;
while( it.hasNext() ) {//判断集合中是否有下一个元素,有就返回true
Integer in = it.next() ;//获取下一个元素
System.out.println(in);
}
}
}
四.List接口
--1,有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素。与 set 不同,列表通常允许重复的元素。列表本身允许 null 元素,通常它们允许多个 null 元素。
--2,特点
--元素有序
--元素有下标
--允许重复元素
--可以存 null 元素
--特有的
void add(int index, E element)
在列表的指定位置插入指定元素(可选操作)。
boolean addAll(int index, Collection<? extends E> c)
将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
E get(int index)
返回列表中指定位置的元素。
int indexOf(Object o)
返回此列表中第一次出现的指定元素的索引;
int lastIndexOf(Object o)
返回此列表中最后出现的指定元素的索引
ListIterator<E> listIterator()
返回此列表元素的列表迭代器(按适当顺序)。
E remove(int index)
移除列表中指定位置的元素(可选操作)。
E set(int index, E element)
用指定元素替换列表中指定位置的元素(可选操作)。
List<E> subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分
--4,测试
package cn.tedu.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
//测试 List接口
public class Test4_List {
public static void main(String[] args) {
//1,创建对象
List<String> list = new ArrayList<>() ;
//2,常用方法
//TODO --继承自Collection接口的方法
list.add("xiongda");
list.add("xionger");
list.add("guangtq");
list.add(null);
list.add("xiongda");
list.add("xionger");
//List特点:元素有序+元素可以重复+可以存null+元素都有下标
System.out.println(list);
//----List接口的特有方法们---都是根据下标操作数据的方式
list.add(2,"美队") ;//在指定下标处,插入指定的元素
System.out.println(list);
System.out.println(list.get(2));//根据下标获取元素
//获取指定元素第一次出现的索引值
System.out.println( list.indexOf("xiongda") );
//获取指定元素最后一次出现的索引值
System.out.println( list.lastIndexOf("xiongda") );
System.out.println( list.remove(2) );//按照索引删除元素并返回被删除的元素是谁
System.out.println( list.set(1, "皮皮霞"));//把指定索引对应的值替换掉
//截取前:[xiongda, 皮皮霞, guangtq, null, xiongda, xionger]
List<String> list2 = list.subList(2, 4);//[2,4)含头不含尾的截取子List
System.out.println(list2);//截取前:[guangtq, null]
//TODO 迭代List接口的方式:
//Iterator<E> iterator()
Iterator<String> it = list.iterator() ;
while(it.hasNext()) {//判断有下一个元素吗
String s = it.next() ;//获取下一个元素
System.out.println(s);
}
//Iterator<E> iterator() --继承自Collection--返回父接口--向后遍历
//ListIterator<E> listIterator() --子接口List--返回子接口--向后遍历/逆向遍历
ListIterator<String> it2 = list.listIterator() ;
while(it2.hasNext()) {//判断有下一个元素吗
String s = it2.next() ;//获取下一个元素
System.out.println(s);
}
//for循环
for(int i = 0 ; i < list.size() ; i++) {
System.out.println( list.get(i) );
}
//增强for/foreach -- for(数据的类型 变量名 : 要遍历的数据 ){ }
for(String s : list) {
System.out.println(s);
}
}
}
五ArrayList实现类
--1,概述
List 接口的大小可变数组的实现。每个 ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小。
--2,特点
--元素有下标
--元素可重复
--元素有序
--底层是一个数组.方便查询.
--3,创建对象
ArrayList()
构造一个初始容量为 10 的空列表。
--4,测试
package cn.tedu.collection;
import java.util.ArrayList;
//测试 ArrayList
public class Test5_ArrayList {
public static void main(String[] args) {
//1,创建对象
//ArrayList底层为了一个数组Object[],用来存储多个元素.
//数组的默认大小是10.大于10的时候,底层会自动扩容.扩容方式是:是以前容量的1.5倍
ArrayList<Integer> list = new ArrayList<>();
//TODO 2,常用方法
//--继承自Collection接口的方法
list.add(1);
//--继承自List接口的方法
}
}
六.LinkedList实现类
--1,概述
是List接口的链接列表实现。
--2,特点
--底层是链表结构
--元素有序
--元素可重复
--元素有下标
--3,常用方法
--继承自List接口的方法 -- 略
--继承自Collection接口的方法 -- 略
--实现类自己的特有方法
void addFirst(E e)
将指定元素插入此列表的开头。
void addLast(E e)
将指定元素添加到此列表的结尾。
E getFirst()
返回此列表的第一个元素。
E getLast()
返回此列表的最后一个元素。
E removeFirst()
移除并返回此列表的第一个元素。
E removeLast()
移除并返回此列表的最后一个元素。
boolean offer(E e)
将指定元素添加到此列表的末尾(最后一个元素)。
boolean offerFirst(E e)
在此列表的开头插入指定的元素。
boolean offerLast(E e)
在此列表末尾插入指定的元素。
E peek()
获取但不移除此列表的头(第一个元素)。
E peekFirst()
获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
E peekLast()
E poll()
获取并移除此列表的头(第一个元素)
E pollFirst()
获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
E pollLast()
获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
--4,创建对象
LinkedList()
构造一个空列表。
--5,测试
package cn.tedu.collection;
import java.util.LinkedList;
//测试 LinkedList
public class Test1_LinkedList {
public static void main(String[] args) {
//1,创建对象--底层是链表结构
LinkedList<Integer> list = new LinkedList<>();
//2,常用方法
//TODO 继承自List接口的方法
//TODO 继承自Collection接口的方法
list.add(1);
list.add(2);
list.add(3);
System.out.println(list);
//--实现类自己的特有方法--针对首尾元素进行操作
list.addFirst(99);//添加首元素
list.addLast(100);//添加尾元素
System.out.println(list);//[99, 1, 2, 3, 100]
System.out.println( list.getFirst());//获取首元素
System.out.println( list.getLast());//获取尾元素
System.out.println( list.removeFirst());//移除首元素
System.out.println( list.removeLast());//移除尾元素
System.out.println(list);//[1, 2, 3]
}
}
七.Set接口
--1,概述
一个不包含重复元素的 collection,最多包含一个 null 元素
--2,特点
--元素不能重复
--元素没有下标
--元素无序
--3,方法
--全都是 继承自Collection接口的方法
--4,测试
package cn.tedu.collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
//测试 Set接口
public class Test2_Set {
public static void main(String[] args) {
//1,创建对象 -- set通常用来给数据去重!!!
Set<String> set = new HashSet<>();
//TODO 2,常用方法
//全都是 继承自Collection接口的方法
set.add("2a");
set.add("1b");
set.add("d");
set.add("c");
set.add("jack");
set.add(null);
set.add("2a");
set.add("1b");
set.add("d");
//set是无序的+可以添加一个null+元素不能重复!!!
System.out.println(set);
//迭代set集合里的元素
//方式1:Iterator<E> iterator()
Iterator<String> it = set.iterator() ;
while(it.hasNext()) {//判断,有元素就返回true
String s = it.next() ;//获取元素
System.out.println(s);
}
//方式2:foreach
for(String s : set) {
System.out.println(s);
}
}
}
八.HashSet
--1,概述
此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持。它不保证 set 的 迭代顺序.
通过hashCode()计算出元素的存储位置,并将这些元素正确地分布在桶中。
对此 set 进行迭代所需的时间与HashSet 实例的大小(元素的数量)和底层 HashMap实例(桶的数量)的“容量”的和成比例。因此,如果迭代性能很重要,则不要将初始容量设置得太高(或将加载因子设置得太低).
--2,特点
--底层是哈希表/散列表
--元素无序
--元素不能重复
--元素没有下标
--3,创建对象
HashSet()
构造一个新的空 set,其底层 HashMap 实例的默认初始容量是 16,加载因子是 0.75。
--4,常用方法
--继承自Set接口的方法们~~
--5,测试
package cn.tedu.collection;
import java.util.HashSet;
//测试 HashSet
public class Test3_HashSet {
public static void main(String[] args) {
//TODO 1,创建对象--桶--性能:初始值+加载因子
//我们创建的是HashSet对象,但是底层实际上是创建了一个HashMap对象
HashSet<Double> set = new HashSet<>();
//TODO 2,常用方法
//我们是向HashSet中添加数据,但是底层实际上是向HashMap中添加的
set.add(1.1);
}
}
九.Map接口
--1,概述
将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能映射到一个值。
Map 接口提供三种collection 视图,允许以键集、值集或键-值映射关系集的形式查看某个映射的内容。映射顺序 定义为迭代器在映射的 collection 视图上返回其元素的顺序。某些映射实现可明确保证其顺序,如 TreeMap 类;另一些映射实现则不保证顺序,如 HashMap 类。
--2,特点
--存的数据是键值对的格式
--其中键不能重复
--每个键对应一个值
--HashMap是无序的,TreeMap是有序的
--3,创建对象
接口无法创建对象,只能创建实现类对象
--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 视图。
--5,测试
package cn.tedu.collection;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
//测试Map接口
public class Test4_Map {
public static void main(String[] args) {
//1,创建对象
Map<Integer,String> map = new HashMap<>();
//TODO 刚刚new出来的map里元素有值吗?--有,都是默认值.null=null
//2,常用方法
map.put(9527, "唐伯虎");
map.put(9528, "如花");
map.put(9528, "兵哥哥");
map.put(9529, "钟南山");
map.put(9530, "袁隆平");
//map里的key是唯一的,不能重复,如果重复了,value会被覆盖.
//HashMap无序
System.out.println(map);
//{9527=唐伯虎, 9528=兵哥哥, 9529=钟南山, 9530=袁隆平}
// map.clear();//清空集合
System.out.println( map.containsKey(9527));//判断map中是否包含指定的key
System.out.println( map.containsValue("袁隆平"));//判断map中是否包含指定的value
System.out.println( map.equals(123) );判断map是否和指定元素相等
System.out.println( map.get(9529) );//根据key查找对应的value
System.out.println( map.hashCode() );//获取哈希值
System.out.println( map.isEmpty() );//判读map是否为空
System.out.println( map.remove(9528) );//根据key删除记录
System.out.println( map.size() );//获取集合的长度
Collection<String> c = map.values() ;//把map里的所有value放入Collection中
System.out.println(c);//[唐伯虎, 钟南山, 袁隆平]
//迭代map里的数据--把map转成set的方式
//方式1--把map里的key存入set--Set<K> keySet()
Set<Integer> set = map.keySet() ;
//遍历set,获取每一个key
for (Integer key : set) {
//根据key,回map里找value
String value = map.get(key);
System.out.println(key+","+value);
}
//方式2--把map里的整条记录key和value一起存入set--Set<Map.Entry<K,V>> entrySet()
Set<Entry<Integer,String>> set2 = map.entrySet() ;
//遍历set获取每个Entry
for (Entry<Integer, String> entry : set2) {
//获取Entry对象封装着的key和value
Integer key = entry.getKey() ;
String value = entry.getValue() ;
System.out.println(key+"===="+value);
}
}
}
十.HashMap实现类
--1,特点/原理
--为了提高查询效率,底层会维护一个数组,把数据存入数组中
--底层根据hashCode()计算得到存储位置/哈希值
--如果该位置没有存过数据,直接放在该位置,也就是放在了数组节点上
--如果该位置存过数据(hash冲突/hash碰撞),会形成链表结构
--把新的数据作为链表的头节点
--如果形成了链表结构,会大大降低查询效率
--jdk1.8优化了链表中多个节点的查询效率,如果链表上节点数>8,会形成红黑树结构,如果树上的节点<6会再次变回成链表
--2,创建对象
HashMap()
构造一个具有默认初始容量 (16) 和默认加载因子 (0.75) 的空 HashMap。
--3,测试
package cn.tedu.collection;
import java.util.HashMap;
import java.util.Map.Entry;
//测试 HashMap
public class Test5_HashMap {
public static void main(String[] args) {
//TODO 1,创建对象
HashMap<String,String> map = new HashMap<>();
//TODO 2,常用方法
map.put("k1", "杨幂");
map.put("k2", "Angelababy");
map.put("k3", "刘沛霞");
System.out.println(map);
//遍历Map --> Set
//把map里的key放到set里`
for(String key : map.keySet()) {
String value = map.get(key);
System.out.println("key="+key+",,,value="+value);
}
//把map里的key和value封装成Entry放入set里
for(Entry<String,String> entry : map.entrySet() ){
String key = entry.getKey() ;
String value = entry.getValue();
System.out.println("key="+key+":::value="+value);
}
}
}
十一.Collections工具类
--0,概述
提供了大量的针对collection 集合的静态方法
--1,常用方法
static <T> boolean addAll(Collection<? super T> c, T... elements)
将所有指定元素添加到指定 collection 中。
static T max(Collection<? extends T> coll)
根据元素的自然顺序,返回给定 collection 的最大元素。
static T min(Collection<? extends T> coll)
根据元素的自然顺序 返回给定 collection 的最小元素。
static void reverse(List<?> list)
反转指定列表中元素的顺序。
static void sort(List<T> list)
根据元素的自然顺序 对指定列表按升序进行排序。
static void swap(List<?> list, int i, int j)
在指定列表的指定位置处交换元素。
--2,测试
package cn.tedu.collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
//测试 集合工具类Collections
public class Test1_Collections {
public static void main(String[] args) {
//TODO 创建List集合,并添加元素
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(7);
list.add(9);
list.add(3);
System.out.println(list);//[1, 7, 9, 3]
//static <T> boolean addAll(Collection<? super T> c, T... elements)
Collections.addAll(list, 2,4,6,8);//向指定集合中,一次性添加多个数据
System.out.println(list);//[1, 7, 9, 3, 2, 4, 6, 8]
//static T max(Collection<? extends T> coll)
//获取list集合里的最大值
System.out.println( Collections.max(list) );
//static T min(Collection<? extends T> coll)
//获取list集合里的最小值
System.out.println( Collections.min(list) );
//static void reverse(List<?> list)
Collections.reverse(list);//指定的list集合中的数据进行反转
System.out.println(list);//[8, 6, 4, 2, 3, 9, 7, 1]
//static void sort(List<T> list)
Collections.sort(list);//指定的list集合中的数据进行排序
System.out.println(list);//[1, 2, 3, 4, 6, 7, 8, 9]
//static void swap(List<?> list, int i, int j)
Collections.swap(list, 1, 6);//把list中,指定下标的两个元素进行位置交换
System.out.println(list);//[1, 8, 3, 4, 6, 7, 2, 9]
}
}