集合
概念: 集合是java中提供的一种容器,可以用来存储多个数据
集合和数组的区别
- 数组的长度固定,集合的长度可变
- 数组中存储的是同一类型的元素,可以存储基本数据类型,集合存储的都是对象,而且对象所属类型可以不一致。
集合框架
集合总共分为两大类:Collection(单例集合)和Map(双例集合)
collection
collection的常用方法:
public boolean add(E e)
: 把给定的对象添加到当前集合中 。public void clear()
:清空集合中所有的元素。public boolean remove(E e)
: 把给定的对象在当前集合中删除。public boolean contains(E e)
: 判断当前集合中是否包含给定的对象。public boolean isEmpty()
: 判断当前集合是否为空。public int size()
: 返回集合中元素的个数。public Object[] toArray()
: 把集合中的元素,存储到数组中。
例子:
public class Main {
public static void main(String[] args) {
// 创建集合对象
Collection<String> collection = new ArrayList<String>();
// 添加数据
collection.add("张三");
collection.add("李四");
collection.add("王五");
System.out.println(collection);
// 判断o是否在集合中存在
System.out.println("判断张三是否在集合中"+collection.contains("张三"));
//删除集合中的指定元素
System.out.println("删除王五:"+collection.remove("王五"));
System.out.println("操作之后集合中元素:"+collection);
// 计算集合中元素的个数
System.out.println("集合中有"+collection.size()+"个元素");
// 将集合转换为数组
Object[] objects = collection.toArray();
// 遍历数组
for (int i = 0; i < objects.length; i++) {
System.out.println(objects[i]);
}
// 清空集合
collection.clear();
System.out.println("集合中内容为:"+collection);
//判断集合是否为空
System.out.println(collection.isEmpty());
}
}
运行结果:
[张三, 李四, 王五]
判断张三是否在集合中true
删除王五:true
操作之后集合中元素:[张三, 李四]
集合中有2个元素
张三
李四
集合中内容为:[]
true
List
介绍: 存储有序可重复的集合
常用方法:
- public void add(int index) : 将指定的元素添加到该集合的末尾。
- public void add(int index, E element) : 将指定的元素,添加到该集合中的指定位置上。
- public E get(int index) :返回集合中指定位置的元素。
- public E remove(int index):移除列表中指定位置的元素, 返回的是被移除的元素。
- public E set(int index, E element):用指定元素替换集合中指定位置的元素,返回值的更新前的元素。
例子:
public class Main {
public static void main(String[] args) {
List<String> list=new ArrayList<>();
//添加元素
list.add("张三");
list.add("李四");
list.add(1,"王五");
System.out.println(list);
//获取集合中的第一个元素
System.out.println(list.get(0));
//移除集合中下标为1的元素
list.remove(1);
System.out.println(list);
//修改集合中第二个元素的值为被修改了(下标从0开始,下标为1代表第2个元素)
list.set(1,"被修改了");
System.out.println(list);
}
}
结果:
[张三, 王五, 李四]
张三
[张三, 李四]
[张三, 被修改了]
ArrayList
- 底层是一个数组
- 初始化容量为10,1.5倍扩容
- 线程不安全
例子:
public class Main {
public static void main(String[] args) {
ArrayList<String> list=new ArrayList<>();
list.add("张三");
list.add("李四");
System.out.println(list);
}
}
LinkedList
- 底层是一个双向链表
- 线程不安全
常用方法:
- public void addFirst(E e) :将指定元素插入此列表的开头。
- public void addLast(E e) :将指定元素添加到此列表的结尾。
- public E getFirst() :返回此列表的第一个元素。
- public E getLast() :返回此列表的最后一个元素。
- public E removeFirst() :移除并返回此列表的第一个元素。
- public E removeLast() :移除并返回此列表的最后一个元素。
- public E pop() :从此列表所表示的堆栈处弹出一个元素。
- public void push(E e) :将元素推入此列表所表示的堆栈。
- public boolean isEmpty() :如果列表不包含元素,则返回true。
例子:
public class Main {
public static void main(String[] args) {
LinkedList<String> list=new LinkedList<>();
list.addFirst("张三");
list.addFirst("李四");
list.addLast("王五");
System.out.println(list);
System.out.println(list.getFirst());
System.out.println(list.getLast());
list.removeFirst();
list.removeLast();
System.out.println(list);
list.push("推入");
System.out.println(list);
list.pop();
System.out.println(list);
System.out.println(list.isEmpty());
}
}
结果:
[李四, 张三, 王五]
李四
王五
[张三]
[推入, 张三]
[张三]
Vector
- 底层是一个数组
- 初始化容量为10,两倍扩容
- 线程安全的,方法都被synchronized关键字修饰
Set
set集合存储无序,不可重复的数据。
HashSet
底层有HashMap实现,key存储HashSet的值,value存储创建的Object对象,该对象被private static final修饰。
LinkedHashSet
底层有LinkedHashMap实现
TreeSet
底层由TreeMap进行实现
Map
概念: 存储键值对的双例集合
常用方法:
- public V put(K key, V value) : 把指定的键与指定的值添加到Map集合中。
- public V remove(Object key) : 把指定的键 所对应的键值对元素 在Map集合中删除,返回被删除元素的值。
- public V get(Object key) 根据指定的键,在Map集合中获取对应的值。
- public Set keySet() : 获取Map集合中所有的键,存储到Set集合中。
- public Set<Map.Entry<K,V>> entrySet() : 获取到Map集合中所有的键值对对象的集合(Set集合)。
例子:
public class Main {
public static void main(String[] args) {
Map<Integer,String> map=new HashMap<>();
//添加元素
map.put(1,"张三");
map.put(2,"李四");
map.put(3,"王五");
System.out.println(map);
//获取key==1的值
System.out.println(map.get(1));
//移除key==3的键值对
map.remove(3);
System.out.println(map);
//获取key的set集合可用于遍历map集合
Set<Integer> integers = map.keySet();
System.out.println(integers);
//获取所有的键值对
Set<Map.Entry<Integer, String>> entries = map.entrySet();
System.out.println(entries);
}
}
结果:
{1=张三, 2=李四, 3=王五}
张三
{1=张三, 2=李四}
[1, 2]
[1=张三, 2=李四]
HashMap
- jdk1.8后底层由数组+链表+红黑树实现
- 初始容量为16,2倍扩容
- 线程不安全
Properties
概念: Properties是一个Map集合,继承Hashtable,Properties的key和value都是String类型。 Properties被称为属性类对象。 Properties是线程安全的。
LinkedHashMap
在HashMap的基础上保证了元素的有序。
例子:
public class Main {
public static void main(String[] args) {
LinkedHashMap<Integer,String> map=new LinkedHashMap<>();
//添加元素
map.put(1,"张三");
map.put(2,"李四");
map.put(3,"王五");
System.out.println(map);
Set<Integer> integers = map.keySet();
for (Integer integer : integers) {
System.out.println(integer+"->"+map.get(integer));
}
}
}
结果:
{1=张三, 2=李四, 3=王五}
1->张三
2->李四
3->王五
Iterator迭代器
**迭代的概念:**即Collection集合元素的通用获取方式。在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
迭代的常用方法:
public E next()
:返回迭代的下一个元素。public boolean hasNext()
:如果仍有元素可以迭代,则返回 true
例子:
public class Main {
public static void main(String[] args) {
// 创建集合对象
Collection<String> collection = new ArrayList<String>();
// 添加数据
collection.add("张三");
collection.add("李四");
collection.add("王五");
System.out.println(collection);
Iterator<String> iterator = collection.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
运行结果:
[张三, 李四, 王五]
张三
李四
王五
注意: 使用迭代器遍历集合时,不要对集合进行删除,否则会抛出异常。
原因: 迭代器里有expectedModCount(期望的修改值)和modCount(修改值)。当对集合进行删除操作时,首先会判断两值是否相等,不相等就抛出异常,而在迭代器里进行删除时,modcount+1了导致两者不等抛出异常,而是用迭代器本身的remove确不会,因为在方法内部更改了其值。
增强for循环
格式:
for(元素的数据类型 变量 : Collection集合or数组){
//写操作代码
}
**它的内部原理其实是个Iterator迭代器。所以尽量避免遍历时进行删除操作**
例子:
public class Main {
public static void main(String[] args) {
// 创建集合对象
Collection<String> collection = new ArrayList<String>();
// 添加数据
collection.add("张三");
collection.add("李四");
collection.add("王五");
System.out.println(collection);
for (String s : collection) {
System.out.println(s);
}
System.out.println("===============");
int[] arr={1,2,3,4};
System.out.println(arr);
for (int i : arr) {
System.out.println(i);
}
}
}
Collections:集合工具类
常用方法
- public static boolean addAll(Collection c, T… elements)
:往集合中添加一些元素。 - public static void shuffle(List<?> list) 打乱顺序 :打乱集合顺序。
- public static void sort(List list) :将集合中元素按照默认规则排序。
- public static void sort(List list,Comparator<? super T> )
:将集合中元素按照指定规则排序。
例子:
public class Main {
public static void main(String[] args) {
ArrayList<Integer> list=new ArrayList<>();
//添加元素
Collections.addAll(list,1,2,3);
System.out.println(list);
//打乱元素
Collections.shuffle(list);
System.out.println(list);
//排序,默认升序
Collections.sort(list);
System.out.println(list);
}
}
结果:
[1, 2, 3]
[3, 1, 2]
[1, 2, 3]
Comparable和Comparator的区别
- Comparable:强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的compareTo方法被称为它的自然比较方法。只能在类中实现compareTo()一次,不能经常修改类的代码实现自己想要的排序。实现此接口的对象列表(和数组)可以通过Collections.sort(和Arrays.sort)进行自动排序,对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器。
- Comparator强行对某个对象进行整体排序。可以将Comparator 传递给sort方法(如Collections.sort或Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用Comparator来控制某些数据结构(如有序set或有序映射)的顺序,或者为那些没有自然顺序的对象collection提供排序。