集合框架

1.泛型

泛型:允许在编写类、接口和方法时使用类型参数,以在运行时确定具体的数据类型,用于增强类型安全性和代码的可重用性

1.1 泛型类

泛型类:类名<T,...>,T是类型占位符,表示一种引用类型,如果编写多个用逗号隔开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MyGeneric<T> {
//1.创建变量
T t;
//2.使用泛型作为方法的参数
public void show(T y){
System.out.println(t);
}
//3.使用泛型作为方法的返回值
public T getT(){
return t;
}
}
class test2{
public static void main(String[] args) {
//使用泛型类创建对象
MyGeneric<String> myGeneric1=new MyGeneric<>();
myGeneric1.t="hello";
MyGeneric<Integer> myGeneric2=new MyGeneric<>();
myGeneric2.t=100;
myGeneric1.show();
myGeneric2.show();
}
}

注:

1.泛型只能是引用类型

2.不同泛型类型的对象之间不能相互赋值

1.2 泛型接口

泛型接口:接口名<T>

注:不能使用泛型创建静态常量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public interface MyInterface<T> {
T server(T t);
}
//接口实现方式一:class确定泛型
class MyImpl1 implements MyInterface<String>
{

@Override
public String server(String s) {
System.out.println(s);
return s;
}
}
//接口实现方式二:class不确定泛型
class MyImpl2<T> implements MyInterface<T>{

@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
class test3{
public static void main(String[] args) {
MyImpl1 myImpl1=new MyImpl1();
myImpl1.server("hello");
MyImpl2<Integer> myImpl2a=new MyImpl2<>();
myImpl2a.server(100);
MyImpl2<String> myImpl2b=new MyImpl2<>();
myImpl2b.server("world");
}
}

out:
hello
100
world

1.3 泛型方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class GenernicMod {
public <T> T show(T t){
System.out.println("泛型方法:"+t);
return t;
}
}
class test4{
public static void main(String[] args) {
GenernicMod genernicMod=new GenernicMod();
genernicMod.show("hello");
genernicMod.show(123);
}
}

out:
泛型方法:hello
泛型方法:123

1.4 泛型集合

泛型集合:参数化类型、类型安全的集合,强制集合元素的类型必须一致。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.ArrayList;
import java.util.Iterator;

public class demo {
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("xxx");
arrayList.add("yyy");
Iterator<String> iterator=arrayList.iterator();
while (iterator.hasNext())
{
String string=iterator.next();
System.out.println(string);
}
}
}

2.Collection体系集合

集合和数组的区别:

(1).数组长度固定,集合长度不固定

(2).数组可以存储基本类型和引用类型,集合只能存储引用类型。

1

  • Collection 接口存储一组不唯一,无序的对象

  • List 接口存储一组不唯一,有序的对象。

  • Set 接口存储一组唯一,无序的对象

  • Map 接口存储一组键值对象,提供key到value的映射

    Collection的使用:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    import java.util.*;
    public class Example {
    public static void main(String[] args) {
    Collection collection = new ArrayList();
    //1.添加元素
    collection.add("a");
    collection.add("b");
    collection.add("c");
    System.out.println(collection);
    //*2.删除元素
    // collection.remove("a");//一次remove操作只删除一个元素,即使Collection中有相同元素
    // System.out.println(collection);
    //*3.1使用增强for遍历
    // for (Object object:collection) {
    // System.out.println(object);
    // }
    //*3.2使用迭代器进行遍历
    //hasNext();判断有没有下一个元素
    //next();获取下一个元素
    //remove();删除当前元素
    Iterator it= collection.iterator();
    while(it.hasNext())
    {
    String s=(String)it.next();
    System.out.println(s);
    // it.remove();//删除当前元素
    }//使用迭代器遍历时禁止使用Collection的其他的一些方法如remove()来改变集合的元素,可以使用迭代器的方法(it.remove())
    // System.out.println(collection);
    //*4.判断元素是否存在
    System.out.println(collection.contains("a"));
    }
    }

2.1 List子接口

List:有序、有下标、元素可以重复

2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.util.*;

public class List_test {
public static void main(String[] args) {
List list=new ArrayList();
//1.添加元素
list.add("a");
list.add("b");
list.add(0,"c");
System.out.println(list);
//2.删除元素
// list.remove("c");//按元素删除
list.remove(0);//按下标删除
System.out.println(list);
//3.遍历
//3.1使用for
System.out.println("3.1使用for");
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
//3.2使用增强for
System.out.println("3.2使用增强for");
for (Object object:list){
System.out.println(object);
}
//3.3使用迭代器
System.out.println("3.3使用迭代器");
Iterator iterator=list.iterator();
while(iterator.hasNext())
{
System.out.println(iterator.next());
}
//3.4使用列表迭代器,ListIterator可以向前或向后遍历,可以添加、删除、修改元素
System.out.println("3.4使用列表迭代器向后遍历");
ListIterator lit=list.listIterator();
while(lit.hasNext())
{
System.out.println(lit.next());
}
System.out.println("3.4使用列表迭代器向前遍历");
while(lit.hasPrevious())
{
System.out.println(lit.previous());
}
//4.获取元素的索引位置
System.out.println(list.indexOf("b"));
}
}

ArrayList存储结构:数组,查找速度快,增删速度慢,运行效率快,线程不安全

Vector存储结构:数组,查找速度快,增删速度慢,运行效率慢,线程安全

LinkedList存储结构:双向链表,增删速度快,查询速度慢

2.2 set子接口

2.2.1 Set

