JAVA集合小记
来自初学小白,如果有误,望各位大佬指点一二!!!!
集合的由来
当需要在Java程序中记录单个数据内容时,则声明一个变量
当需要在Java程序中记录多个类型相同的数据内容时,则声明一个一维数组
当需要在Java程序中记录多个类型不同的数据内容时,则创建一个对象
当需要在Java程序中记录多个类型相同的对象时,则准备一个集合
类集设置的目的------数组不能动态扩充大小,为了方便用户操作各个数据结构引入了类集的概念
集合的框架结构
Java中集合框架的顶层集合是:Java.util.Collection集合和Java.util.Map集合。
其中Collection集合中存取元素的基本单位是:单个元素
其中Map集合中存取元素的基本单位是:单对元素
类集中最大的几个操作接口----Collection, Map, Iterator
所有类集操作的接口或类都在Java.until包中
Java类集结构图:
Collection接口
Java.util.Collection接口是List接口,Queue接口以及Set接口的父接口,因此该接口里定义的方法,既可用于操作List集合,也可用于操作Queue集合和Set集合/
Collection接口一共定义了15个方法。
开发中不会直接使用Collection接口,而使用其操作的子接口-----List、Set
代码:
package com.java5.Collection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class CollectionTest {
public static void main(String[] args) {
//准备一个Collection集合并打印
//Collection接口是不能实例化对象的
//Collection collection = new Collection();
//接口类型的引用指向实现类的对象,从而形成多态
Collection collection = new ArrayList();
//自动调用toString方法,ArrayList类中的toString方法
//默认打印格式为:[元素值1,元素值2,元素值3……]
System.out.println(collection);//无内容
System.out.println("------------------------------------");
//实现元素的添加
boolean flag = collection.add(new String("one"));
System.out.println("flag = " + flag);//flag=true
System.out.println(collection);//[one]
flag = collection.add(Integer.valueOf(2));
System.out.println("flag=" + flag);//flag=true
System.out.println(collection);//[one,2]
flag = collection.add(new Person("张飞",50));
System.out.println("flag=" + flag);//flag = true
//打印集合时,本质上就是让集合中每个元素调用toString方法进行打印
System.out.println(collection);//[one, 2, Person{name='张飞', age=50}]
System.out.println("-------------------------------");
//实现多个元素的添加
Collection collection1 = new ArrayList();
collection1.add("three");//常量池
collection1.add(4); //装箱池
System.out.println(collection1);//[three, 4]
//将集合collection1中所有元素添加到集合collection中,本质上是将元素一个一个放入
collection.addAll(collection1);
//将集合collection1看作一个大对象放入集合中
//collection.add(collection1);
//[one, 2, Person{name='张飞', age=50}, three, 4]
//[one, 2, Person{name='张飞', age=50}, [three, 4]]
System.out.println(collection);
System.out.println("-------------------------------");
//判断参数指定的元素是否存在
flag = collection.contains("two");
System.out.println(flag);//false
flag = collection.contains(2);
System.out.println(flag);//true
//由源码可知;
// 当参数对象为空时,则去集合中查找是否有空对象,若有则返回对应的编号。
// 当参数对象不为空时,则使用参数对象调用equals方法与集合中已有元素依次比较,若相等返回编号,
// 若上述条件都不成立,则返回-1表示查找失败
//当Person类中没有重写equals方法时,则调用从Object类中继承的版本,比较地址 false
//当Person类中重写equals方法后,则调用重写以后的版本,比较内容 true
flag = collection.contains(new Person("张飞",50));
System.out.println(flag);//false
System.out.println("-------------------------------");
//实现集合之间交集的的获取并打印
//[one, 2, Person{name='张飞', age=50}, three, 4]
System.out.println(collection);
//[three, 4]
System.out.println(collection1);
//实现交集的运算,若当前集合中内容发生改变则返回true,否则返回false
flag = collection.retainAll(collection);
System.out.println(flag);//false
//[one, 2, Person{name='张飞', age=50}, three, 4]
System.out.println(collection);
//再次取交集
flag = collection.retainAll(collection1);
System.out.println(flag);//true
//[three, 4]
System.out.println(collection);
System.out.println("-------------------------------");
//实现集合中元素的删除操作
flag = collection.remove(3);
System.out.println(flag);//false
System.out.println(collection);
flag = collection.remove("three");
System.out.println(flag);//true
System.out.println(collection);
//清空集合
collection.clear();
System.out.println(collection);//[]
System.out.println(collection.isEmpty()?"集合已经空了":"集合还没有空");
System.out.println("集合中元素个数是:"+collection.size());//0
System.out.println("-------------------------------");
//如何实现集合和数组之间的相互转换
Collection collection2 = new ArrayList();
collection2.add("one");
collection2.add("two");
collection2.add("three");
System.out.println(collection2);//[one, two, three]
//实现集合到数组类型的转换
Object[] objects = collection2.toArray();
System.out.println("数组中的元素有:");
for (int pos=0;pos<objects.length;pos++){
System.out.println(objects[pos]+" ");
}
System.out.println();
//实现数组到集合类型的转换
Collection collection3 = Arrays.asList(objects);
System.out.println(collection3);
}
}
List接口
整个集合中List是Collection的子接口,该集合中允许有重复的元素并且有先后放入次序。
该接口的主要实现类有:ArrayList类,LinkedList类,Stack类,Vector类。
可以认为ArrayList和LiknedList的方法在逻辑上完全一样,只是在性能上有一定的差别,ArrayList更适合于访问,而LinkedList更适合于插入和删除,在性能要求不是特别苛刻的情形下可以忽略这个差别。
定义: public interface List extends Collection
此接口上依然使用了泛型技术,此接口对于Collection接口来讲有如下的扩充方法
代码:
package com.java5.Collection;
import java.util.LinkedList;
import java.util.List;
/**
* 编程实现List集合的测试
*/
public class ListTest {
public static void main(String[] args) {
//准备List集合并打印
List list = new LinkedList();
System.out.println(list);//[]
System.out.println("--------------------------");
//实现向集合中添加元素
list.add(0,"one");
System.out.println(list);//[one]
list.add(0,1);
System.out.println(list);//[1, one]
list.add(1,"two");
System.out.println(list);//[1, two, one]
list.add("one");
System.out.println(list);//[1, two, one, one] 元素可以重复,有先后放入次序
System.out.println("--------------------------");
//实现集合中所有元素的遍历
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('[');
for (int pos=0;pos<list.size();pos++){
stringBuilder.append(list.get(pos));
if (pos<list.size()-1){
stringBuilder.append(',').append(' ');
}
}
stringBuilder.append(']');
System.out.println(list);//[1, two, one, one]
System.out.println("--------------------------");
//实现集合中元素的修改
//Object obj = list.set(0, "one");
//该方法的返回值默认为Object类型,若希望表达真实的数据类型则需要进行强制类型转换
Integer integer = (Integer) list.set(0, "one");
System.out.println("obj = "+integer);//obj = 1
System.out.println(list);//[one, two, one, one]
String string = (String) list.set(2,3);
System.out.println("被修改的元素是:"+string);//one
System.out.println(list);//[one, two, 3, one]
System.out.println("--------------------------");
//实现集合中元素的删除操作 使用remove方法删除所有元素
//注意:每当删除一个元素后,后面的元素向前补位,同时元素的个数少1
/*int len = list.size();
for (int pos=0;pos<len;pos++){
list.remove(pos);//编译ok,运行出现IndexOutOfBoundsException下标越界异常
}*/
//倒着删除是可以的
/* for (int pos=list.size()-1;pos>0;pos--){
list.remove(pos);
}
System.out.println(list);//[]*/
System.out.println("--------------------------");
//获取子集合
List list1 = list.subList(0,3);
System.out.println(list1);//[one, two, 3]
//考点:共用一块内存空间
list1.remove(0);
System.out.println(list1);//[two, 3]
System.out.println(list);//[two, 3, one]
}
}
ArrayList
ArrayList类的底层是采用动态数组进行数据管理的,支持下标访问,增删元素不方便。
public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable,Serializable
此类继承了 AbstractList 类。AbstractList 是 List 接口的子类。AbstractList 是个抽象类,适配器设计模式。
扩容—1.5倍
package com.java3.List;
import java.util.ArrayList;
/**
* ArrayList方法
*/
public class Demo {
public static void main(String[] args) {
//ArrayList<E> :使用的是数组结构,对于增加删除慢,查找快
//E---此列表中元素的类型
//ArrayList()构造一个初始容量为10的空列表
ArrayList<Integer> data = new ArrayList<>();//实例化ArrayList对象,并指定泛型类型
//ArrayList(int initialCapacity)构造具有指定初始容量的空列表
ArrayList<Integer> data1 = new ArrayList<>(2);
//ArrayList(Collection<? extends E> c)按照集合的迭代器返回的顺序构造一个包含指定集合元素的列表
//ArrayList<Integer> data2 = new ArrayList(data);
// void add(int index, E element) 将指定元素插入此列表中的指定位置
// Boolean add(E e)将指定的元素追加到此列表的末尾
data.add(0,5);
data.add(1,6);
data.add(90);
data.add(80);
boolean z = data.add(100);
System.out.println(z);
//E get(int index) 返回此列表中指定位置的元素
System.out.println(data.get(0));
//int size() 返回此列表中的元素数
int i = data.size();
System.out.println(i);
//Object[] toArray() 以适当的顺序(从第一个元素到最后一个元素)返回包含次列表中所有元素的数组
Object[] array = data.toArray();
System.out.println(array);
//E remove(int index) 删除此列表中指定位置的元素
//Boolean remove(Object o) 从该列表中删除指定元素的第一个匹配项(如果存在)
data.remove(0);
System.out.println(data.get(0));
boolean a = data.remove((Integer) 80);
System.out.println(a);
System.out.println(array);
// void clear() 从此列表中删除所有元素
//boolean removeAll(Collection<?> c)从此列表中删除指定集合中包含的所有元素
data.clear();
//boolean isEmpty() 如果此列表中不包含任何元素,则返回true
System.out.println(data.isEmpty());
}
}
Vector(基本已经不用了)
Vector类的底层采用动态数组进行数据管理,该类于ArrayList类相比属于线程安全的类,效率比较低,以后开发中基本不用。
public class Vector extends AbstractList implements List,RandomAccess, Cloneable, Serializable
此类与 ArrayList 类一样,都是 AbstractList 的子类。所以,此时的操作只要是 List 接口的子类就都按照 List 进行操作。
使用与 ArrayList 本身并没有任何的区别。因为操作的时候是以接口为操作的标准。但是 Vector 属于 Java 元老级的操作类,是最早的提供了动态对象数组的操作类,在 JDK 1.0 的时候就已经推出了此类的使用,只是后来在 JDK 1.2 之后引入了 Java 类集合框架。但是为了照顾很多已经习惯于使用 Vector 的用户,所以在JDK 1.2 之后将 Vector 类进行了升级了,让其多实现了一个 List 接口,这样才将这个类继续保留了下来。
Vector类和ArrayList类的区别
LinkedList
LinkedList类的底层采用双向链表进行数据管理的,访问不方便,增删元素方便。
public class LinkedList extends AbstractSequentialList implements List, Deque, Cloneable, Serializable
此类继承了 AbstractList,所以是 List 的子类。但是此类也是 Queue 接口的子类。
package com.java3.List;
import java.util.LinkedList;
public class Demo3 {
public static void main(String[] args) {
// LinkedList
LinkedList<Integer> data = new LinkedList<>();
data.addFirst(122);
data.addFirst(100);
Integer j = data.removeFirst();
System.out.println(j);//100
Integer i = data.getFirst();
System.out.println(i);//122
// 压栈
data.push(100);
data.push(500);
// 弹栈
Integer x = data.pop();
System.out.println(i);//122
}
}
StackList
Stack类的底层是采用动态数组进行数据管理,主要用于描述一种具有后进先出特征的数据结构,叫做栈(last in first out LIFO)
package com.java5.Collection;
import java.util.Stack;
/**
* 编程实现Stack类的使用
*/
public class StackTest {
public static void main(String[] args) {
//准备一个Stack集合
Stack stack = new Stack();
System.out.println(stack);//[]
System.out.println("-----------------------------------");
//将数据11,22,33,44,55一次入栈并打印
for (int cnt=1;cnt<=5;cnt++){
stack.push(cnt*11);
System.out.println(stack);//[11, 22, 33, 44, 55]
}
System.out.println("-----------------------------------");
//查看栈顶元素并打印
System.out.println("栈顶元素是:"+stack.peek());//55
System.out.println("-----------------------------------");
//然后将所有数据依次出栈并打印
for (int cnt=1;cnt<=5;cnt++){
System.out.println("出栈的元素是:"+stack.pop());//55, 44, 33, 22, 11
}
}
}
Set接口
java.util.Set集合是Collection集合的⼦集合,与List集合平级。
该集合中元素没有先后放⼊次序,且不允许重复。
该集合的主要实现类是:HashSet类 和 TreeSet类以及LinkedHashSet类。
Set 接口并没有对 Collection 接口进行扩充,基本上还是与 Collection 接口保持一致。因为此接口没有 List 接口中定义的 get(int index)方法,所以无法使用循环进行输出。
package com.java3.List;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Demo6 {
//Set接口---没有get,内容不能重复,
//HashSet:散列存放(哈希表--HashMap集合)无序的存储方式
//TreeSet:基于TreeMap有序的存储方式
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
boolean flag1 = set.add("锄禾日当午");
set.add("汗滴禾下土");
set.add("谁知盘中餐");
set.add("粒粒皆辛苦");
boolean flag2 = set.add("锄禾日当午");
System.out.println(flag1);//true
System.out.println(flag2);//false (内容不能重复)
for (String s : set) {
System.out.println(s);
}
System.out.println("----------------------------");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
TreeSet<String> data = new TreeSet<>();
data.add("B");
data.add("A");
data.add("E");
data.add("C");
data.add("D");
for (String s : data) {
System.out.println(s);
}
}
}
HashSet–散列存放
其中HashSet类的底层是采⽤哈希表进⾏数据管理的。
元素放入HashSet集合的原理
使⽤元素调⽤hashCode⽅法获取对应的哈希码值,再由某种哈希算法计算出该元素在数组中的索引位置。
若该位置没有元素,则将该元素直接放⼊即可。
若该位置有元素,则使⽤新元素与已有元素依次⽐较哈希值,若哈希值不相同,则将该元素直接放⼊。
若新元素与已有元素的哈希值相同,则使⽤新元素调⽤equals⽅法与已有元素依次⽐较。
若相等则添加元素失败,否则将元素直接放⼊即可。
package com.java5.Collection;
import java.util.HashSet;
import java.util.Set;
/**
* 编程实现HashSet类
*/
public class HashSetTest {
public static void main(String[] args) {
//实例化Set接口对象
Set<String> set = new HashSet<String>();
set.add("A");
set.add("C");
set.add("B");
set.add("锄禾日当午");
set.add("汗滴禾下土");
set.add("A");//Set接口中不能有重复内容
set.add("E");
set.add("D");
System.out.println(set);//[A, B, C, 汗滴禾下土, D, E, 锄禾日当午]
System.out.println("---------------------------------------------");
//HashSet实例化的Set接口实例,本身属于无序的存放
//通过循环的方式将Set接口中的内容输出
//将集合变为对象数组进行输出
Object obj[] = set.toArray();//将集合变为对象数组
for (int i=0;i<obj.length;i++){
System.out.print(obj[i]+",");//A,B,C,汗滴禾下土,D,E,锄禾日当午,
}
System.out.println();
System.out.println("---------------------------------------------");
//变为指定的泛型类型数组
String[] strings = set.toArray(new String[]{});
for (int i=0;i<strings.length;i++){
System.out.print(strings[i]+",");//A,B,C,汗滴禾下土,D,E,锄禾日当午,
}
}
}
TreeSet–排序的子类
其中TreeSet类的底层是采⽤红⿊树进⾏数据管理的。
⽐较元素⼤⼩的规则有两种⽅式:
使⽤元素的⾃然排序规则进⾏⽐较并排序,让元素类型实现java.lang.Comparable接⼝。
//Comparable比较器是在自定义类中实现Comparable接口,并重写compareTo()方法
使⽤⽐较器规则进⾏⽐较并排序,构造TreeSet集合时传⼊java.util.Comparator接⼝。
//Comparator–该比较器是在调用sort方法的同时传送一个实现Comparator接口匿名内部类对象,
//在内部类重写中重写compara方法
package com.java3.List;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Demo6 {
//Set接口---没有get,内容不能重复,
//HashSet:散列存放(哈希表--HashMap集合)无序的存储方式
//TreeSet:基于TreeMap有序的存储方式
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
boolean flag1 = set.add("锄禾日当午");
set.add("汗滴禾下土");
set.add("谁知盘中餐");
set.add("粒粒皆辛苦");
boolean flag2 = set.add("锄禾日当午");
System.out.println(flag1);//true
System.out.println(flag2);//false (内容不能重复)
for (String s : set) {
System.out.println(s);
}
System.out.println("----------------------------");
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
TreeSet<String> data = new TreeSet<>();
data.add("B");
data.add("A");
data.add("E");
data.add("C");
data.add("D");
for (String s : data) {
System.out.println(s);
}
}
}
LinkedHashSet
其中LinkedHashSet类与HashSet类的不同之处在于内部维护了⼀个双向链表,链表中记录了元素的迭代顺序,也就是元素插⼊集合中的先后顺序,因此便于迭代。
Map接口(Mapping)
Map集合存储的是一个个的 键值对 数据
Map集合的键(key)不可重复,每个键最多可以映射一个值
java.util.Map<K,V>集合中存取元素的基本单位是:单对元素,其中类型参数如下:
K - 此映射所维护的键(Key)的类型,相当于⽬录。
V - 此映射所维护的值(Value)的类型,相当于内容。
该集合中key是不允许重复的,⽽且⼀个key只能对应⼀个value。
该集合的主要实现类有:HashMap类、TreeMap类、LinkedHashMap类、Hashtable类、Properties类。
其中HashMap类的底层是采⽤哈希表进⾏数据管理的。
其中TreeMap类的底层是采⽤红⿊树进⾏数据管理的。
其中LinkedHashMap类与HashMap类的不同之处在于内部维护了⼀个双向链表,链表中记录了元素的迭代顺序,也就是元素插⼊集合中的先后顺序,因此便于迭代。
其中Hashtable类是古⽼的Map实现类,与HashMap类相⽐属于线程安全的类,且不允许null作为key或者value的数值。
其中Properties类是Hashtable类的⼦类,该对象⽤于处理属性⽂件,key和value都是String类型的。
Map集合是⾯向查询优化的数据结构, 在⼤数据量情况下有着优良的查询性能。
经常⽤于根据key检索value的业务场景。
DEFAULT_INITIAL_CAPACITY : HashMap的默认容量是16。
DEFAULT_LOAD_FACTOR:HashMap的默认加载因⼦是0.75。
threshold:扩容的临界值,该数值为:容量*填充因⼦,也就是12。
TREEIFY_THRESHOLD:若Bucket中链表⻓度⼤于该默认值则转化为红⿊树存储,该数值是8。
MIN_TREEIFY_CAPACITY:桶中的Node被树化时最⼩的hash表容量,该数值是64。
HashMap
package com.java5.Collection;
import java.util.Collection;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* 编程实现HashMap类
*/
public class HashMap {
public static void main(String[] args) {
Map<Integer,String> map = new java.util.HashMap<Integer,String>();
map.put(1,"张三");
map.put(2,"李四");
map.put(3,"王五");
map.put(4,"赵六");
//v get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回null
String string = map.get(6);
System.out.println(string);//null,
System.out.println("-------------------------------");
//Set<K> keySet() 返回此映射中包含的键的视图---遍历
Set<Integer> set = map.keySet();
//Collection<V> values() 将全部的value变为Collection集合
Collection<String> value = map.values();
Iterator<Integer> iterator = set.iterator();
while (iterator.hasNext()){
System.out.print(iterator.next()+"、");
}
System.out.println();
for (String s : value) {
System.out.print(s+"、");
}
System.out.println();
System.out.println("-------------------------------");
//循环输出Map中的全部内容
Set<Integer> set1 = map.keySet();
for (Integer key : set1) {
System.out.println(key+"-->"+map.get(key));
}
}
}
package com.java3.List;
import java.util.HashMap;
import java.util.Objects;
public class Demo11 {
//存储自定义对象
public static void main(String[] args) {
HashMap<Book,String> data = new HashMap<>();
Book book1 = new Book("金苹果","讲述了种植苹果的辛酸历程");
data.put(book1,"我们人生的第一本书");
// book1.setName("青苹果");//哈希码值改变,查找不到----哈希值错乱,
// 对象作为哈希表的键存储时,作为计算哈希值的存储时,存完之后不要改变
System.out.println(data.get(book1));
Book book2 = new Book("红苹果","讲述了种植苹果的辛酸历程");
data.put(book2,"我们人生的第二本书");
System.out.println(data.get(book2));
Book book3 = new Book("金苹果","讲述了种植苹果的辛酸历程");
System.out.println(data.get(book3));
}
static class Book{
private String name;
private String info;
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
", info='" + info + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Book book = (Book) o;
return Objects.equals(name, book.name) && Objects.equals(info, book.info);
}
@Override
public int hashCode() {
return Objects.hash(name, info);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
public Book(String name, String info) {
this.name = name;
this.info = info;
}
public Book() {
}
}
}
Hashtable
Hashtable 是一个最早的 keyvalue 的操作类,本身是在 JDK 1.0 的时候推出的。其基本操作与 HashMap是类似的。
TreeMap
package com.java5.Collection;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* 编程实现TreeMap类
*/
public class TreeMapTest {
public static void main(String[] args) {
//TreeMap其本身在操作的时候将按照key进行排序
Map<String,String> map = new TreeMap<String,String>();
map.put("ZS", "张三");
map.put("LS", "李四");
map.put("WW", "王五");
map.put("ZL", "赵六");
map.put("SQ", "孙七");
Set<String> set = map.keySet();
/* LS-->李四
SQ-->孙七
WW-->王五
ZL-->赵六
ZS-->张三 */
for (String s : set) {
System.out.println(s+"-->"+map.get(s));
}
}
}
JDK 9 集合新特性
package com.java3.List;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Demo12 {
//JDK 9 集合新特性
//of()返回包含任意数量元素的不可修改集,
public static void main(String[] args) {
//此方法还接受单个数组作为参数,结果集的元素类型将是数组的组件类型,并且集的大小将等于数组的长度,
List<String> list = List.of("ha","xi","han","shu","hei","haa");
//list.add(" 1 ");不能添加,会报错,出异常
for (String s : list) {
System.out.print(s+",");
}
System.out.println();
System.out.println("-------------------");
String[] array = {"ha","xi","han","shu","hei","haa"};
Set<String> set = Set.<String>of(array);
for (String strings : set) {
System.out.print(strings+",");//haa,han,hei,shu,xi,ha,
}
System.out.println();
System.out.println("-------------------");
// Set<String> set = Set.of("遇事不决","可问春风");
// for (String s : set) {
// System.out.println(s);
// }
// 可问春风
// 遇事不决
// Map<String,String> map = Map.of("1","遇事不决","2","可问春风","3","春风不语","4","可随本心");
// Set<String> keyset = map.keySet();
// for (String s : keyset) {
// System.out.println(s+"--"+map.get(s));
// }
// 1--遇事不决
// 2--可问春风
// 3--春风不语
// 4--可随本心
}
}
Collections类
Collections实际上是一个集合的操作类,这个类与Collection接口没有任何的关系,是一个单独存在的类。
java.util.Collections类主要提供了对集合操作或者返回集合的静态⽅法。
package com.java5.Collection;
import java.util.*;
/**
* 编程实现Collections类
*/
public class CollectionsTest {
public static void main(String[] args) {
//emptyList() 返回一个空列表(不可变)。
List<String> all = Collections.emptyList();//空集合
//all.add("A");//出异常,UnsupportedOperationException
// for (String s : all) {
// System.out.println(s);
// }
Set<String> set = new TreeSet<>();
Collections.addAll(set,"A","B","C");//向集合增加元素
for (String string : set) {
System.out.println(string);//A B C
}
System.out.println("----------------------------");
//返回给定集合的最大元素,自然顺序
String s = Collections.max(set);
System.out.println(s);//C
//返回给定集合的最小元素,自然顺序
String s1 = Collections.min(set);
System.out.println(s1);//A
System.out.println("-------------------------------");
//将⼀个列表中的所有元素复制到另⼀个列表中
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
System.out.println(list);//[A, B, C]
//必须将复制到的列表指定和被复制列表的大小设为一致,否则会出现下标越界问题
List<String> list1 = new ArrayList<>(list.size());
Collections.copy(list,list1);
System.out.println(list);//[A, B, C]
System.out.println("---------------------");
//反转指定列表中元素的顺序
Collections.reverse(list);
System.out.println(list);//[C, B, A]
System.out.println("---------------------");
//根据其元素的自然顺序对指定列表按升序排序
List<Integer> list2 = new ArrayList<>();
list2.add(8);
list2.add(5);
list2.add(9);
list2.add(15);
Collections.sort(list2);
System.out.println(list2);//[5, 8, 9, 15]
System.out.println("---------------------");
//交换指定列表中指定位置的元素
Collections.swap(list2,2,0);
System.out.println(list2);//[9, 8, 5, 15]
}
}
Queue集合
Java.util.Queue集合是Collection集合的子集合,与List集合属于平级关系
该集合的主要用于描述具有先进先出特征的数据结构,叫做队列(first in first out FIFO)
该集合的主要实现类是LinkedList类,因为该类在增删方面比较有优势
应用场景有:排队购票,银行排队,击鼓传花游戏等.
package com.java5.Collection;
import java.util.LinkedList;
import java.util.Queue;
/**
* 编程实现Queue集合的使用
*/
public class QueueTest {
public static void main(String[] args) {
//准备⼀个Queue集合
Queue queue = new LinkedList();
System.out.println(queue);//[]
System.out.println("-----------------------------");
//将数据11、22、33、44、55依次⼊队并打印
for (int cnt=1;cnt<=5;cnt++){
queue.offer(cnt*11);
System.out.println(queue);//[11, 22, 33, 44, 55]
}
System.out.println("------------------------------");
//查看队首元素并打印
System.out.println("队首元素是:"+queue.peek());//11
System.out.println("------------------------------");
//再将队列中所有数据依次出队并打印
for (int cnt=1;cnt<=5;cnt++){
System.out.println("出队的元素是:"+queue.poll());//11 22 33 44 55
}
}
}
Deque集合
java.util.Deque集合是Queue的⼦集合,英⽂全称是“double ended queue(双端队列)”的缩写,通常读为“deck”,该集合是⼀个⽀持在两端插⼊和移除元素的线性集合。
Java语⾔中的Stack类已经过时,Java官⽅推荐使⽤Deque替代Stack实现栈的效果,也可以代替Queue实现队列的效果。
package com.java5.Collection;
import java.util.Deque;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
/**
* 编程实现Deque类
*/
public class DequeTest {
public static void main(String[] args) {
//准备一个Stack集合
Stack stack = new Stack();
System.out.println(stack);//[]
//准备⼀个Queue集合
Queue queue = new LinkedList();
System.out.println(queue);//[]
//准备两个Deque类
Deque deque = new LinkedList();
System.out.println(deque);//[]
Deque deque1 = new LinkedList();
System.out.println(deque1);//[]
System.out.println("---------------------------");
//将数据11,22,33,44,55依次存入集合
//双端队列作为栈时
for (int cnt=1;cnt<=5;cnt++){
stack.push(cnt*11);
System.out.println(stack);//[11, 22, 33, 44, 55]
}
for (int cnt=1;cnt<=5;cnt++){
// deque1.addFirst(cnt*11);//[55, 44, 33, 22, 11]
deque1.addLast(cnt*11);//[11, 22, 33, 44, 55]
System.out.println(deque1);
}
System.out.println("---------------------------");
//双端队列作为队列时
for (int cnt=1;cnt<=5;cnt++){
queue.offer(cnt*11);
System.out.println(queue);//[11, 22, 33, 44, 55]
}
for (int cnt=1;cnt<=5;cnt++){
// deque.offerFirst(cnt*11);//[55, 44, 33, 22, 11]
deque.offerLast(cnt*11);//[11, 22, 33, 44, 55]
System.out.println(deque);
}
System.out.println("-----------------------------------");
//查看头元素并打印
System.out.println("栈顶元素是:"+stack.peek());//55
System.out.println("队首元素是:"+queue.peek());//11
System.out.println("作为栈时栈顶元素:"+deque1.getFirst());//55
System.out.println("作为队列时队首元素:"+deque.peek());//11
System.out.println("------------------------------");
//所有数据依次出队/栈并打印
for (int cnt=1;cnt<=5;cnt++){
System.out.println("出栈的元素是:"+stack.pop());//55, 44, 33, 22, 11
}
for (int cnt=1;cnt<=5;cnt++){
System.out.println("双端队列出栈的元素是:"+deque1.removeFirst());//55, 44, 33, 22, 11
}
System.out.println("------------------------------");
for (int cnt=1;cnt<=5;cnt++){
System.out.println("出队的元素是:"+queue.poll());//11 22 33 44 55
}
for (int cnt=1;cnt<=5;cnt++){
System.out.println("双端队列出队的元素是:"+deque.pollFirst());//11 22 33 44 55
}
}
}
迭代器–Iterator接口
Java.util.Iterator接口主要用于描述迭代器对象,可以遍历Collection集合中的所有元素。
java.util.Collection接口继承Iterable接口,因此所有实现Collection接口的实现类都可以使用上述迭代器方法。
package com.java3.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
public class Demo4 {
/**
* 遍历集合中所有的元素,提供了迭代器
* public E next() :返回迭代的下一个元素。
* public boolean hasNext() :如果仍有元素可以迭代,则返回 true。
* @param args
*/
public static void main(String[] args) {
//Iterator
//ListIterator
ArrayList<Integer> data = new ArrayList<>();
data.add(1);
data.add(2);
data.add(3);
data.add(4);
data.add(5);
ListIterator<Integer> iterator = data.listIterator();
iterator.add(12);
iterator.next();
iterator.next();
iterator.set(200);
System.out.println(data.size());
iterator.previous();
iterator.previous();
iterator.previous();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
// Iterator<Integer> iterator = data.iterator();
// while (iterator.hasNext()){
//
// Integer i = iterator.next();
// System.out.println(i);
// }
// iterator.next();
// iterator.remove();
// System.out.println(data.size());
}
}
forEach
package com.java3.List;
import java.util.ArrayList;
public class Demo5 {
public static void main(String[] args) {
//forEach : 增强for循环,最早出现在C#中,
//用于迭代(iterator)数组或集合(只能是Collection下的集合)
//语法:
//for(数据类型 变量名 : 集合或数组名){}
int[] arr = {6,5,4,3,2,1};
for (int i : arr) {
System.out.println(i);
}
System.out.println("------------------------");
ArrayList<String> data = new ArrayList<>();
data.add("哈哈");
data.add("嘻嘻");
data.add("嘿嘿");
for (String datum : data) {
System.out.println(datum);
}
}
}