- Collection、Set、List、Queue接口
Collection、Set、List、Queue是Java中的四种接口,它们都属于Java集合框架的一部分。Collection是所有集合类的根接口,Set接口继承了Collection接口,并且不允许集合中包含重复的元素;List接口也继承了Collection接口,但是允许集合中包含重复的元素,并且可以通过索引来访问集合中的元素;Queue接口则继承了Collection接口,但是它是一个队列,支持在队列头部插入元素,在队列尾部删除元素。
Collection根接口包含了:
add添加
contains包含
boolean 判断是否为空
Iteartor 迭代器
remove 移除
int size()索引大小
具体解释:Collection接口提供了多个方法来操作集合元素,其中包括add、contains、isEmpty、iterator、remove和size。add方法用于向集合中添加元素,contains方法用于判断集合中是否包含指定元素,isEmpty方法用于判断集合是否为空,iterator方法返回一个迭代器用于遍历集合中的元素,remove方法用于从集合中移除指定元素,size方法返回集合中元素的个数。这些方法的使用可以帮助我们更加方便地操作集合。
2.List接口支持索引访问,适用于有序但元素可能重复的集合。
ArrayList在底层会创建一个新的内存数组来存储数据,这意味着当需要添加或移除元素时,需要重新分配内存并复制元素。这样的操作会导致性能下降,因此如果需要频繁添加或移除元素,建议使用LinkedList。LinkedList使用链表来存储元素,可以快速添加或移除元素,但是访问元素的性能较差。因此,在选择数据结构时,需要根据具体的需求来进行选择。
LinkedList是一种链表结构,它提供了一组专门用于处理集合中第一个和最后一个元素的方法。
LinkedList底层实现是一个双向链表,每个节点都包含指向前一节点和后一节点的引用。这种数据结构使得在LinkedList中插入和删除元素更加高效,因为只需要改变相邻节点的引用即可。同时,LinkedList也支持随机访问,但是由于需要遍历整个链表(一个一个数过去),所以效率相对较低。
实例OddEven.java
[qzdypre]
import java.util.*;
public class OddEven {
//对参数list进行初始化
private static void initial(List<Integer> list,int size){
Random random=new Random(1);
for (int i=0;i<size;i++){
list.add(random.nextInt(10000000));
}
}
// private static void removeEven(List<Integer> list){
// for(int i=list.size()-1;i>=0;i--){
// if(list.get(i) % 2==0){
// list.remove(i);
// }
// }
// }
private static void removeEven(List<Integer> list){
Iterator<Integer> iterator=list.iterator();
int current;
while (iterator.hasNext()){
current=iterator.next();
if(current % 2==0){
iterator.remove(); //用迭代器来提高性能
}
}
}
public static void main(String[] args) {
final int SIZE=10000000;
List<Integer> list=new LinkedList<>();
initial(list,SIZE);
long start=System.currentTimeMillis();
removeEven(list);
long end=System.currentTimeMillis();
System.out.println(end-start);
}
}
[/qzdypre]
综上所述
ArrayList的性能较慢是因为每次对数组进行修改时,它都会创建一个新的数组来进行修改,导致重复操作。
LinkedList的性能较慢是由于其在访问元素时需要遍历整个链表(不会记录索引,每次都要从头加上数),而不像ArrayList可以通过索引直接访问元素。此外,LinkedList还需要额外的内存空间来存储节点间的指针信息。
迭代器会记录索引,这意味着它可以跟踪当前正在处理的元素的位置。(比如当这次数到5,下次访问位置10时不需要从1开始而是从5开始)通过使用迭代器,我们可以简化代码并提高程序的可读性和可维护性。
所以我们要根据程序不同要求来选用ArrayList或LinkedList。
3.Set接口
Set接口继承了Collection接口,类似于数学中的集合,具有无序性和非重复性。
例如{2,3}={3,2},这两个集合在数学中是相等的。
填充因子是一个用于动态数组或哈希表等数据结构中的参数。它表示在何时进行扩容操作,即当数据元素的数量达到容量的一定比例时,就会自动扩容以增加容量。这个比例就是填充因子。一般情况下,填充因子的取值范围为0到1之间。例如,当填充因子为0.75时,表示当数据元素的数量达到容量的75%时,就会进行扩容操作。这样可以避免频繁扩容,提高数据结构的性能。
set是一种数据结构,可以支持add和remove操作。使用add操作时,可以根据索引添加元素。而使用remove操作时,只能通过元素值来移除元素,因为set中元素是不可以重复的。这意味着,如果要添加一个已经存在的元素,它将不会被添加到set中(返回false)。同样地,如果要移除一个不存在的元素,它也不会产生任何影响。
HashSet在底层会维护一个数组,用来存储元素的位置。当元素被添加到HashSet中时,HashSet会根据元素的哈希值确定该元素在数组中的位置。如果该位置已经存在元素,那么HashSet会维护一个链表,将新元素添加到该链表的末尾。当需要查找元素时,HashSet首先根据元素的哈希值找到该元素在数组中的位置,然后遍历该位置上的链表,直到找到目标元素或者链表结束。这种设计可以使HashSet在添加、查找元素时具有较高的效率。
使用HashSet储存字符串时,输出顺序不保证与添加顺序相同。但是,如果使用LinkedHashSet,则可以按照添加顺序输出。
4.TreeSet接口
如果要使用TreeSet,其参数类型必须实现Comparable接口,否则需要在TreeSet对象上添加一个比较器。
(使用TreeSet时,如果参数类型没有实现Comparable接口,那么需要在TreeSet对象上添加一个比较器,否则会抛出ClassCastException异常。这是因为TreeSet是一个有序的集合,它需要对元素进行比较来确定它们的顺序。如果元素没有实现Comparable接口,那么就需要提供一个比较器来帮助TreeSet进行比较。比较器可以通过实现Comparator接口来创建,并将其传递给TreeSet的构造函数或使用setComparator()方法设置。)
实例TestTreeSet.java
[qzdypre]
import java.util.Comparator;
import java.util.TreeSet;
class Employee implements Comparable<Employee> {
int id;
double salary;
public Employee(int id, double salary) {
this.id = id;
this.salary = salary;
}
public int getId() {
return id;
}
public double getSalary() {
return salary;
}
@Override
public String toString() {
return "Employee{" +
"id=" + id +
", salary=" + salary +
'}';
}
@Override
public int compareTo(Employee o) {
return this.id-o.id;
}
}
public class TestTreeSet {
public static void main(String[] args) {
TreeSet<Employee> ts = new TreeSet<>(new Comparator<Employee>() { //优先输出
@Override
public int compare(Employee o1, Employee o2) {
return (int) (o1.getSalary()- o2.getSalary());
}
});
ts.add(new Employee(2,20000));
ts.add(new Employee(1,25000));
ts.add(new Employee(3,18000));
System.out.println(ts);
}
}
[/qzdypre]
当使用compareTo()方法和Comparator进行排序时,如果两者都存在,Java会优先使用Comparator进行排序,而不是使用对象自身的compareTo()方法。这是因为Comparator可以提供更灵活的排序方式,而且可以对任何类进行排序,而不需要修改类本身的代码。因此,在使用Java集合框架进行排序时,我们可以根据需要选择使用compareTo()方法或Comparator进行排序。
5.Map接口
Map接口是一个Java集合框架中的接口,它表示一种映射关系,即一组键(key)和对应的值(value)之间的映射。Map集合中的每个元素都包含了一个键值对(key-value pair),其中键唯一且不可重复,它用来标识该元素;值可以是任何类型的Java对象,可以重复,用来表示该元素对应的信息。
Map集合中提供了一系列操作键值对的方法,包括添加、删除、修改、查询等。常见的实现类有HashMap(性能最高)、TreeMap(自动排序,但键的类型必须实现Comparable接口)、LinkedHashMap等。
- put(Object key, Object value):将指定键与指定值相关联,如果key已经存在,则用新的value替换旧的value,并返回旧的value。
- get(Object key):返回指定键所映射的值,如果该键不存在,则返回null。
- remove(Object key):移除指定键所映射的值,并返回该键对应的value。
- containsKey(Object key):判断该Map中是否包含指定的键。返回的是布尔值(true/false)
- containsValue(Object value):判断该Map中是否包含指定的值。返回的是布尔值(true/false)
- size():返回该Map中键值对的数量。
实例TestMap.java
[qzdypre]
import java.util.*;
public class TestMap {
public static void main(String[] args) {
Map<String, String> map = new HashMap<>();
map.put("南通", "0513");
map.put("北京", "010");
map.put("南京", "025");
map.put("上海", "010");
// map.remove("南通");
// System.out.println(map.containsValue("0513"));
for (String city : map.keySet()) { //keySet得到所有键构成的数学集
System.out.println(city);
}
Collection<String> postCodes = map.values(); //得到所有的值构成的集合
for(String code:postCodes){ //通过迭代器来迭代
System.out.println(code);
}
System.out.println(map);
}
}
[/qzdypre]
请注意以上的注释部分,有相关代码说明
keySet()方法返回一个包含映射中所有键的 Set 集合
values()方法返回一个包含映射中所有值的 Collection 集合
entrySet()方法返回一个包含映射中所有键值对的 Set 集合;通过getKey获取键,getValue获取值
文章评论