集合简介:
1. 定义: 可以同时存储不同类型的数据
他的存储空间会随着数据的增大而增大
2. 缺点: 只能存储引用数据类型
3. 优点: 更加合理的利用空间, 封装了更多的方法, 用起来更加方便
4. 分类: 集合分为: Collection(接口):
List 接口: ArrayList 类, LinkedList 类, Vector 类
Set 接口: HashSet 类, TreeSet 类
Map 接口:
HashMap 类
TreeMap 类
(相比较数组的概念: 数组: 可以存储不同类型的数据 可以存储简单数据类型和引用数据类型 缺点: 创建的数组长度是一个定值, 只能存储固定长度的数据)
5. 详细方法和注意项:
Collection 是一个接口, 所以无法实例化,
即 Collection 只能类似于 Collection collection = new ArrayList(); 创建对象
1)List: 存储是有序的 (即存储的顺序, 不是排序), 存储的元素可以重复
ArrayList: 底层结构是数组, 线程是不安全的, 添加删除慢 (因为是数组的结构), 查找快
LinkedList: 底层结构是链表, 线程是不安全的, 添加删除快 (因为是链表的结构), 查找慢
Vector: 底层结构是数组, 线程是安全的, 添加删除慢, 查找快,(同 ArrayList)
Collection 的方法:
- // 方法
- Collection collection=new ArrayList();
- collection.add("java2");
- collection.addAll();
- collection.remove();
- collection.removeAll();
- collection.clear();
- collection.size();
- System.out.println(collection.contains("java1"));// false
- System.out.println(collection.containsAll(collection1));// false
- System.out.println(collection.isEmpty());// false
- System.out.println(collection.equals(collection));// true
- Object[]arr=collection.toArray();// 集合变数组: 希望将集合的长度固定下来
- // 获取:
- // Iterator<E> iterator() // 获取集合中的对象 (迭代器)
- // int size() // 获取集合中对象的个数
- //hasNext() 判断当前位置是否有元素, 如果有返回 true 没有返回 false
- //next() 将当前位置的元素取出, 并且让指针指向下一个位置
- // 程序给每一个集合都准备了一个属于自己的迭代器对象, 我们获取对象的方法是调用集合的一个方法
- Iterator iterator=collection.iterator();
- while(iterator.hasNext()) {
- Object obj=iterator.next();
- System.out.println(obj+"iterator");
- }
- // 注意:
- //1. 再次遍历会报错因为指针在上次遍历时在最后位置, 如果需要重新遍历需要将指针移到最开始的位置, 所以需要重新获取迭代器的对象 Iterator iterator=collection.iterator();
- //2. 集合中可以存放不同类型的元素 collection.add(new Integer(22));
- // 容错处理: 当集合中存储了不同类型的元素, 需要进行容错处理
- Iterator iterator2=collection.iterator();
- while (iterator2.hasNext()) {
- Object object = iterator2.next();
- // System.out.println(object+"iterator");
- // 容错处理: 过滤掉 integer 类型的 22
- if(object instanceof String) {
- // 向下转型
- String string =(String)object;
- System.out.println(string+"S");
- }
- }
- // 获取当前元素个数
- System.out.println(collection.size());//4
- }
LinkedList 的特有方法
- // LindedList
- // 特有的方法:
- //
- // addFirst()// 始终在首位添加
- // addLast()// 始终在末尾添加
- //
- // getFirst()// 获取的对象不存在会发生异常
- // getLast()
- //
- // removeFirst()// 删除的对象不存在会发生异常
- // removeLast()
- //
- // 从 jdk1.6 开始出现以下方法
- // offerFirst()
- // offerLast()
- //
- // peekFirst()// 获取的对象不存在会返回 null
- // peekLast()
- //
- // pollFirst()// 删除的对象不存在会返回 null
- // pollLast()
2)Set: 没有顺序, 不可以重复
HashSet: 底层是哈希表, 线程是不安全的
TreeSet: 底层是树, 线程是不安全的
HashSet 重写 hashCode() 和 equals() 方法
* HashSet 实现元素不重复的过程:
* 使用的是元素内部的 HashCode() 和 equals(), 首先调用 HashCode() 方法比较两个对象的哈希值,
* 如果哈希值不相等, 认为是两个对象, 就不会再去调用 equals() 方法了, 如果相等再去调用 equals() 方法, 如果返回 true, 就认为是一个对象, 否则认为是两个对象
- HashSet set=new HashSet<>();
- // 在 String 内部重写了 Hashcode() 和 equals() 方法, 通过对这两个方法的调用, 实现了去重
- set.add("java1");//add 方法内部实现了去重, 默认调用了 String 里的 Hashcode() 和 equals() 方法实现的元素的去重
- set.add("java2");
- set.add("java3");
- set.add("java4");
- set.add("java4");
- System.out.println(set);// 重写了 toString
- HashSet set1=new HashSet<>();
- set1.add(new Person("bb1",11));
- set1.add(new Person("bb2",11));
- set1.add(new Person("bb3",11));
- set1.add(new Person("bb4",11));
- set1.add(new Person("bb4",11));
- set1.add(new Person("bb5",11));
- System.out.println(set1);
- class Person{
- String name;
- int age;
- public Person(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- @Override
- public String toString() {
- return "Person [name=" + name + ", age=" + age + "]";
- }
- @Override
- public int hashCode() {
- // TODO Auto-generated method stub
- return name.hashCode()+age*999;
- }
- @Override
- public boolean equals(Object obj) {
- if(!(obj instanceof Person)) {// 容错处理
- throw new RuntimeException();
- }
- Person person=(Person)obj;// 向下转型
- return age==person.age && name.equals(person.name);
- }
- }
- // 结果是
- [java4, java3, java2, java1]
- [Person [name=bb4, age=11], Person [name=bb3, age=11], Person [name=bb5, age=11], Person [name=bb2, age=11], Person [name=bb1, age=11]]
分析: 1.Set 本身有去重功能是因为 String 内部重写了 hashCode() 和 equals() 方法, 在 add 里实现了去重
而我们模仿这个功能, 自己重写 hashCode() 和 equals() 方法对 add(new Person("bb5",11)) 这种进行去重
2. 在打印 set 时, 内部重写了 toString() 与后来我们重写的 toString 无关, 后来重写的 toString 是为了打印后
面的带对象的添加.
TreeSet
1) Comparable 接口里的 compareTo 方法
- @Override
- @Override
- public int compareTo(Object o) {
- if(!(o instanceof P)) {
- throw new ClassCastException();
- }
- P p=(P)o;
- // 例如先比较年龄, 再比较姓名
- int num = age - p.age;
- return num==0?name.compareTo(p.name):num;
- }
- public class Test1 {
- public static void main(String[] args) {
- TreeSet set=new TreeSet<>();
- //TreeSet 在存储字符串的时候可以实现自动的排序去重
- // 原因: 作为元素的字符串实现了 Comparable 接口的 comparaTo(Object obj) 方法
- //compareTo() 实现的是排序和去重
- //add 方法内部调用了字符串的 CompareTo() 方法
- // 默认是字典排序升序排序
- set.add("java1");
- set.add("java2");
- set.add("java4");
- set.add("java4");
- set.add("java0");
- System.out.println(set);
- TreeSet set1=new TreeSet();
- set1.add(new P("bb1",11));
- set1.add(new P("bb2",12));
- set1.add(new P("bb3",13));
- set1.add(new P("bb4",14));
- set1.add(new P("bb4",14));
- set1.add(new P("bb5",11));
- System.out.println(set1);
- }
- }
- class P implements Comparable{// 实现 Comparable 接口
- String name;
- int age;
- public P(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- @Override
- public String toString() {
- return "P [name=" + name + ", age=" + age + "]";
- }
- @Override
- public int compareTo(Object o) {
- if(!(o instanceof P)) {
- throw new ClassCastException();
- }
- P p=(P)o;
- // 例如先比较年龄, 再比较姓名
- int num = age - p.age;
- return num==0?name.compareTo(p.name):num;
- }
- }
- // 结果是
- [java0, java1, java2, java4]
- [P [name=bb1, age=11], P [name=bb5, age=11], P [name=bb2, age=12], P [name=bb3, age=13], P [name=bb4, age=14]]
2) 实现了 Comparator 接口的类, 接口中有比较的方法叫 compare(Object obj1,Object obj2)
- ublic class Test3 {
- public static void main(String[] args) {
- // 2) 创建比较器对象
- CompareWitnLength compareWitnLength = new CompareWitnLength();
- // 3) 将比较器对象传给 TreeSet
- TreeSet set = new TreeSet(compareWitnLength);
- // 当默认排序和人工排序同时作用于一个类的时候, 人工排序优先级高于默认的
- set.add("java1");
- set.add("java2");
- set.add("java4");
- set.add("java4");
- set.add("java0");
- System.out.println(set);
- // 按照字符串的长短排序, 长度相同再按字典排序
- // 1. 单独创建比较器对象, 对应的类就是实现了 Comparator 接口的类, 接口中有比较的方法叫 compare(Object obj1,Object
- // obj2)
- // 2. 将比较器对象作用去 TreeSet,TreeSet 里面再添加元素的时候, 就会按照比较器规定的规则进行比较
- //
- ComWithAgeAndName comWithAgeAndName=new ComWithAgeAndName();
- TreeSet set1 = new TreeSet(comWithAgeAndName);
- set1.add(new Pp("bb1", 11));
- set1.add(new Pp("bb2", 12));
- set1.add(new Pp("bb3", 13));
- set1.add(new Pp("bb4", 14));
- set1.add(new Pp("bb4", 14));
- set1.add(new Pp("bb5", 11));
- System.out.println(set1);
- }
- }
- // 1). 创建字符串的比较器按照长短比较
- class CompareWitnLength implements Comparator {
- @Override
- public int compare(Object arg0, Object arg1) {
- if (!(arg0 instanceof String)) {
- throw new ClassCastException();
- }
- if (!(arg1 instanceof String)) {
- throw new ClassCastException();
- }
- String s1 = (String) arg0;
- String s2 = (String) arg1;
- int num = s1.length() - s2.length();
- return num;
- }
- }
- class Pp implements Comparable{
- String name;
- int age;
- public Pp(String name, int age) {
- super();
- this.name = name;
- this.age = age;
- }
- @Override
- public String toString() {
- return "P [name=" + name + ", age=" + age + "]";
- }
- @Override
- public int compareTo(Object o) {
- if(!(o instanceof P)) {
- throw new ClassCastException();
- }
- P p=(P)o;
- // 例如先比较年龄, 再比较姓名
- int num = age - p.age;
- return num==0?name.compareTo(p.name):num;
- }
- }
- class ComWithAgeAndName implements Comparator {
- @Override
- public int compare(Object o1, Object o2) {
- if (!(o1 instanceof Pp)) {
- throw new ClassCastException();
- }
- if (!(o2 instanceof Pp)) {
- throw new ClassCastException();
- }
- Pp p = (Pp) o1;
- Pp p1 = (Pp) o2;
- int num = p.age - p1.age;
- return num == 0 ? p.name.compareTo(p1.name) : num;
- // return 0;
- }
- }
来源: https://www.cnblogs.com/FORCASH/p/9029280.html