文章目录
集合
集合体系
单列集合
双列集合
Collection接口
Java中集合类默认使用泛型,如果没有定义集合中存储的数据类型,默认类型为Object类。
collection接口中常用的方法(单列集合中所共有的方法)
import javafx.print.Collation;
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo1 {
public static void main(String[] args) {
Collection<String> c1 = new ArrayList<String>();
c1.add("a"); //添加元素
c1.add("b");
System.out.println(c1); //[a, b]
//c1.clear(); //删除集合中所有元素
System.out.println(c1.contains("a")); //true 是否包含指定元素,包含返回true,否则返回false
System.out.println(c1.isEmpty()); //false 是否为空,为空返回true,不为空返回false
System.out.println(c1.remove("b")); //true 删除指定元素,成功返回true,否则返回false
System.out.println(c1.size()); //1 长度
Collection<String> c2= new ArrayList<String>();
c2.add("c"); //添加元素
c2.add("b");
c1.addAll(C2);//把c2集合添加到c1集合
c1.removeAll(c2);//把c2集合从c1集合中删除
c1.retainAll(c2);//保留两个集合的交集部分,内容改变返回true,不变返回false
}
}
List
ArrayList和LinkedList的区别:
ArrayList:数组列表,基于动态数组,查询快,中间插入、删除效率低。
LinkedList:链表列表,基于链表,查询慢,中间插入、删除效率高。
ArrayList
可重复存储元素
import java.util.ArrayList;
public class ArrayListDemo1 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();//创建对象时不会创建数组,第一次创建时容量为10
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
System.out.println(arrayList.get(4)); //e 获取指定位置的元素
arrayList.add(2, "F"); //在指定位置添加元素
System.out.println(arrayList.indexOf("c")); //3 获取指定元素的索引
arrayList.remove(3); //根据索引删除元素
arrayList.remove("a"); //根据内容删除元素
arrayList.set(2, "D"); //替换指定位置的元素
System.out.println(arrayList.size()); //4 返回列表中的元素数
}
}
扩容机制:
(1)创建对象时创建一个指定容量的数组;
(2)添加前判断元素添加后,数组是否能容纳下,如果可以则直接添加,否则会创建一个新数组(扩容);
(3)扩容为原来的1.5倍
LinkedList
存储重复元素,按照添加顺序排放
import java.util.LinkedList;
public class LinkListDemo {
public static void main(String[] args) {
/*
* LinkedList 存储重复元素 ,按照添加顺序排放
* Node 节点
* E item; 数据
Node<E> next; 后
Node<E> prev; 前
*/
LinkedList<String> llist = new LinkedList<>();
llist.add("a");
llist.add("b");
llist.add("c");
llist.add("d");
llist.add("e");
llist.add("a");
System.out.println(llist.get(2));
System.out.println(llist);
}
}
Vector
底层也是数组实现,是线程安全。
import java.util.Vector;
public class VectorDemo {
public static void main(String[] args) {
/*
Vector 底层也是数组实现
是线程安全
public synchronized boolean add(E e) {
modCount++;
ensureCapacityHelper(elementCount + 1);
elementData[elementCount++] = e;
return true;
}
*/
Vector<String> v = new Vector<>();
v.add("a");
v.add("a");
}
}
List集合接口迭代
(1)for循环
for(int i=0;i<alist.size();i++){
System.out.println(alist.get(i));
}
(2)增强for循环
for(String item:alist){
System.out.println(item);
}
(3)迭代器
Iterator<String> it = alist.iterator();
while(it.hasNext()){
String item = it.next;
if(item.equals("a")){
it.remove();
}
}
Set
不能存储重复的元素,元素无序(指的是添加的顺序),元素没有索引;
set集合只能用增强for循环和迭代器遍历。
HashSet
在添加元素时,先用内容调用hashCode()方法计算出一个hash值(int类型),用哈希值比较是否相同,但是只用哈希值比较是不安全的,这时会调用equals()方法对每个字进行比较。
public class HashSetDemo2 {
public static void main(String[] args) {
//hash值相同,调用equals()进行比较
HashSet<String> set = new HashSet<>();
/*add添加时,先用内容调用hashCode()方法计算出一个hash值(int 类型),
用hash值比较是否相同,效率高,但只用hash值比较不安全,
这时调用equals()方法对每个字符进行比较
*/
set.add("a");
set.add("b");
set.add("通话");
set.add("c");
set.add("重地");
System.out.println(set);
}
}
TreeSet
不重复,可以根据元素进行排序,添加时要对元素进行排序和去重。
public class TreeSetDemo {
public static void main(String[] args) {
//TreeSet不重复可以对元素进行排序
TreeSet<Car> tset = new TreeSet<>();
Car car1 = new Car(1, "宝马1");
Car car2 = new Car(2, "宝马2");
Car car3 = new Car(3, "宝马3");
Car car4 = new Car(1, "宝马1");
Car car5 = new Car(4, "宝马4");
//添加时要对元素进行排序和去重
tset.add(car1);
tset.add(car2);
tset.add(car3);
tset.add(car4);
tset.add(car5);
System.out.println(tset);//[Car{id=1, name='宝马1'}, Car{id=2, name='宝马2'}, Car{id=3, name='宝马3'}, Car{id=4, name='宝马4'}]
}
}
Map
双列存储,键—值,键不允许重复,值可以重复。
HashMap
键值不能重复,排序不固定,可以存储一个为null的键。
public class HashMapDemo1 {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
map.put("a", "aa");
map.put("b", "bb");
map.put("c", "cc");
map.put("d", "dd");
map.put("a", "aaa");
System.out.println(map.containsKey("a"));//true 是否包含指定的键
System.out.println(map.containsValue("cc"));//true 是否包含指定的值
System.out.println(map.get("d"));//dd 根据指定的键,获取对应的值
System.out.println(map.remove("b"));//bb 删除指定的键,返回对应的值
System.out.println(map.size());//3
System.out.println(map);//{a=aaa, c=cc, d=dd}
Set<String> set = map.keySet();//获取map中键的那一列,存放到一个set中
System.out.println(set);//[a, c, d]
Collection<String> list = map.values();//获取map中值的那一列,存放到一个list中
System.out.println(list);//[aaa, cc, dd]
}
}
HashMap的底层实现原理:
哈希函数根据内容的哈希值计算出在哈希表中的位置;
第一次添加元素时会创建哈希表,将元素插入到对应的位置,后面如果有位置相同的元素就放在链表中;
当链表长度大于等于7时,将链表转为红黑树;
当哈希表容量达到整数数组的0.75时,扩容为原来的2倍。
HashTable
不允许为null key ;
线程安全,锁住了整个put(),访问量较小时可以使用,访问量较高时,效率太低了。
TreeMap
可以根据键的自然顺序排序;
key值所在类必须实现Comparable接口。
Collections类
public class CollectionsDemo {
//addAll(Collection<? super T> c, T... elements)
public static void main(String[] args) {
//List<Integer> list = new ArrayList<>();
//Collections.addAll(list, 2,1,3,5,4);
//Collections.sort(list); //排序
/* Collections.sort(list,new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2-o1;
}
}); 自定义倒序排序*/
//System.out.println(Collections.binarySearch(list,4)); //二分查找
//Collections.swap(list, 0, 3); //交换
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(2);
list.add(4);
List<Integer> list1 = new ArrayList<>();
list1.add(5);
list1.add(6);
list1.add(7);
//Collections.copy(list, list1);
//System.out.println(list);
//List<Integer> list2 = Collections.emptyList();//返回一个空集合,集合不能使用 ,避免在判断时候出现空指针
//Collections.fill(list, 5);//用5填充集合中元素
//System.out.println(list);
System.out.println(Collections.max(list));//返回集合中最大元素
System.out.println(Collections.min(list));
//Collections.replaceAll(list, 2,6); //替换,新值替换原值
Collections.reverse(list); //逆序
System.out.println(list);
}
public static void test1() {
test2(1, 2, 3, 4, 5);
}
//int...a 定义可变长度参数,本质是数组,一个参数列表中只能有一个,并且 放在参数列表的最后一位
public static void test2(int b, int... a) {
}
}