集合类的特点:提供一种存储空间可变的存储模型, 存储的数据容量可以发生改变
集合体系结构 Collection Collection集合的概述和使用- 单列集合的顶层接口,表示一组对象,这些对象也称为Collection的元素
- JDK不提供此接口的任何直接实现,它提供更具体的子接口(如SET和LIST)实现
- 可以通过多态由具体的实现类创建Collection集合的对象
boolean add(E e)//添加元素
boolean remove(Object)//从集合中移除指定的元素
void clear()//清空集合中的元素
boolean contains(Object)//判断集合中是否存在指定的元素
boolean isEmpty()//判断集合是否为空
int size()//集合的长度,也就是集合中元素的个数
Collection集合的遍历
Iterator
- 迭代器,集合的专用遍历方式。
- E next(): 返回迭代中的下一个元素
- boolean hasNext():如果迭代具有更多元素,则返回true
- 并发修改异常:ConcurrentModificationException
- 产生原因:迭代器遍历的过程中,通过集合对象修改了集合中元素的长度,造成了迭代器获取元素中判断预期修改值与实际修改值不一样。
- 解决方案:用for循环遍历,用对象做对应的操作。
public class CollectionDemo {
public static void main(String[] args) {
Collection c = new ArrayList();
//添加元素
c.add("hello");
c.add("world");
c.add("Java");
show(c);
//移除元素
c.remove("hello");
show(c);
//清空集合
c.clear();
show(c);
Collection c1 = new ArrayList();
c1.add("hello");
c1.add("world");
c1.add("Java");
Iterator it = c1.iterator();
//判断下一个数据的有无
while (it.hasNext()) {
System.out.println(it.next());
}
// Iterator it =list.iterator();
// while (it.hasNext()){
// String s=it.next();
// if(s.equals("中国")){
// list.add("针不戳");
// }
// }
}
public static void show(Collection c){
//已经重写toString方法
System.out.println("集合c:" + c);
//集合大小
System.out.println("集合C的大小为:" + c.size());
//判断集合是否为空
System.out.println("集合c是否为空" + c.isEmpty());
//判断集合中是否有指定元素
System.out.println("集合c中是否含有元素hello:" + c.contains("hello"));
}
}
List
List集合概述和特点
list集合概述
- 有序集合(也称为序列),用户科技精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素。
- 与Set集合不同,列表通常允许重复的元素
- 有序:存储和取出的元素顺序一致
- 可重复:存储的元素可以重复
void add(int index,E element) //在此集合中的指定位置插入指定的元素
E remove(int index) //删除指定索引处的元素,返回被删除的元素
E set(int index,E element)//修改指定索引处的元素,返回被修改的元素
E get(int index) //返回指定索引处的元素
ListIterator:列表迭代器
- 通过List集合的listlterator()方法得到, 所以说它是List集合特有的迭代器
- 用于允许程序员沿任一 方向遍历列表的列表迭代器, 在迭代期间修改列表,并获取列表中迭代器的当前位置
E next(); //返回迭代中的下一个元素 boolean hasNext(); //如果迭代具有更多元素,则返回true E previous(); //返回列表中的上一个元素 boolean hasPrevious(); //如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true void add(E e); // 将指定的元素插入列表list代码演示:
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
show(list);
//可重复:允许重复的数据
list.add("world");
show(list);
//在此集合中的指定位置插入指定的元素
list.add(1, "中国");
show(list);
//删除指定索引处的元素,返回被删除的元素
list.remove(2);
show(list);
//修改指定索引处的元素,返回被修改的元素
list.set(0, "你好");
show(list);
返回指定索引处的元素
System.out.println("list集合第二个数据:" + list.get(1));
// ListIterator
ListIterator lit = list.listIterator();
//如果迭代具有更多元素,则返回true
while (lit.hasNext()) {
//返回迭代中的下一个元素
String s = lit.next();
if(s.equals("中国")){
// 将指定的元素插入列表
lit.add("针不戳");
}
System.out.println(s);
}
System.out.println("-----------------------------");
//如果此列表迭代器在相反方向遍历列表时具有更多元素,则返回true
while (lit.hasPrevious()) {
//返回列表中的上一个元素
String s = lit.previous();
System.out.println(s);
}
}
public static void show(List list){
//有序性:以什么顺序输入就以什么顺序输出
System.out.println("list集合:" + list);
}
}
List集合常用子类
- ArrayList: 底层数据结构时数组,查询快,删除慢。(举棋不定用ArrayList)
- linkedList:底层数据结构是链表,查询慢,增删快
public void addFirst(E e)//在该列表开头插入指定的元素
public void addLast(E e)//将指定的元素追加到此列表的末尾
public E getFirst()//返回此列表中的第一个元素
public E getLast()//返回此列表中的最后个元素
public E removeFirst()//从此列表中删除并返回第一个元素
public E removeLast()//从此列表中删除并返回最后一个元素
linkedList代码演示
public class linkedListDemo {
public static void main(String[] args) {
linkedList linkedList = new linkedList();
linkedList.add("你好");
linkedList.add("中国");
linkedList.add("加油");
show(linkedList);
//可重复:允许重复的数据
linkedList.add("中国");
show(linkedList);
//linkedlist集合的特有功能:
//在该列表开头插入指定的元素
linkedList.addFirst("世界");
show(linkedList);
//将指定的元素追加到此列表的末尾
linkedList.addLast("亚洲");
show(linkedList);
// 返回此列表中的第一个元素
show(linkedList.getFirst());
//返回此列表中的最后一个元素
show(linkedList.getLast());
//从此列表中删除并返回第一个元素
linkedList.removeFirst();
show(linkedList);
//从此列表中删除并返回最后一个元素
linkedList.removeLast();
show(linkedList);
}
public static void show(T t) {
System.out.println(t);
}
Set
Set集合的概述和特点
特点:
- 不包含重复元素的集合
- 没有带索引的方法,所以不能使用普通for循环遍历
public class SetDemo {
public static void main(String[] args) {
//创建集合对象
Set set = new HashSet();
//添加元素
set.add("he1lo");
set.add("world");
set.add("java");
//不包含重复元素的集合
set.add("world");
//遍历
for (String s : set) {
System.out.println(s);
}
}
}
哈希值
-
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
-
Object类中有一个方法可以获取对象的哈希值
-
public int hashCode():返回对象的哈希码值
-
同一个对象多次调用hashCode()方法返回的哈希值是相同的
-
默认情况下,不同对象的哈希值是不同的,但是可以通过方法重写来使不同的对象哈希值相同。
ArrayListHashSet集合的概述和特点arraylist = new ArrayList (); System.out.println(arraylist.hashCode());
- 实现了Set接口,底层数据结构由哈希表支持。
- 对集合的迭代顺序不做任何保证(不保证存储和读取元素循序不一致)
- 没有带索引的方法,所以不能使用普通for循环遍历
- 要保证元素的唯一性,需要重写hashCode()和equals()方法。 需要通过hashCode验证哈希值是否相同,还要通过equals()判断内容是否一致
public class HashSetDemo {
public static void main(String[] args) {
//创建集合对象
HashSet hashSet = new HashSet();
//添加元素
hashSet.add("he1lo");
hashSet.add("world");
hashSet.add("java");
//不包含重复元素的集合
hashSet.add("world");
//遍历
for (String s : hashSet) {
System.out.println(s);
}
}
}
linkedHashSet集合概述和特点
- 哈希表和链表实现的Set接口,具有可预测的迭代次数
- 由链表保证元素有序,也就是元素存储和取出的循序是一致的
- 有哈希表保证元素唯一,无重复元素。
public class linkedHashSetDemo {
public static void main(String[] args) {
//创建集合对象
linkedHashSet linkedHashSet = new linkedHashSet();
//添加元素
linkedHashSet.add("he1lo");
linkedHashSet.add("world");
linkedHashSet.add("java");
//不包含重复元素的集合
linkedHashSet.add("world");
//遍历
for (String s : linkedHashSet) {
System.out.println(s);
}
}
}
TreeSet集合概述和特点
-
元素有序, 这里的顺序不是指存储和取出的顺序,而是按照一定的规则进行排序,具体排序方式取决于构造方法。
TreeSet():根据其元索的自然排序进行排序
TreeSet(Comparator comparator):根据指定的比较器进行排序
-
没有带索引的方法, 所以不能使用普通for循环遍历
-
由于是Set集合,所以不包含重复元素的集合
public class TreeSetDemo {
public static void main(String[] args) {
//创建集合对象
//无参构造方法,按照自然排序
TreeSet treeSet = new TreeSet();
//添加元素
treeSet.add(3);
treeSet.add(1);
treeSet.add(4);
treeSet.add(1);
treeSet.add(5);
treeSet.add(9);
treeSet.add(2);
treeSet.add(6);
//遍历
for (int s : treeSet) {
System.out.print(s + " ");
}
System.out.println();
//有参构造方法,根据指定的比较器
TreeSet treeSet1 = new TreeSet(new Comparator() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
//添加元素
treeSet1.add(3);
treeSet1.add(1);
treeSet1.add(4);
treeSet1.add(1);
treeSet1.add(5);
treeSet1.add(9);
treeSet1.add(2);
treeSet1.add(6);
//遍历
for (int s : treeSet1) {
System.out.print(s + " ");
}
}
}
Map
Map集合概述和使用
Map集合概述:
-
Interface Map
K:键的类型; V:值的类型 -
将键映射到值的对象; 不能包含重复的键;每个健可以映射到最多一个值
-
举例: 学生的学号和姓名
001 张三
002 李四
003 王五
创建Map集合的对象:
- 多态的方法
- 具体的实现类HashMap
V put(K key,V value)//添加元素
V remove(Object key)//根据键删除键值对元素
void clear()//移除所有的键值对元素
boolean containsKey(Object key)//判断集合是否包含指定的键
boolean containsValue(Object value)//判断集合是否包含指定的值
boolean isEmpty()//判断集合是否为空
int size()//集合的长度,也就是集合中键值对的个数
Map集合的获取功能
V get(Object key) //根据健获取值
Set keySet()//获取所有键的集合
Collection values()//获取所有值的集合
Set > entrySet()//获取所有键值对对象的集合
Map代码演示
public class MapDemo {
public static void main(String[] args) {
Map map =new HashMap();
//添加方法
map.put("001","北京");
map.put("002","上海");
map.put("003","广州");
map.put("004","深圳");
show(map);
//key值相同,value替换
map.put("004","香港");
show(map);
//value值可以相同
map.put("005","北京");
show(map);
//允许一个key值为空
map.put("","武汉");
show(map);
map.put("","长沙");
show(map);
//允许多个value值为空
map.put("006","");
show(map);
map.put("007","");
show(map);
Map map1 =new HashMap();
//添加方法
map1.put("001","北京");
map1.put("002","上海");
map1.put("003","广州");
map1.put("004","深圳");
show(map1);
//判断集合是否包含指定的键
System.out.println(map1.containsKey(004));
//判断集合是否包含指定的值
System.out.println(map1.containsValue("深圳"));
//根据键删除键值对元素
map1.remove(004);
show(map1);
System.out.println(map1.containsKey(004));
System.out.println(map1.containsValue("深圳"));
//移除所有的键值对元素
map1.clear();
show(map1);
Map map2 =new HashMap();
//添加方法
map2.put("001","北京");
map2.put("002","上海");
map2.put("003","广州");
map2.put("004","深圳");
show(map2);
//根据健获取值
System.out.println("001的值:"+map.get("001"));
//获取所有键的集合
Set keySet = map2.keySet();
System.out.println("键的集合:"+keySet);
//获取所有值的集合
Collection values = map2.values();
System.out.println("值的集合:"+values);
//获取所有键值对对象的集合
Set> entrySet = map2.entrySet();
System.out.println("键值对对象的集合:"+entrySet);
}
public static void show(Map map) {
System.out.println("-------------------------");
//判断集合是否为空
System.out.println("Map是否为空:"+map.isEmpty());
if(!map.isEmpty()){
//集合的长度,也就是集合中键值对的个数
System.out.println("Map大小为:"+map.size());
System.out.println("Map:"+map);
}
}
}
Map集合的遍历
遍历的思路1:
- 获取所有键的集合。 用keySet0方法实现
- 遍历键的集合, 获取到每一个键。用增强for实现
- 根据键去找值,用get(Object key)方法实现
//创建集合对象 Mapmap = new HashMap (); //添加元素 map.put("1","1"); map.put("2","2"); map.put("3","3"); //获取所有键的集合。用keySet()方法实现 Set keySet = map.keySet(); //遍历键的集合,获取到每一个键,用增强for实现 for (String key : keySet) { //根据键去找值,用get(object key)方法实现 String value = map.get(key); System.out.println(key +“,”+ value); }
遍历的思路2:
- 获取所有键值对对象的集合
Set> entrySet():获取所有键值对对象的集合 - 遍历键值对对象的集合, 得到每一个键值对对象
用增强for实现,得到每-个Map.Entry - 根据键值对对象获取键和值
用getKey0得到键
用getValue0得到值
//创建集合对象 Mapmap = new HashMap (); //添加元素 map.put("1","1"); map.put("2","2"); map.put("3","3"); //获取所有键值对对象的集合 Set > entrySet = map.entrySet(); //遍历键值对对象的集合,得到每一个键值对对象 for (Map.Entry me : entrySet) { //根据键值对对象获职键和值 String key = me.getKey(); string value = me.getValue(); System.out.println(key + ","+ value); }
当一个实体类没有重写需要重写hashCode()和equals()方法,当内容相同的值被初始化生成对象的时候会生成的是两个不同的对象。哈希值也不同,无法保证唯一性。
集合相关 泛型概述泛型:是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型它的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数一提到参数, 最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型这种参数类型可以用在类、方法和接口中,分别被称为泛型类泛型方法、泛型接口
泛型定义格式- <类型>: 指定-种类型的格式。这里的类型可以看成是形参
- <类型1.类型…>:.指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参
- 将来具体调用时候给定的类型可以看成是实参, 并且实参的类型只能是引用数据类型
- 把运行时期的问题提前到了 编译期间
- 避免了强制类型转换
//没有使用泛型 Collection c = new Arraylist(); //使用了泛型 Collection泛型类c = new ArrayList ();
泛型类的定义格式:
- 格式:修饰符class 类名<类型>{ }
- 范例: public class Generic{ }
//定义泛型类 public class Generic{ private T t; public T getT() { return t; } public void setT(T t) { this.t = t; } }
//调用泛型类 Generice泛型方法g1 = new Generic (); g1.setT("周杰伦"); System.out.println(g1.getT()); Generic g2 = new Generic (); g2.setT(30); System.out.println(g2.getT());
泛型方法的定义格式:
- 格式: 修饰符<类型>返回值类型方法名(类型变量名){}
- 范例: public void show(T t) { }
public class Generic {
//定义泛型方法
public void show(T t) {
System.out.println(t);
}
}
Generic g = new Generic();
//调用泛型方法
g.shou("周杰伦");
g.show(30);
g.show(true);
泛型接口
泛型接口的定义格式:
- 格式:修饰符interface接口名<类型>{ }
- 范例: public interface Generic { }
//定义泛型接口 public interface Generic{ void show(T t); }
//泛型接口实现类 public class GenericImplimplements Generic { @Override public void show(T t) { System.out. println(t); } }
//调用
public class GenericDemo {
pub1ic static void main(String[] args) {
Generic g1 = new GenericImpl();
g1.show("林青霞");
Generic g2 = new GenericImpl(); .
g2.show(30);
}
}
类型通配符
为了表示各种泛型List的父类,可以使用类型通配符
- 类型通配符: >
- List>: 表示元素类型末知的List, 它的元素可以匹配任何的类型
- 这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
如果说我们不希望List>是任何泛型List的父类,只希望它代表某一类泛 型List的父类,可以使用类型通配符的上限
- 类型通配符 上限:
- List extends Number>:它表示的类型是Number或者其子类型
除了可以指定类型通配符的.上限,我们也可以指定类型通配符的下限
- 类型通配符下限:
- List super Number>:它表示的类型是Number或者其父类型
public class GenericDemo {
public static void main(String[] args) {
//类型通配符: >
List> list1 = new ArrayList
可变参数
可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
- 格式: 修饰符返回值类型方法名(数据类型…变量名){ }
- 范例: public static int sum(int…a){ }
可变参数注意事项
- 这里的变量其实是一 个数组
- 如果一个方法有多个参数, 包含可变参数,可变参数要放在最后
public class ArgsDemo {
public static void main(String[] args) {
//调用可变参数方法
System.out.println(sum(10,20));
System.out.println(sum(10,20,30));
System.out.println(sum(10,20,30,40));
System.out.println(sum(10,20,30,40,50));
System.out.println(sum(10,20,30,40,50,60));
System.out.println(sum(10,20,30,40,50,60,70));
}
//定义可变参数方法,单个参数
public static int sum(int... a) {
int sum = e;
for(int i : a) {
sum += i;
}
return sum;
}
//定义可变参数方法,多个参数
public static int sum(int b,int... a) {
int sum = e;
for(int i : a) {
sum += i;
}
return sum-b;
}
}
可变参数的使用
Arrays工具类中有一个静态方法:
- public static List aslist(T… a): 返回由指定数组支持的固定大小的列表
- 返回的集合不能做增删操作,可以做修改操作
Listlist = Arrays.aslist("hello", "world", "java"); //因为添加和移除方法会改变列表的大小,所以无法使用 //list.add("javaee"); //UnsupportedOperationException //list.remove("world"); //UnsupportedOperat ionException list.set(1, "javaee"); System.out.println(list);
List接口中有一个静态方法:
- public static List ofE… elements): 返回包含任意数量元素的不可变列表
- 返回的集合不能做增删改操作
Listlist = List.of("he11o","world","java","world" ); //因为任意数量元素的不可变,所以添加,移除和修改方法都无法使用 //list.add("javaee");//UnsupportedOperationException //list.remove("java");//UnsupportedOperationException //list.set(1, "javaee")://UnsupportedOperationException System.out.println(list);
Set接口中有一个静态方法:
- public static Set of(E… elements) :返回一个包含任意数量元素的不可变集合
- 在给元素的时候,不能给重复的元素
- 返回的集合不能做增删操作,没有修改的方法
//Set不允许有重复元素 //SetCollections Collections概述和使用set = Set.of("he11o", "world", "java", "world"); Set set = Set.of("he11o", "world", "java"); //Set没有带索引所以无法使用set方法,同时列表不可变,无法使用增删方法 //set.add( "javaee ");//UnsupportedOperat ionException //set.remove( "world");//UnsupportedOperat ionException System.out.println(set);
Collections类的概述:
- 是针对集合操作的工具类
Collections类的常用方法:
//将指定的列表按升序排序 public staticCollections代码演示> void sort(List list); //反转指定列表中元素的顺序 public static void reverse(List> list); //使用默认的随机源随机排列指定的列表 public static void shuffle(List> list);
public class CollectionsDemo {
public static void main(String[] args) {
List list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(4);
list.add(1);
list.add(5);
//将指定的列表按升序排序
Collections.sort(list);
System.out.println(list);
//反转指定列表中元素的顺序
Collections.reverse(list);
System.out.println(list);
//使用默认的随机源随机排列指定的列表
Collections.shuffle(list);
System.out.println(list);
}
}
自然排序Comparable的使用
- 实体类继承Comparable接口,重写compareTo()方法。
- compareTo()方法返回0,认为数值一样,不会存储;返回正数,认为数值大,正序输出;返回负数,认为数值小,逆序输出。
public class Student implements Comparable增强for循环{ private String name; private int age; public Student() { } public Student(String name, int age) { this.name = name; this.age = age; } 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 int compareTo(Student s) { //return 0; //return 1; //return -1; //按照年龄从小到大排序 int num = this.age - s.age; //int num = s.age. - this. age; //年龄相同时,按照姓名的字母顺序排序 int num2 = num==0?this.name.compareTo(s.name):num; return num2; } }
增强for:简化数组和Collection集合的遍历
- 实现Iterable接口的类允许其对象成为增强型 for语句的目标
- 它是JDK5之 后出现的,其内部原理是一个Iterator迭代器所以也会有并发修改异常
增强for的格式:
for(元素数据类型变量名:数组或者Collection集合) {
//在此处使用变量,该变量就是元素
}
//数组范例
int[]arr= {1,2,3, 4, 5};
for(inti: arr) {
System.out.printn0);
}
//集合范例
List list = new ArrayList();
list.add("hello" );
list.add("world" );
list.add("java" );
for(String s : list) {
System.out.println(s);
}



