2021/09/01 Java 集合框架学习1
集合框架的学习,其实就是c++的容器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7mXESiUs-1630551095601)(C:\Users\Administrator\Desktop\新建文件夹\1.png)]
Collection
是所有集合类的父类,他的方法大家都是通用的,比如 size/contains/isEmpty/add
等等
public class Application {
public static void main(String[] args) {
Collection c = new ArrayList();
c.add(new Student("xiaoming",12));
c.add(new Student("xiaohong",18));
Iterator it=c.iterator();
while (it.hasNext()) {
Student x=(Student)it.next(); //注意,此处必须有这句话,否则remove执行不成功
it.remove();
}
System.out.println(c.size());
}
}
class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
List()
有序、有下标、元素可以重复
//常用的List方法
public class Application {
public static void main(String[] args) {
List list=new ArrayList();
list.add(new Character('a'));
list.add(new Character('b'));
list.add(0,3);
System.out.println(list.indexOf('b')); //输出是2
boolean b=list.contains(3); //b=true
for (int i = 0; i <list.size(); i++) {
System.out.println(list.get(i)); //List可以通过get(下标)来访问list中的元素
}
for (Object o : list) {
System.out.println(o);
}
}
}
ArrayList()
以数组方式存储的,迭代器除了有Iterator
还有 ListIterator
- ArrayList底层实现,刚创建的时候数组容量为0,add一个元素之后,数组容量扩容为10,满10之后会扩容1.5倍
vector
- vector存储结构也是数组,但是他是线程安全的
- vector的遍历是Enumeration
LinkedList【重点】
- 存储结构:双向链表
- 源码分析:底层就是C++的Node类
//重写类的equals方法,从而可以使用list.remove(对象)来删除元素,因为list.remove底层是通过equals来判断的
public class Application {
public static void main(String[] args) {
LinkedList list = new LinkedList();
Student s1 = new Student("张三",18);
Student s2 = new Student("李四", 19);
Student s3 = new Student("王五",20);
list.add(s1);
list.add(s2);
list.add(s3);
list.remove(new Student("张三", 18)); //在Student的equals方法没有重写之前是不行的
System.out.println(list.toString());
}
}
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override //此处重写了toString方法
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override //此处重写了equals方法
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Student)) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
}
ArrayList和LinkedList的区别
- ArrayList需要开辟连续空间,查询快,增删慢
- LinkedList不需要开辟连续空间,增删快,查询慢
泛型
- 泛型T必须是引用类型
泛型接口
//实现泛型接口的两种方法:1.在实现类的之后直接指定类型 2.直接写成泛型类
public class Application {
public static void main(String[] args) {
//方法一:
GnericImpl imp=new GnericImpl();
System.out.println(imp.print(2));
//方法二:
GenericImpl1<Integer> imp1 = new GenericImpl1<Integer>();
System.out.println(imp1.print(2));
}
}
interface Gneric<T>{
T print(T t);
}
//方法一:直接在实现的时候指定类型
class GnericImpl implements Gneric<Integer> {
@Override
public Integer print(Integer integer) {
return integer;
}
}
//方法二:直接将实现类也变成泛型类
class GenericImpl1<T> implements Gneric<T> {
@Override
public T print(T t) {
return t;
}
}
泛型方法
就是在普通方法前面加上 <T>
//普通方法
public void function(int a){
sout(a);
}
//泛型方法
public <T> void function(T t){
sout(t);
}
//泛型方法2
public <T> T function(T t){
sout(t);
}
泛型方法的好处
- 提高代码的重用性
- 提高代码安全性,防止类型转换出现异常
泛型在集合中的使用
- 避免在集合中放入不一样的类型,从而导致遍历的时候需要类型转换
- 就和STL语法一样的
Set集合
-
存储结构:哈希表(数组+链表)、红黑树
-
Set和LIst都是接口,所以在new的时候需要指明是HashSet还是TreeSet
-
Set就是元素不能重复的Collection
HashSet
- HashSet存储过程
- 根据hashCode来计算存储位置,如果hashCode的值不同,则直接存储。否则进行第二步
- 根据equals方法,对比两个对象,如果为true则不存储,如果为false,形成链表,接在下方
TreeSet
-
存储结构:红黑树
-
存储的时候需要实现接口comparable,因为红黑树需要排序【或者实现comparator接口,就不用实现Comparable接口了】
public class MyTreeSet {
public static void main(String[] args) {
TreeSet<Person> tree = new TreeSet<>();
Person p1 = new Person("zhangsan", 18);
Person p2 = new Person("lisi", 20);
Person p3 = new Person("wangmazi", 50);
tree.add(p1);
tree.add(p2);
tree.add(p3);
System.out.println(tree.toString()); //必须实现Comparable接口才能打印,因为treeset底层是红黑树
//实现,需要排序
}
}
//此类必须继承comparable接口
class Person implements Comparable<Person>{ //注意:此接口是泛型的,必须指定类型
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person o) {
int x = this.name.compareTo(o.name);
int y=this.age-o.age;
return x==0?x:y;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
Comparator接口实现
//重写Comparator接口TreeSet根据字符串长度排序
public class MyTreeSet {
public static void main(String[] args) {
TreeSet<Person> tree = new TreeSet<>(new Comparator<Person>() { //匿名内部类的方式实现Comparator接口
@Override
public int compare(Person o1, Person o2) {
int m=o1.getName().length()-o2.getName().length();
int n=o1.getAge()-o2.getAge();
return m==0?n:m;
}
});
Person p1 = new Person("zhangsan", 18);
Person p2 = new Person("lisi", 20);
Person p3 = new Person("wangzi", 50);
tree.add(p1);
tree.add(p2);
tree.add(p3);
System.out.println(tree.toString());
}
}
class Person {
private String name;
private int age;
public Person(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 "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
MAP
HashMap
- 存储结构是哈希表(数组+链表)
- 遍历的方式需要用到
keySet()
- 插入的方式是
put()
public class MyTreeSet {
public static void main(String[] args) {
HashMap<Person, String> map = new HashMap<>();
Person p1 = new Person("zhangsan",18);
Person p2 = new Person("lisi",20);
Person p3 = new Person("wangmaz",88);
map.put(p1, "BeiJing"); //注意map的插入方式和其他的不太一样
map.put(p2, "ShangHai");
map.put(p3, "HangZhou");
for (Person a:map.keySet()) { //map的遍历方式1:使用keySet()方法
System.out.println(a.toString()+" "+map.get(a));
}
System.out.println("------------");
for (Map.Entry<Person,String> entry:map.entrySet()) { //Map的遍历方式2:使用entrySet()方法
System.out.println(entry.getKey()+" "+entry.getValue());
}
}
}
class Person {
private String name;
private int age;
public Person(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 "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
TreeMap
- 存储结构是红黑树
- 对比TreeSet()
Collections
集合工具类,就和Arrays类【都是对数组的基本操作】一样的,主要有以下方法:
- 对集合内元素进行翻转,Collections.reverse()
- 随机重置集合类元素的顺序,Collections.shuffle()
- 对集合中的元素进行排序Collections.sort()
还有bineryserch()/cop()等对集合的基本操作方法