集合

几种重要的接口和类简介

1、List(有序、可重复
List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

   ArrayList和LinkedList

ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。LinkedList经常用在增删操作较多而查询操作很少的情况下,ArrayList则相反。

 

2、Set(无序、不能重复
Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。

(1)HashSet

     HashSet 是一个没有重复元素的集合。它是由HashMap实现的不保证元素的顺序(这里所说的没有顺序是指:元素插入的顺序与输出的顺序不一致),而且HashSet允许使用null 元素。HashSet是非同步的,如果多个线程同时访问一个哈希set,而其中至少一个线程修改了该set,那么它必须保持外部同步。 HashSet按Hash算法来存储集合的元素,因此具有很好的存取和查找性能。

HashSet的实现方式大致如下,通过一个HashMap存储元素,元素是存放在HashMap的Key中,而Value统一使用一个Object对象。

HashSet使用和理解中容易出现的误区:

a.HashSet中存放null值
  HashSet中是允许存入null值的,但是在HashSet中仅仅能够存入一个null值。

b.HashSet中存储元素的位置是固定的
  HashSet中存储的元素的是无序的,这个没什么好说的,但是由于HashSet底层是基于Hash算法实现的,使用了hashcode,所以HashSet中相应的元素的位置是固定的。

c.必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。

* HashSet如何去重
* 需要依赖hashCode ,equals
* 先判断hashCode值
* 不同:直接存入
* 相同:判断equals
* 相同:不存入
* 不同:直接存入
package 集合.set;

import java.util.Objects;

public class student {
    String name;
    int age;

    public student(String name, int age) {
        this.name = name;
        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 instanceof student)) return false;
        student student = (student) o;
        return Objects.equals(name, student.name) &&
                Objects.equals(age, student.age);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }


}
package 集合.set;

import java.util.HashSet;


/*
* * HashSet如何去重
 * 需要依赖hashCode ,equals
 * 先判断hashCode值
 *   不同:直接存入
 *   相同:判断equals
 *           相同:不存入
 *           不同:直接存入
*
* */
public class HashSetDemo {
    public static void main(String[] args) {
        HashSet<student> set = new HashSet<>();

        student p1 = new student("张三", 22);
        student p2 = new student("张三", 22);
        student p3 = new student("张1",33 );
        student p4 = new student("张3", 22);

        set.add(p1);
        set.add(p2);
        set.add(p3);
        set.add(p4);


        //使用set时 避免添加值 之后不要修改值 容易导致数据重复
        for (student f:set){
            System.out.println(f);
        }

    }
}


输出结果;

student{name='张三', age=22}
student{name='张3', age=22}
student{name='张1', age=33}

 

 

(2)TreeSet

     TreeSet是一个有序集合,其底层是基于TreeMap实现的,非线程安全。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序和定制排序,其中自然排序为默认的排序方式。当我们构造TreeSet时,若使用不带参数的构造函数,则TreeSet的使用自然比较器;若用户需要使用自定义的比较器,则需要使用带比较器的参数。

注意:TreeSet集合不是通过hashcode和equals函数来比较元素的.它是通过compare或者comparaeTo函数来判断元素是否相等.compare函数通过判断两个对象的id,相同的id判断为重复元素,不会被加入到集合中。

package 集合.set;
/*
* 1.自然排序:默认实现compareable接口
*
* String 自己已经实现了接口; Comparable<String>  所有要自动排序
 * */

import java.util.TreeSet;
public class Treesetdemo1 {
    public static void main(String[] args) {
        TreeSet<String> set = new TreeSet<>();
        set.add("java");
        set.add("hello");
        set.add("php");
        set.add("linux");

        for (String str: set) {
            System.out.println(str);
        }
    }
}

输出结果;

hello
java
linux
php

  

package 集合.set;
/*
* 此接口强行对实现它的每个类的对象进行整体排序。
* 这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法。
*
*
* */
public  class Dog implements Comparable<Dog> {
    String name;
    int age;

    public Dog(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Dog [name=" + name + ", age=" + age + "]";
    }

    /**
     * 排序:
     *  1、主要条件: 需求给的条件 按照年龄
     *  如果主要条件相同还需要判断次要条件:
     *  2、次要条件:找一个可以区分的字段
     */
    @Override
    public int compareTo(Dog o) {
//        System.out.println(this +" ---- "+ o);
//        return this.age - o.age;
        int a = this.age - o.age; //设定顺序还是倒叙
        if(a == 0) {
            return this.name.compareTo(o.name);
        }
        return a;
    }
}


package 集合.set;
import java.util.TreeSet;


public class Treesetdemo2 {
    public static void main(String[] args) {
        TreeSet<Dog> set = new TreeSet<>();
        set.add(new Dog("小黑", 2));
        set.add(new Dog("小黑黑", 2));
        set.add(new Dog("小花", 1));
        set.add(new Dog("小灰", 3));
        set.add(new Dog("小黄", 0));

        for (Dog dog : set) {
            System.out.println(dog);
        }
    }
}
输出结果;

Dog [name=小黄, age=0]
Dog [name=小花, age=1]
Dog [name=小黑, age=2]
Dog [name=小黑黑, age=2]
Dog [name=小灰, age=3]

 

 

3、Map(键值对、键唯一、值不唯一
Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。

1.HashMap

      以哈希表数据结构实现,查找对象时通过哈希函数计算其位置,它是为快速查询而设计的,其内部定义了一个hash表数组(Entry[] table),元素会通过哈希转换函数将元素的哈希地址转换成数组中存放的索引,如果有冲突,则使用散列链表的形式将所有相同哈希地址的元素串起来,可能通过查看HashMap.Entry的源码它是一个单链表结构

 

 

是否有序

是否允许元素重复

Collection

 

 

List

Set

AbstractSet

 

HashSet

 

TreeSet

是(用二叉排序树)

Map

AbstractMap

使用key-value来映射和存储数据,key必须唯一,value可以重复

 

HashMap

 

TreeMap

是(用二叉排序树)

遍历

 在类集中提供了以下四种的常见输出方式:

1)Iterator:迭代输出,是使用最多的输出方式。

2)ListIterator:是Iterator的子接口,专门用于输出List中的内容。

3)foreach输出:JDK1.5之后提供的新功能,可以输出数组或集合。

4)for循环

代码示例如下:

 for的形式:for(int i=0;i<arr.size();i++){...}

 foreach的形式: for(int i:arr){...}

 iterator的形式:
Iterator it = arr.iterator();
while(it.hasNext()){ object o =it.next(); ...}

 

posted @ 2019-04-13 19:31  后天2333  阅读(101)  评论(0)    收藏  举报