Collection接口
public static void main(String[] args) {
Collection collection = new ArrayList();
//增
collection.add("苹果");
collection.add("西瓜");
collection.add("菠萝");
collection.add("榴莲");
//删
collection.remove("菠萝");
//collection.clear();清空集合
//遍历
//增强for
for(Object object : collection){
System.out.println(object);
}
//迭代器
Iterator iterator = collection.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//判断
System.out.println(collection.contains("草莓"));//false
System.out.println(collection.isEmpty());//false
}
List接口
List集合的特点:有序、有下标、元素可以重复
public static void main(String[] args) {
List list = new ArrayList();
//增加
list.add("苹果");
list.add("小米");
list.add(0,"华为");
System.out.println(list);//[华为, 苹果, 小米]
//删除
//arrayList.remove(1);
list.remove("苹果");
list.add(20);
//arrayList.remove((Object) 20);
list.remove((new Integer(20)));
//遍历
//for
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
//增强for
for(Object object : list){
System.out.println(object);
}
//迭代器
Iterator iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//列表迭代器 ListIterator可以向前或向后遍历、添加、删除、修改元素
ListIterator listIterator = list.listIterator();
//向后迭代
while (listIterator.hasNext()){
System.out.println(listIterator.nextIndex()+":"+listIterator.next());
//0:华为
//1:小米
}
//向前迭代
while (listIterator.hasPrevious()){
System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
//1:小米
//0:华为
}
//sublist
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
System.out.println(list);//[华为, 小米, 1, 2, 3, 4, 5]
System.out.println(list.subList(2,7));//[1, 2, 3, 4, 5]
}
关于List的遍历删除,有一个关于foreach的坑
@Test
public void test1() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
for(int num: list) {
if (num == 2) {
list.remove(num);
}
}
System.out.println(StringUtils.join(list, ","));
}
这样会报异常
java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:909)
at java.util.ArrayList$Itr.next(ArrayList.java:859)
...
解决方案
@Test
public void test2() {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
List<Integer> tmp = new ArrayList<>();
for(int num: list) {
if (num == 2) {
tmp.add(num);
}
}
list.removeAll(tmp);
System.out.println(StringUtils.join(list, ","));
}
详情点击这里
List接口实现类
- ArryList 数组结构实现,查询快,增删满。运行效率快,线程不安全
- Vector 数组结构实现,查询快,增删慢。运行效率慢,线程安全
- LinkedList 链表结构实现,增删快,查询慢
ArrayList
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
Student student1 = new Student("张三",18);
Student student2 = new Student("李四",19);
Student student3 = new Student("王五",20);
Student student4 = new Student("赵六",21);
//增
arrayList.add(student1);
arrayList.add(student2);
arrayList.add(student3);
arrayList.add(student4);
System.out.println(arrayList);
//[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='王五', age=20}, Student{name='赵六', age=21}]
//删
arrayList.remove(student4);
System.out.println(arrayList);//[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='王五', age=20}]
//遍历
//for
for (int i=0;i<arrayList.size();i++){
System.out.println(arrayList.get(i));
}
//增强for
for(Object object : arrayList){
System.out.println(object);
}
//迭代器
Iterator iterator = arrayList.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//列表迭代器
ListIterator listIterator = arrayList.listIterator();
//正向迭代
while (listIterator.hasNext()){
System.out.println(listIterator.nextIndex()+":"+listIterator.next());
}
//逆向迭代
while (listIterator.hasPrevious()){
System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
}
//判断
System.out.println(arrayList.contains(student3));//true
//查找
System.out.println(arrayList.indexOf(student1));//0
}
Vector与LinkedList
Vector和LinkedList的使用方法与ArrayList相同,不再演示
泛型
泛型中的<T>只能为引用类型(Integer)
泛型类
public class MyGeneric<T>{
T t;
//泛型作为方法的参数
public void show(T t){
System.out.println(t);
}
//泛型作为方法的返回值
public T getT(){
return t;
}
}
泛型类的使用
public static void main(String[] args) {
MyGeneric<String> myGeneric = new MyGeneric<>();
myGeneric.t = "Hello";
myGeneric.show("world");//world
System.out.println(myGeneric.getT());//Hello
MyGeneric<Integer> myGeneric1 = new MyGeneric<>();
myGeneric1.t = 100;
myGeneric1.show(200);
System.out.println(myGeneric1.getT());
}
泛型类的接口
public interface MyInterface <T>{
String name = "张三";
T server(T t);
}
接口的实现类
//在实现类中确定类型
public class MyInterfaceImpl implements MyInterface<String >{
@Override
public String server(String s) {
System.out.println(s);
return null;
}
}
//在实现类中使用泛型
public class MyInterfaceImpl2<T> implements MyInterface<T>{
@Override
public T server(T t) {
System.out.println(t);
return null;
}
}
接口的使用
public static void main(String[] args) {
MyInterfaceImpl myInterface = new MyInterfaceImpl();
myInterface.server("你好");
MyInterfaceImpl2 myInterfaceImpl2 = new MyInterfaceImpl2();
myInterfaceImpl2.server("世界");
MyInterfaceImpl2 myInterfaceImpl21 = new MyInterfaceImpl2();
myInterfaceImpl21.server(404);
}
泛型方法
public <T> void show(T t){
System.out.println(t);
//return t;
}
public static void main(String[] args) {
Test06 test06 = new Test06();
test06.show("Hello world");
}
泛型集合
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Hello");
arrayList.add(" ");
arrayList.add("World");
System.out.println(arrayList);//[Hello, , World]
}
Set接口
Set集合的特点:无序、无下标、元素不可重复
public static void main(String[] args) {
//创建集合
Set<String> set = new HashSet<>();
//增
set.add("小米");
set.add("华为");
set.add("苹果");
set.add("三星");
System.out.println("数据个数:"+set.size()+" 集合内容"+set);//数据个数:4 集合内容[苹果, 华为, 小米, 三星]
//删
set.remove("三星");
System.out.println(set);//[苹果, 华为, 小米]
//遍历
//增强for
for(Object object : set){
System.out.println(object);
}
//迭代器
Iterator iterator = set.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
//判断
System.out.println(set.contains("华为"));
}
Set接口实现类
- HashSet(重点) 基于HashCode计算元素存放位置实现元素不重复
- TreeSet 基于排列顺序实现元素不重复
HashSet
存储过程
(1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步
(2)在执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
hashSet.add("明");
hashSet.add("日");
hashSet.add("方");
hashSet.add("舟");
hashSet.add("终末地");
System.out.println(hashSet);//[日, 终末地, 方, 明, 舟]
hashSet.remove("终末地");
System.out.println(hashSet);//[日, 方, 明, 舟]
for (Object object : hashSet){
System.out.println(object);
}
Iterator iterator = hashSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println(hashSet.contains("终末地"));
}
TreeSet
特点:
- 基于排列顺序实现元素不重复
- 实现了SortedSet接口,对集合元素自动排序
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过CompareTo方法确定是否为重复元素
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>();
//增
treeSet.add("abc");
treeSet.add("xyz");
treeSet.add("hello");
treeSet.add("唐");
System.out.println(treeSet.size()+" "+treeSet);//4 [abc, hello, xyz, 唐]
//注意添加对象时需要实现compareTo方法
TreeSet<Student> studentTreeSet = new TreeSet<>();
Student student1 = new Student("张三",18);
Student student2 = new Student("李四",19);
Student student3 = new Student("王五",20);
Student student4 = new Student("赵六",21);
studentTreeSet.add(student1);
studentTreeSet.add(student2);
studentTreeSet.add(student3);
studentTreeSet.add(student4);
System.out.println(studentTreeSet);
//[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='王五', age=20}, Student{name='赵六', age=21}]
//删
treeSet.remove("xyz");
System.out.println(treeSet);//[abc, hello, 唐]
//遍历
//增强for
for (Object o : treeSet){
System.out.println(o);
}
//迭代器
Iterator<String> iterator = treeSet.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
实现compareTo( )方法的Student类
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name,int age){
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.getAge()-o.age;
return n1==0?n2:n1;
}
}
通过匿名内部类的Comparator接口实现比较器
public static void main(String[] args) {
TreeSet<Student> studentTreeSet = new TreeSet<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n1 = o1.getName().compareTo(o2.getName());
int n2 = o1.getAge()-o2.getAge();
return n1==0?n2:n1;
}
});
Student student1 = new Student("张三",18);
Student student2 = new Student("李四",19);
Student student3 = new Student("王五",20);
Student student4 = new Student("赵六",21);
studentTreeSet.add(student1);
studentTreeSet.add(student2);
studentTreeSet.add(student3);
studentTreeSet.add(student4);
System.out.println(studentTreeSet);
//[Student{name='张三', age=18}, Student{name='李四', age=19}, Student{name='王五', age=20}, Student{name='赵六', age=21}]
}
Map接口
特点:
- 用于存储任意键值对(Key-Value)
- 键:无序、无下标、不允许重复(唯一)
- 值:无序、无下标、允许重复
public static void main(String[] args) {
Map<String , String> stringMap = new HashMap<>();
stringMap.put("cn","中国");
stringMap.put("us","美国");
stringMap.put("uk","英国");
stringMap.put("jp","日本");
System.out.println(stringMap);//{uk=英国, jp=日本, cn=中国, us=美国}
stringMap.remove("jp");
System.out.println(stringMap);//{uk=英国, cn=中国, us=美国}
//keySet
/*Set<String> keySet = stringMap.keySet();
for(String key : keySet){
System.out.println(key+"="+stringMap.get(key));
}*/
for(String key : stringMap.keySet()){
System.out.println(key+"="+stringMap.get(key));
}
//entrySet()方法 效率更高
Set<Map.Entry<String,String>> entries = stringMap.entrySet();
for(Map.Entry<String,String> entry: entries){
System.out.println(entry);
}
}
Map接口实现类
- HashMap 线程不安全,运行效率快;允许null作为key或value
- Hashtable 线程安全,运行效率慢;不允许null作为key或value,实际几乎已被淘汰
- Properties Hashtable的子类,要求key和value都为String,常用于配置文件的读取
- TreeMap 实现了SortedMap接口,可以自动对key进行排序(用法参考TreeSet和HashMap)
HashMap
HashMap是依靠key的hashcode和equals方法来判断重复的,如果操作时new了一个新的对象,相当于开辟了新的空间,hashcode不同,HashMap不会认为是相同对象。如果需要判重,需要重写类中的hashcode和equals方法
public static void main(String[] args) {
HashMap<Person,String> hashMap = new HashMap<>();
Person person1 = new Person("猪八戒",1001);
Person person2 = new Person("孙悟空",1002);
Person person3 = new Person("沙和尚",1003);
hashMap.put(person1,"上海");
hashMap.put(person2,"北京");
hashMap.put(person3,"上海");
System.out.println(hashMap);
//{Person{name='沙和尚', personNo=1003}=上海, Person{name='孙悟空', personNo=1002}=北京, Person{name='猪八戒', personNo=1001}=上海}
//使用new添加相同name和personNo的对象时不会判重,需要重写hashcode和equals方法
/*hashMap.put(new Person("猪八戒",1001),"上海");
System.out.println(hashMap);*/
//{Person{name='沙和尚', personNo=1003}=上海, Person{name='孙悟空', personNo=1002}=北京, Person{name='猪八戒', personNo=1001}=上海, Person{name='猪八戒', personNo=1001}=上海}
//重写hashcode和equals方法后
hashMap.put(new Person("猪八戒",1001),"上海");
System.out.println(hashMap);
//{Person{name='沙和尚', personNo=1003}=上海, Person{name='孙悟空', personNo=1002}=北京, Person{name='猪八戒', personNo=1001}=上海}
//进行了判重,该对象没有添加进hashMap中
//hashMap.remove(person1);
//重写hashcode和equals方法之后可以使用该种方式删除
hashMap.remove(new Person("猪八戒",1001));
System.out.println(hashMap);
//keySet
Set<Person > keySet = hashMap.keySet();
for(Person person : keySet){
System.out.println(person+"="+hashMap.get(person));
}
//entry
Set<Map.Entry<Person,String >> entries = hashMap.entrySet();
for (Map.Entry entry : entries){
System.out.println(entry);
}
System.out.println(hashMap.containsKey(person2));//true
//重写hashcode和equals方法之后可以使用该种方式判断
System.out.println(hashMap.containsKey(new Person("孙悟空",1002)));//true
}
重写了hashcode和equals方法的Person类
public class Person {
private String name;
private int personNo;
public Person(String name,int personNo) {
this.name = name;
this.personNo = personNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPersonNo() {
return personNo;
}
public void setPersonNo(int personNo) {
this.personNo = personNo;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", personNo=" + personNo +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return personNo == person.personNo && Objects.equals(name, person.name);
}
@Override
public int hashCode() {
return Objects.hash(name, personNo);
}
}
Collections工具类
- sort() 排序
- binarySearch() 二分查找
- copy() 复制
- reserve() 反转
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(21);
list.add(4);
list.add(9);
list.add(17);
//排序
Collections.sort(list);
System.out.println(list);//[4, 9, 10, 17, 21]
//二分查找
int index = Collections.binarySearch(list,9);
System.out.println(index);//1
//复制 要求两个集合大小相等
List<Integer> list1 = new ArrayList<>();
for (int i=0;i<list.size();i++){
list1.add(0);
}
Collections.copy(list1,list);//[4, 9, 10, 17, 21]
System.out.println(list1);
//反转
Collections.reverse(list);
System.out.println(list);//[21, 17, 10, 9, 4]
}
集合总结
- 集合的概念:对象的容器,和数组类似,定义了对多个对象进行操作的常用方法。
- List集合:有序、有下标、元素可以重复。(ArrayList、LinkedList、Vector)
- Set集合:无序、无下标、元素不可重复。(HashSet、TreeSet)
- Map集合:存储一对数据,无序、无下标、键不可重复、值可重复。(HashMap、TreeMap)
- Collections:集合工具类,定义了除了存取以外的集合常用方法
Comments NOTHING