集合和数组的区别

  1. 数组可以存任何数据类型,集合只能存引用数据类型
  2. 如果集合想存基本数据类型,泛型中要定义它们的包装类。
  3. 数组的长度不可变,集合的长度可变

集合的体系结构

java 单列集合和双列集合的使用场景 单列集合collection_java

 

 Collection集合

  1. 是单列集合的顶层接口
  2. 它提供更具体的子接口List和Set实现

Collection接口中提供的常用方法方法:

 

1  Collection<String> collection = new ArrayList<>();
2         collection.add("aaa");//向集合中添加元素
3         boolean b = collection.remove("aaa");//删除集合中的元素并返回布尔型结果true表示删除成功,false表示删除失败
4         int size = collection.size();//返回集合已存数据的个数
5         boolean b1 = collection.removeIf((String s) -> {
6            return s.length()==2;
7         });//根据条件删除元素
8         boolean result = collection.contains("aaa");//判断集合中是否有指定元素
9         collection.clear();//清除集合内所有元素

Iterator迭代器(集合特有)

  1. 单列集合可以直接使用迭代器
  2. 创建一个迭代器对象:Iterator<String> it = list.iterator();默认指向集合第一个索引
  3. boolean hasNext(); 判断集合索引处是否含有元素
  4. next(); 取出索引处元素,并将迭代器指向集合的索引位置向下推进一次
public static void main(String[] args) {
      ArrayList<String> list=new ArrayList<>();
      list.add("sss");
      list.add("sss");
      list.add("sss");
      list.add("sss");
      list.add("sss");
      list.add("sss");
      list.add("sss");
        Iterator<String> it = list.iterator();
        while (it.hasNext()){
            String s = it.next();
            System.out.println(s);


        }

增强for

  • 格式:for(Object o:集合或数组名){o就是从集合或数组中的每一个第三方中间变量,可对其进行操作但修改不会改变原集合或者数组}
  • 实现Iterable接口的类才可以使用迭代器和增强for(单列集合Collection实现了Iterable,双列集合Map没有实现)
  • 在迭代器中不能通过集合对象增删元素,不然会发生并发错误

下面先讲单列集合:

List(有序,有索引,可重复)

list集合的常用方法:

public static void main(String[] args) {
List<String> list=new ArrayList<>();//多态形式,只能有List中的方法
        list.add("aaa");//
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        list.add("aaa");
        list.add(3,"ooo");//在制定索引增加元素
        String s1 = list.get(0);//在制定索引获得制定索引元素
        String remove = list.remove(1);//删除指定索引元素
        String s3 = list.set(0, "nnn");//设置指定索引元素


    }

ArrayList(底层是数组查询快,增删慢)

 

1.Arraylist第的底层结构是数组,在ArrayList创建对象的时候,默认长度是0,也就是空集合,但是在add();方法执行后会把集合长度变为10,所以我们一般认为ArrayList集合的默认长度是10,当添加的元素的格式超过10的时候,会自动创建一个新的集合,长度为原来集合的1.5倍,然后把原来集合的所有数据全部赋值给新的集合。

2.size

size是集合创建时的底层变量,它的默认值是0,当每次使用add();方法向集合中添加元素的时候,size就会+1;指向下一个将要被添加元素的索引,所以size也可以理解为集合中当前拥有的元素个数。

LinkedList

1.LinkedList(底层结构是链表,查询慢,增删快)

public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.addFirst("aaa");//添加元素到头部
        list.add("sss");
        list.addLast("zzz");//添加元素到尾部
        list.removeFirst();//删除头部元素
        list.removeLast();//删除尾部元素
        list.getFirst();//获得头部元素
        list.getLast();//获得尾部元素


    }

 Set(不可重复)

Set集合的特点

  • 可以去除重复
  • 存取顺序不一致
  • 没有带索引的方法,所以不能用普通for遍历也不能通过索引来获取或者删除Set集合里面的元素

TreeSet集合的特点(底层是红黑树)

  • 不重复
  • 没有带索引的方法
  • 可以将元素按照规则进行排序

 TreeSet的自然排序(自定义对象要实现Comparable接口)

1 package com.heima.test;
 2 
 3 import java.util.TreeSet;
 4 
 5 public class TreeSetTest {
 6     public static void main(String[] args) {
 7         TreeSet<Student> treeSet=new TreeSet<>();
 8         Student student1=new Student("xiaoming",22);
 9         Student student2=new Student("wanggang",23);
10         Student student3=new Student("liuneng",25);
11         Student student4=new Student("zhanosi",21);
12         Student student5=new Student("zhulei",22);
13         treeSet.add(student1);
14         treeSet.add(student2);
15         treeSet.add(student3);
16         treeSet.add(student4);
17         treeSet.add(student5);
18         treeSet.add(student5);//重复添加测试
19         System.out.println(treeSet);
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30     }
31 }
package com.heima.test;

public class Student implements Comparable<Student> {//实现并重写comparato方法
    private String name;
    private int age;

    public Student() {
    }

    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 result = this.age - o.age;//首先按照年龄从小到大排序
        return result == 0 ? this.name.compareTo(o.name) : result;//在年龄相等的情况下按照姓名字母的字典比较方法排序

    }
}

 

 

TreeSet的Comparator比较器排序(使用TreeSet的带参构造)

代码如下:

package com.heima.test;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSetTest {
    public static void main(String[] args) {
        TreeSet<Student> treeSet=new TreeSet<>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                int result = o1.getAge() - o2.getAge();
                return result==0?o1.getName().compareTo(o2.getName()):result;//匿名内部类的方式重写
            }
        });
        Student student1=new Student("xiaoming",22);
        Student student2=new Student("wanggang",23);
        Student student3=new Student("liuneng",25);
        Student student4=new Student("zhanosi",21);
        Student student5=new Student("zhulei",22);
        treeSet.add(student1);
        treeSet.add(student2);
        treeSet.add(student3);
        treeSet.add(student4);
        treeSet.add(student5);
        treeSet.add(student5);//重复添加测试
        System.out.println(treeSet);










    }
}

 

两种比较方式的选择,在自然排序不满足需求时,可以选择比较排序

 

HashSet

  • 底层数据结构是哈希表
  • 不能保证存储和取出的顺序完全一致
  • 没有索引
  • 不重复

HashCode(哈希值):是JDK根据对象的地址或者属性值(要经过方法重写)算出来的int类型的整数

Object类中的public inthashcode();方法根据地址值计算出来哈希值,HashSet集合存储对象是根据哈希值和集合长度计算出来的值进行存储的。

 

 

存数据时要重写hashCode方法

代码如下:

package com.heima.test;

import java.util.Comparator;
import java.util.HashSet;
import java.util.TreeSet;

public class HashSetTest {
    public static void main(String[] args) {
        HashSet<Student> hashSet=new HashSet<>();
        Student student1=new Student("haha",23);
        Student student2=new Student("haha",24);
        Student student3=new Student("haha",25);
        Student student4=new Student("haha",26);
        Student student5=new Student("haha",23);//重复测试
        hashSet.add(student1);
        hashSet.add(student2);
        hashSet.add(student3);
        hashSet.add(student4);
        hashSet.add(student5);
        System.out.println(hashSet);









    }
}
package com.heima.test;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        if (age != student.age) return false;
        return name != null ? name.equals(student.name) : student.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;//重写HashCode方法
        result = 31 * result + age;
        return result;
    }
}

 

迎风少年