Set:无序、无下标、元素不可重复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import java.util.*;
public class demo {
public static void main(String[] args) {
Set <String> set=new HashSet<>();
set.add("a");
set.add("b");
set.add("c");
set.add("a");
System.out.println(set.size());
System.out.println(set.toString());
}
}

out:
3
[a, b, c]
2.2.2 HashSet

HashSet存储结构:哈希表(数组+链表+红黑树)

存储过程:

(1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。

(2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import java.util.*;
public class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
class demo {
public static void main(String[] args) {
HashSet <Person> set=new HashSet<>();
Person person1=new Person("wang",23);
Person person2=new Person("xu",22);
set.add(person1);
set.add(person2);
set.add(new Person("xu",22));
System.out.println(set.size());
System.out.println(set.toString());
}
}

out:
3
[Person@41629346, Person@4eec7777, Person@3b07d329]

问题:相同name,age的对象于集合中重复添加

解决方法:重写hashcode、equals方法

注:hashcode、equals方法定义了hashset的重复依据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import java.util.*;
public class Person{
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}

public int getAge() {
return age;
}
//重写hashCode和equals方法
public int hashCode(){
int n1=this.name.hashCode();
int n2=this.age;
return n1+n2;
}
public boolean equals(Object obj){
if(this==obj)
return true;
if(obj==null)
return false;
if (obj instanceof Person)
{
Person p=(Person) obj;
if (this.name.equals(p.getName())&&this.age==p.getAge())
return true;
}
return false;
}
}
class demo {
public static void main(String[] args) {
HashSet <Person> set=new HashSet<>();
Person person1=new Person("wang",23);
Person person2=new Person("xu",22);
set.add(person1);
set.add(person2);
set.add(new Person("xu",22));
System.out.println(set.size());
System.out.println(set.toString());
}
}

out:
2
[Person@f13, Person@37921a]
2.2.3 TreeSet

TreeSet:

  • 基于排序顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素

TreeSet存储结构:红黑树

TreeSet的使用一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.util.*;
public class Person implements Comparable<Person>{//TreeSet的元素类型必须实现Comparable接口
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}

public int getAge() {
return age;
}

public int compareTo(Person o) {//重写Comparable接口的compareTo方法,compareTo方法返回值为0认为是重复元素
int n1=this.name.compareTo(o.getName());
int n2=this.age-o.getAge();
return n1==0?n2:n1;
}
public String toString()
{
String str=this.getName()+":"+this.getAge();
return str;
}
}
class demo {
public static void main(String[] args) {
TreeSet <Person> persons=new TreeSet<>();
Person person1=new Person("wang",23);
Person person2=new Person("xu",22);
Person person3=new Person("xu",24);
persons.add(person1);
persons.add(person2);
persons.add(person3);
persons.add(new Person("xu",22));
System.out.println(persons.size());
System.out.println(persons.toString());
}
}

out:
3
[wang:23, xu:22, xu:24]

TreeSet的使用二:Comparator实现比较器,无需实现Comparable接口

1
2
3
4
5
6
7
8
TreeSet <Person> persons=new TreeSet<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1=o1.getName().compareTo(o2.getName());
int n2=o1.getAge()-o2.getAge();
return n1==0?n2:n1;
}
});

利用TreeSet实现字符串排序:先按长度排,长度相同比大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public static void main(String[] args) {
TreeSet<String> treeSet=new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int n1=o1.length()-o2.length();
int n2=o1.compareTo(o2);
return n1==0?n2:n1;
}
});
treeSet.add("peng");
treeSet.add("xu");
treeSet.add("wang");
treeSet.add("an");
System.out.println(treeSet.toString());
}

3.Map集合体系

3

Map:存储一对数据(Key-Value),无序、无下标、键不可重复、值可重复

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import java.util.*;

public class demo2 {
public static void main(String[] args) {
Map<String, String> map=new HashMap<>();
//1.添加元素
map.put("a","1");
map.put("b","2");
map.put("c","3");
map.put("d","4");
System.out.println(map.toString());
//2.删除元素
map.remove("b");
System.out.println(map.toString());
//3.1 使用keySet()遍历
System.out.println("使用keySet()遍历");
// Set<String> keys=map.keySet();
for (String key:map.keySet()){
System.out.println(key+":"+map.get(key));
}
//3.2 使用entrySet()遍历(效率高于keySet())
System.out.println("使用entrySet()遍历");
// Set<Map.Entry<String,String> > entrySet=map.entrySet();
for (Map.Entry<String,String> entry:map.entrySet()){
System.out.println(entry.getKey()+":"+entry.getValue());
}
//4.判断是否包含
System.out.println(map.containsKey("a"));
System.out.println(map.containsValue("1"));
}
}

HashMap的存储结构:哈希表(数组+链表+红黑树)

注:HashMap使用key的hashcode和equals作为重复的依据

TreeMap:实现了SortedMap接口,可以对key自动排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.util.*;
public class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}

public int getAge() {
return age;
}
public String toString()
{
String str=this.getName()+":"+this.getAge();
return str;
}
}
class demo {
public static void main(String[] args) {
TreeMap <Person,String> persons=new TreeMap<>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int n1=o1.getName().compareTo(o2.getName());
int n2=o1.getAge()-o2.getAge();
return n1==0?n2:n1;
}
});
Person person1=new Person("wang",23);
Person person2=new Person("xu",22);
Person person3=new Person("xu",24);
persons.put(person1,"a");
persons.put(person2,"b");
persons.put(person3,"c");
persons.put(new Person("xu",22),"d");
System.out.println(persons.size());
System.out.println(persons.toString());

}
}

4.Collections工具类

Collections工具类:集合工具类,定义了除存取以外的集合常用方法。

4