集合分为两种,Collection和Map。
Collection
1.1List接口
- 接口方法有很多,详见API
- 实现类
- ArrayList -> 底层实现为数组
- LikedList -> 底层实现是双向链表
- Vector ->底层实现为数组,线程安全的集合
- Stack ->是Vector的子类
常用的List的实现类是ArrayList和LinkedList,两者的比较: - 数组的增删效率不高,查询效率高,链表的增删效率高,查询效率不高。
- 如果需要频繁的进行元素的增删,使用LinkedList较好
- 如果增删不频繁,查询频繁,使用ArrayList较好
部分代码:
List<String> list = new ArrayList<>();
//添加元素
list.add("xiaoming");
//在指定下标插入一个元素
list.add(0, "xiaoli");
//将一个集合中所有的元素批量的插入到指定的下标位置
list.addAll(1, list);
//删除下标为2的元素
list.remove(2);
//将所有的名字长度<7的元素改为全大写
list.repalceAll(ele -> ele.length() < 7 ? ele.toUpperCase() : e);
//修改指定下标的元素
list.set(1, "lily");
//获取指定下标的元素
System.out.println(list.get(i));
//迭代器
list<Integer> list2 = new ArrayList<>();
for(int i = 0; i<= 20; i++){
list2.add(i);
}
ListIterator<Integer> li = list.iterator();
//ListIterator是Iterator的子类,是可以修改值和从后往前遍历的
while(li.hasNext()){
Integer ele = li.next();
if(ele == 10){
li.set(100);
}
if(ele == 15){
li.add(150);
}
}
//增强for循环遍历输出
for(Integer i : list){
System.out.println(i);
}
对对象进行排序有几种方法,都可以实现排序
List<Person> list = new ArrayList<>();
list.add(new Person("xiaoming", 18));
list.add(new Person("xiaoli", 15));
list.add(new Person("xiaobai", 19));
//按年龄从小到大排序
//第一种方法
list.sort((o1, o2) -> o1.age - o2.age);
//第二种方法
Collections.sort(list,(o1, o2) -> o1.age - o2.age);
//第三种方法需要Person类实现Comparable接口,并重写compareTo方法
Collections.sort(list);
class Person implements Comparable<Person>{
//属性和构造方法、setter和getter方法略
public int compareTo(Person o){
return this.age - o.age;
}
}
1.2 Set接口
Set接口的特点:
- Set集合是一个去重的集合,不允许出现重复的元素。
- Set集合没有下标的概念。
部分代码
Set<String> set = new HashSet<>();
set.add("hello");
set.add("world");
//Set是一个去重的集合
//去重原理:判断每一个元素的hashCode,如果不同则视为不同元素,如果
//相同再使用equals方法比较,如果相同视为相同元素,不同则视为不同
//元素。
Set<Person> set = new HashSet<>();
set.add(new Person("xiaoming", 10));
set.add(new Person("xiaoming", 10));
//输出元素可以看到,set里面有两个小明10岁的元素,并没有去重
//这里如果要去重,那么需要重写hashCode和equals方法
LinkedHashSet<String> set = new LinkedHashSet<>();
set.add("hello");
set.add("world");
//去重的,规则与HashSet相同
//是有序的,添加的顺序与存储的顺序一致
//TreeSet是Set接口常用的实现类之一,底层实现是红黑树
//它是一个去重,并自带排序的集合
//在TreeSet中进行元素比较的方法,如果返回0会被认为是相同的元素,然后去重
TreeSet<Dog> set = new TreeSet<>();
set.add(new Dog("哈士奇", 1));
set.add(new Dog("泰迪", 2));
set.add(new Dog("英斗", 3));
set.add(new Dog("英斗", 3));
//这是无法编译进行输出的,会抛出一个ClassCastException
set.forEach(System.out:println);
//这时想要解决异常的问题,就要实现Comparable接口,并重写compareTo方法
class Dog implements Comparable<Dog>{
String name;
int age;
public Dog(){}
public Dog(String name, int age){
this.name = name;
this.age = age;
}
public int compareTo(Dog d){
if(this.age >= d.age)
return 1;
return -1;
}
public String toString(){
return "[name = " + name + " age = " + age +"]";
}
}
//经过实现接口和重写compareTo方法,我们实现了两个名字为英斗和年龄为3的两个相同元素的添加
Map
Map集合和Collection集合都是java集合框架重要组成部分。
与Collection不同的是,Map中存储的都是键值对形式存在的数据。
注意:
map中不允许出现重复的键
键值对
由一个键key和一个值value组成的数据存储单元。键和值是一一对应的,一个键对应一个值。不允许出现一个键对应多个值,也不允许出现一个值对应多个键,也不允许出现一个键,没有值。。。
部分代码:
Map<String, String> map = new HashMap<>();
//增:讲一个键值对添加到map中
map.put("name", "xiaoming");
map.put("age", "10岁");
//如果两个键相同,则后一个会覆盖前一个键值对
map.put("name", "laowang");
//增加一组元素
map.putAll(map);
//删除,通过一个键删除键值对
//返回值是被删除的键值对中的值
String value = map.remove("age");
//删除。键值对删除,返回boolean值
boolean b = map.remove("name", "xiaoming");
//清空元素
map.clear();
//修改
map.replace("name", "xiaowang");
map.replace("name", "laowang", "dawang");
map.replaceAll((k, v) -> k.toUpperCase());
//查询
map.get("name");
map.get("age");
Set<String> keys = map.keySet();
for(String ky :kes){
System.out.println(String.format("%s = %s", key, map.get(key)));
}
//entrySet:返回由每一个键和值组成的键值对的set集合
Set<Map.Entry<String, String>> set = map.entrySet();
for(Map.Entry<String, String> entry : set){
String k = entry.getKey();
String v = entry.getValue();
System.out.printf("%s = %s\n", k, v);
if(v.equals("xiaowang")){
entry.setValue("wangxiongdi");
}
}
//获取集合中有多少个元素
map.size();
//判断集合中是否包含指定的键
map.containsKey(key);
//比较类似与TreeSet是一个自带排序的Map集合
//对键进行排序
TreeMap<Integer, String> map = new TreeMap<>();
map.put(1, "1");
map.put(2, "2");
map.put(0, "0");
map.put(3, "3");
HashMap和HashTable的区别:
- HashMap线程不安全,HashTable线程安全
- HashMap执行效率高,HashTable执行效率低
- HashMap中允许出现null键和null值,HashTable不允许
- HashMap是Map集合新的实现方式,父类是AbstractMap;Hashtable是旧的实现方式,父类是Dictionary
- HashMap的效率比Hashtable效率高
TreeMap
可以对集合中的键值对,按照键进行排序,排序的依据如下:
- 让键对应的类实现Comparable接口
- 在实例化TreeMap的时候,通过一个Comparator接口进行实例化,定制一个大小比较的依据
Collections工具类
LinkedList<Integer> list = new LinkedList<>();
//向指定的集合中添加元素
Collections.addAll(list, 1, 2, 3, 6, 4, 8, 7);
//对集合进行排序,需要对应的类实现comparable接口,重写compareTo方法
Collections.sort(list);
Collections.sort(list, (o1, o2) -> o1.age - o2.age);
//对集合进行倒叙
Collections.reverse(list);
//对集合中的元素进行随机排列
Collections.shuffle(list);
//采用二分法,对集合进行查询
Collections.binarySearch(list, 5);
//将一个线程不安全的集合,转成一个线程安全的集合,并返回
List<Integer> result = Collections.synchronizedList(list);
//元素的拷贝
ArrayList<Integer> ls = new ArrayList<>();
list.forEach(ele -> ls.add(ele));
ls.addAll(list);
Collections.copy(ls, list);
//获取集合中最大元素,需要元素中对应类实现comparable接口的方法进行比较
Collections.max(list);
//获取集合中最大的元素,通过一个指定的comparator接口的方法进行比较
Collections.max(list, (ele1, ele2) -> ele2 - ele1);
//将一个集合中指定的两个下标的元素进行交换
Collections.swap(list, 0, 5);