集合实际上就是一个容器。可以来容纳其它类型的数据。数组其实就是一个集合。
Java 集合主要有 3 种重要的类型:
Collection是最基本的集合接口。它继承自Iterable接口,Iterable表示可迭代的,所以所有的集合元素都是可迭代可遍历的。它有两个子接口:
Collection中能存放什么元素 ?
没有使用泛型之前,Collection中可以存储Object的所有子类型。
使用了泛型之后,Collection中只能存储某个具体的类型。
返回值类型 | 方法名 | 描述 |
---|---|---|
boolean | add(Object e) | 向集合中添加元素 |
int | size() | 获取集合中元素的个数 |
void | clear() | 清空集合 |
boolean | contains(Object o) | 判断当前集合中是否包含元素o |
boolean | remove(Object o) | 删除集合中的某个元素 |
boolean | isEmpty() | 判断该集合中元素的个数是否为0 |
Object[] | toArray() | 调用这个方法可以把集合转换成数组 |
注意:集合不能直接存储基本数据类型,另外集合也不能直接存储java对象,集合当中存储的都是java对象的内存地址(或者说集合中存储的是引用)
//这里存进去的并不是int类型的1200
//这里使用了自动装箱机制 Integer x = new Integer(1200);
c.add(1200);
Iterator常用方法
返回值类型 | 方法名 | 描述 |
---|---|---|
boolean | hasNext() | 如果仍有元素可迭代就返回true |
Object | next() | 返回迭代的下一个元素 |
void | remove() | 从集合中移除next()方法返回的最后一个元素 |
注意:在迭代集合元素的过程中,不能调用集合对象的remove方法删除元素。否则会造成java.util.ConcurrentModificationException异常。正确做法是使用迭代器Iterator提供的remove方法
public static void main(String[] args) {
Collection c1 = new ArrayList(); // 创建集合对象
c1.add(1);// 添加元素
c1.add(2);// 添加元素
c1.add(3);// 添加元素
c1.add(4);// 添加元素
c1.add(1);// 添加元素
// 获取集合迭代器
Iterator it = c1.iterator();
while(it.hasNext()){
Object obj = it.next();
//c1.remove(obj);删除元素之后,集合的结构发生了变化,但是循环下一次的时候并没有重新获取迭代器
it2.remove();// 迭代器去删除时,会自动更新迭代器,并且更新集合
System.out.println(obj);
}
}
List集合中的常用方法
返回值类型 | 方法名 | 描述 |
---|---|---|
void | add(int index,Object element) | 将元素element插入到List集合的index索引处 |
Object | get(int index) | 返回列表index索引处的元素 |
Object | remove(int index) | 删除列表index索引处的元素 |
int | indexOf(Object o) | 返回对象o在List集合中出现的位置索引 |
int | LastIndexOf(Object o) | 返回对象o在List集合中最后一次出现的位置索引 |
List | subList(int fromIndex,int toIndex) | 返回从索引fromIndex(包括)到toIndex处(不包括)处的子集合 |
ArrayList集合底层是一个Object[]数组,默认初始化容量10。ArrayList集合是非线程安全的
public class ArrayListTest{
public static void main(String[] args) {
//List list = new ArrayList();默认初始化容量是10
List list = new ArrayList(4); // 指定初始化容量4
// 集合的size()方法是获取当前集合中元素的个数。不是获取集合的容量。
System.out.println(list1.size()); // 0
list.add(1);
list.add(2);
list.add(3);
list.add(4);
// 再加一个元素
list.add(5);//数组自动扩容,增长到原容量的1.5倍
}
//第一种遍历方式:fori
for(int i = 0; i <list1.size(); i++){
Object elem = list1.get(i);
System.out.println(elem);
}
//第一种遍历方式:foreach
for (Object elem : list1) {
System.out.println(elem);
}
//第一种遍历方式:使用迭代器
Iterator iterator = list1.iterator();
while (iterator.hasNext()){
Object next = iterator.next();
System.out.println(next);
}
}
注意:并不是一创建ArrayList容器对象就初始化容量。底层先创建了一个长度为0的数组,当添加第一个元素的时候,初始化容量10
LinkedList集合底层采用了双向链表的数据结构
LinkedList集合中常用的方法
返回值类型 | 方法名 | 描述 |
---|---|---|
void | addFirst(Object o) | 将元素o添加到集合的开头 |
void | addLast(Object o) | 将元素o添加到集合的结尾 |
Object | getFirst() | 返回集合的首元素 |
Object | getLast() | 返回集合的尾元素 |
Object | removeFirst() | 移除并返回集合的首元素 |
Object | removeLast() | 移除并返回集合的尾元素 |
public class LinkedListTest01 {
public static void main(String[] args) {
// LinkedList集合底层也是有下标的。
// LinkedList集合有初始化容量吗?没有。
List<String> list = new LinkedList();
list.add("a");
list.add("b");
list.add("c");
//第一种遍历方式:fori
for(int i = 0; i <list.size(); i++){
String str = list.get(i);
System.out.println(str);
}
//第一种遍历方式:foreach
for (String str : list) {
System.out.println(str);
}
//第一种遍历方式:使用迭代器
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
String nextStr = iterator.next();
System.out.println(nextStr);
}
}
}
public class VectorTest {
public static void main(String[] args) {
// 创建一个Vector集合
List vector = new Vector();
vector.add(1);
vector.add(2);
vector.add(3);
vector.add(4);
vector.add(5);
Iterator it = vector.iterator();
while(it.hasNext()){
Object obj = it.next();
System.out.println(obj);
}
}
如何将非线程安全的集合转换成线程安全的集合
List myList = new ArrayList(); // 非线程安全的。
// 变成线程安全的
Collections.synchronizedList(myList);
// myList集合就是线程安全的了。
myList.add("111");
myList.add("222");
myList.add("333");
Set集合存储元素的特点:无序不可重复
Set集合没有下标不能使用fori的方式遍历
HashSet集合在new的时候底层实际上new了一个HashMap集合,向HashSet集合中存放元素实际上存储到HashMap集合的key部分、HashMap集合底层是一个哈希表。
public class HashSetTest01 {
public static void main(String[] args) {
// 演示一下HashSet集合特点
Set<String> hashSet= new HashSet<>();
//String类已经重写了hashCode()方法和equals()方法
hashSet.add("hello3");// 添加元素
hashSet.add("hello4");
hashSet.add("hello1");
hashSet.add("hello2");
hashSet.add("hello3");
hashSet.add("hello3");
hashSet.add("hello3");
hashSet.add("hello3");
//第一种遍历方式:foreach
for(String s : hashSet){
System.out.println(s);
}
//第二种遍历方式:迭代器
Iterator<String> iterator = hashSet.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
【运行结果】
hello1
hello4
hello2
hello3
Process finished with exit code 0
【结论】
1、存储时顺序和取出的顺序不同。
2、不可重复。
3、放到HashSet集合中的元素实际上是放到HashMap集合的key部分了。
HashSet集合是如何保证添加元素时不出现重复的 ?
保证不重复的关键在于出入对象的hashCode()方法和equals()方法。向HashSet集合中存入对象时,首先调用对象的hashCode()方法获取对象的哈希值,然后根据哈希值计算处存储位置。如果该位置上没有元素就将元素存入,如果该位置上已有元素则调用equals()方法比较两个元素是否相同,如果不相同则通过探测再散列的方法找到一个新的位置将元素存入,如果相同就不存入元素
TreeSet集合在new的时候底层实际上new了一个TreeMap集合,向TreeSet集合中存放元素实际上存储到TreeMap集合的key部分。TreeMap集合底层是一个二叉树。
TreeSet集合存储元素特点:
1、无序不可重复的,但是存储的元素可以自动按照大小顺序排序!
2、无序:这里的无序指的是存进去的顺序和取出来的顺序不同。并且没有下标。
TreeSet中定义的方法
返回类型 | 方法名 | 描述 |
---|---|---|
Object | first() | 返回集合中的最低元素 |
Object | last() | 返回集合中的最高元素 |
Comparator<? super E> | comparator() | 返回对此集合中元素进行排序的比较器 |
public class TreeSetTest01 {
public static void main(String[] args) {
// 创建集合对象
Set<String> strs = new TreeSet<>();
// 添加元素
strs.add("A");
strs.add("B");
strs.add("Z");
strs.add("Y");
strs.add("Z");
strs.add("K");
for(String s : strs){
System.out.print(s+" ");//从小到大自动排序
}
}
}
【输出结果】
A B K M Y Z
Process finished with exit code 0
TreeSet集合中自定义类型元素可排序的二种方式
//1、实现Comparable接口并且重写compareTo方法
public class Customer implements Comparable<Customer>{
int age;
public Customer(int age){
this.age = age;
}
public int compareTo(Customer c) {
return c.age - this.age;
}
}
//2、使用比较器
public class TreeSetTest {
public static void main(String[] args) {
// 给构造方法传递一个比较器。(匿名内部类)也可以单独编写一个比较器
TreeSet<Customer> customerList = new TreeSet<>(new Comparator<WuGui>() {
@Override
public int compare(Customer c1, Customer c2) {
return c1.age - c2.age;
}
});
customerList.add(new Customer(20));
customerList.add(new Customer(30));
customerList.add(new Customer(18));
for(Customer customer: customerList){
System.out.println(customer);
}
}
}
Comparable和Comparator怎么选择呢 ?
返回值类型 | 方法名 | 描述 |
---|---|---|
void | put(K key, V value) | 向Map集合中添加键值对 |
Object | get(Object key) | 通过key获取value |
void | clear() | 清空Map集合 |
boolean | containsKey(Object key) | 判断Map中是否包含某个key |
boolean | containsValue(Object value) | 判断Map中是否包含某个value |
boolean | isEmpty() | 判断Map集合中元素个数是否为0 |
V | remove(Object key) | 通过key删除键值对 |
int | size() | 获取Map集合中键值对的个数。 |
Collection<V> | values() | 获取Map集合中所有的value,返回一个Collection |
Set<K> | keySet() | 获取Map集合所有的key(所有的键是一个set集合) |
Set<Map.Entry<K,V>> | entrySet() | 将Map集合转换成Set集合 |
public class MapTest {
public static void main(String[] args) {
Map<Integer, String> map = new HashMap<>();
map.put(1, "zhangsan");
map.put(2, "lisi");
map.put(3, "wangwu");
map.put(4, "zhaoliu");
// 第一种方式:获取所有的key,通过遍历key,来遍历value
Set<Integer> keys = map.keySet();
for(Integer key : keys){// foreach遍历,当然也可以使用迭代器遍历
System.out.println(key + "=" + map.get(key));
}
// 第二种方式:Set<Map.Entry<K,V>> entrySet()
// 这个方法是把Map集合直接全部转换成Set集合。
// Set集合中元素的类型是:Map.Entry
Set<Map.Entry<Integer,String>> set = map.entrySet();
for(Map.Entry<Integer,String> node : set){// foreach遍历,当然也可以使用迭代器遍历
System.out.println(node.getKey() + "--->" + node.getValue());
}
}
}
public class HashMapTest {
public static void main(String[] args) {
// Integer是key,它的hashCode和equals都重写了。
Map<Integer,String> map = new HashMap<>();
map.put(1, "zhangsan");
map.put(6, "lisi");
map.put(7, "wangwu");
map.put(2, "zhaoliu");
map.put(2, "king"); //key重复的时候value会自动覆盖。
System.out.println(map.size()); // 4
// 遍历Map集合
Set<Map.Entry<Integer,String>> set = map.entrySet();
for(Map.Entry<Integer,String> entry : set){
// 验证结果:HashMap集合key部分元素:无序不可重复。
System.out.println(entry.getKey() + "=" + entry.getValue());
}
}
}
Map map = new Hashtable();
map.put(null, "123");//NullPointerException
map.put(100, null);//NullPointerException
public class PropertiesTest {
public static void main(String[] args) {
// 创建一个Properties对象
Properties pro = new Properties();
// 需要掌握Properties的两个方法,一个存,一个取。
pro.setProperty("url", "jdbc:mysql://localhost:3306/whydb");
pro.setProperty("driver","com.mysql.jdbc.Driver");
pro.setProperty("username", "root");
pro.setProperty("password", "123");
// 通过key获取value
String url = pro.getProperty("url");
String driver = pro.getProperty("driver");
String username = pro.getProperty("username");
String password = pro.getProperty("password");
System.out.println(url);
System.out.println(driver);
System.out.println(username);
System.out.println(password);
}
}
TreeMap集合也是用来存储键值映射关系的,TreeMap不允许出现重复的键,该映射关系根据其键的自然顺序进行排序,或者根据创建映射时提供的Comparator进行排序。TreeMap的底层采用了二叉树这种数据结构
public class HashtableTest01 {
public static void main(String[] args) {
Map<Integer,String > treeMap = new TreeMap<>();
treeMap.put(1,"张三");
treeMap.put(9,"李四");
treeMap.put(8,"王五");
treeMap.put(2,"赵六");
Set<Map.Entry<Integer, String>> entries = treeMap.entrySet();
for (Map.Entry<Integer, String> entry : entries) {
System.out.println(entry.getKey()+"=="+entry.getValue());
}
}
}
【运行结果】
1==张三
2==赵六
8==王五
9==李四
Process finished with exit code 0
Collections常用方法
返回类型 | 方法名 | 描述 |
---|---|---|
static boolean | addAll(Collection<? super T>,T…elements) | 将所有指定元素添加到Collection中 |
static void | reserve(List<?> list) | 反转指定列表中的元素 |
static void | shuffle(List<?> list) | 使用默认随机源对指定列表进行置换 |
static void | sort(List<?> list) | 根据元素的自然顺序进行升序排序 |
static void | swap(List<?> list,int i,int j) | 将指定列表中i处元素和j处元素进行交换 |
static int | binarySearch(List<?> list,Object key) | 使用二分查找搜索指定列表 |
static Object | max(Collection col) | 根据元素的自然顺序返回给定集合中的最大元素 |
static Object | min(Collection col) | 根据元素的自然顺序返回给定集合中的最小元素 |
static boolean | replaceAll(List list,Object oldVal,Object newVal) | 使用newVal替换列表中所有的oldVal |
static List<T> | synchronizedList(List<T> list) | 将指定集合转换成线程安全 |
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/m0_60117382/article/details/123759352
内容来源于网络,如有侵权,请联系作者删除!