java 集合

1 set 接口

set接口表示一个唯一的,无序的容器(和添加顺序无关)

1.1 set接口提供的方法

package set;

import java.util.HashSet;
import java.util.Set;

public class Test01 {
    public static void main(String[] args) {
        /**
         * 增:add/addAll
         * 删:clear/remove/removeAll/retainAll
         * 改:
         * 查:contains/containsAll
         * 遍历:iterator
         * 其他:size/isEmpty
         */
        Set<Integer> set = new HashSet<Integer>();
        // [1]添加
        // 无序
        set.add(10);
        set.add(3);
        set.add(20);
        set.add(0);
        System.out.println(set);
        // 【2】删除
        //set.remove(10);
        //set.clear();
        //System.out.println(set);
        
        // 【3】查看是否包含
        System.out.println(set.contains(0));
        
        // 【4】其他
        System.out.println(set.isEmpty());
        System.out.println(set.size());
        
    }
}
[0, 3, 20, 10]
true
false
4

1.2 Set接口的遍历

package set;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class Test02 {
    public static void main(String[] args) {
        Set<String> set = new HashSet<String>();
        set.add("banana");
        set.add("apple");
        set.add("coco");
        //快速遍历
        for (String item : set) {
            System.out.println(item);
        }
        //迭代器
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String item =  it.next();
            System.out.println(it);
        }
    }
}
banana
apple
coco
banana
apple
coco

set接口常见的实现类有HashSet     LinkedHashSet      TreeSet

1.3 HashSet 是set接口的实现类,底层数据结构是哈希表  线程是不安全的

1.4 添加自定义对象

根据哈希表工作原理,请存储一个自定义对象到HashSet

 

package cn.sxt03.hashset;

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

    //
    

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((id == null) ? 0 : id.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (id == null) {
            if (other.id != null)
                return false;
        } else if (!id.equals(other.id))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

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

}

【1】如果HashSet中存储元素时元素一定要实现hashCode方法和equals方法。

[2] 优点:添加、删除、查询效率高;缺点:无序

 

1.5 LinkedHashSet

 

LinkedHashSetSet接口的实现底层数据结构哈希表+链表

 

哈希表用于散列元素;链表用于维持添加顺序。

 

 如果要添加自定义对象元素,也需要重写hashCodeequals方法。

 

 

1.6 TreeSet

TreeSet Set接口的实现类,底层数据结构是二叉树。

TreeSet 存储的数据按照一定的规则存储。存储规则让数据表现自然序。

  

添加一个新元素t存储的步骤

[1] 如果集合无元素,t直接加入;如果集合有元素,t和根节点比较;

[2] 如果t小于根节点;把t放到根节点的左子树上;重复1-3步骤

[3] t大于根节点;把t放到根节点的右子树上;重复1-3步骤

 

输出时按照一定的规则:子树->节点->右子树

 

根据TreeSet工作原理,向TreeSet添加自定义元素

TreeSet中添加元素时,一定要提供比较策略否则会出现ClassCastException

 

比较策略分两种:内部比较器外部比较器

1.6 内部比较器

一个自定义对象实现Comparable实现compareTo方法通过指定具体的比较策略此时称为内部比较器

 

package set;

public class Student implements Comparable<Student> {
    private String id;
    private String name;
    private int age;

    public Student() {
        super();
    }

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

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
        
    public int getAge() {
        return age;
    }

    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
    }
    
    @Override
   public int compareTo(Student o) {
        /*if (this.getAge()<o.getAge()) {
            
            return -1 ;
        }else if (this.getAge()==o.getAge()) {
            return 0;
        }else {
            if (this.getAge()>o.getAge()) {
                return 1;
            }*/
        return this.getAge()-o.getAge();
 }
}

package set;

import java.util.TreeSet;

public class Test03 {
    public static void main(String[] args) {
        TreeSet<Student> set = new TreeSet<Student>();
        Student s1=new Student("001", "dagou", 20);
        Student s2=new Student("002", "2dagou", 21);
        Student s3=new Student("003", "3dagou", 22);
        
        set.add(s2);
        set.add(s3);
        set.add(s1);
        System.out.println(set);
    }
}
[Student [id=001, name=dagou, age=20], Student [id=002, name=2dagou, age=21], Student [id=003, name=3dagou, age=22]]

比较策略几种情况

[1]比较策略一般当前对象写在前面,比较对象也在后面,比较结果默认升序

return  this.getAge() - o.getAge() ;

如果想要降序,改变两个比较对象的位置即可。

 

[2] 多种比较因素

 

@Override
    public int compareTo(Student o) {
        /*if(this.getAge()<o.getAge()) {
            return -1;
        }else if(this.getAge() == o.getAge()) {
            return 0;
        }else {
            return 1;
        }*/
        
        // return  this.getAge() - o.getAge() ;
        
        if(this.getAge()<o.getAge()) {
            return -1;
        }else if(this.getAge() == o.getAge()) {
            return this.getName().compareTo(o.getName());
        }else {
            return 1;
        }
    }

 

1.6 外部比较

实际开发过程不知道添加元素的源代码无权修改别人的代码此时可以使用外部比较器。

 

Comparator 位于java.util中,定义了compare(o1,o2) 用于提供外部比较策略。

TreeSet接受一个指定比较策略的构造方法,这些比较策略的实现类必须实现Comparator

接口

 

需求:按照字符串的长度比较

 

package set;

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

public class Test04 {
    public static void main(String[] args) {
        
        LenComparator lenComparator = new LenComparator();
        TreeSet<String> set2 = new TreeSet<String>(lenComparator);
        
        set2.add("banana");
        set2.add("coco");
        set2.add("apple");
        
        set2.add("apple");
        System.out.println(set2);
        
    }
}

class LenComparator implements Comparator<String>{

    @Override
    public int compare(String o1, String o2) {
        return o1.length() - o2.length();
    }    
}
[coco, apple, banana]

1.7Map接口

Map接口称为键值对集合或者映射集合其中的元素(entry)键值对(key-value)的形式存在

Map 容器接口中提供了增、删、改、查的方式对集合进行操作。

Map接口中都是通过key来操作键值对,一般key是已知。通过key获取value

 

1.8 map常用方法

 

package set;

/**
 * 增:put/putAll
 * 删:clear/remove
 * 改:put
 * 查:get/containsKey/containsValue
 * 其他:isEmpty/size
 */
import java.util.HashMap;
import java.util.Map;

public class Test05 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        
        // 【1】put
        map.put("A", "apple");
        map.put("B", "banana");
        map.put("C", "coco");
        System.out.println(map);
        
        // 【2】删除
        //map.clear();
        //map.remove("A");
        //System.out.println(map);
        
        // 【3】修改
        map.put("A", "apple X");
        System.out.println(map);
        // 【4】查看
        System.out.println(map.get("A"));
        System.out.println(map.containsKey("C"));
        System.out.println(map);
    }
}
{A=apple, B=banana, C=coco}
{A=apple X, B=banana, C=coco}
apple X
true
{A=apple X, B=banana, C=coco}

 

1.8 map接口的遍历

 

通过keySet() 返回mapset集合

 

package set;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class Test06 {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("B", "apple");
        map.put("A", "banana");
        map.put("C", "coco");
        // map无序
        // 可以根据key的自然顺序 让map有序  => 一般用string作为key
        System.out.println(map);
        
        // 遍历
        Set<String> keys = map.keySet();
        for (String key : keys) {
            System.out.println(map.get(key));
        }
        Iterator<String> it = keys.iterator();
        while (it.hasNext()) {
            String key = it.next();
            System.out.println(map.get(key));
        }
    }
}
{A=banana, B=apple, C=coco}
banana
apple
coco
banana
apple
coco

 

map中以键值对作为元素,键值对map中称为entryentrySet返回键值对的set集合。

 

public static void main(String[] args) {

        Map<String, String> map = new HashMap<String,String>();
        
        map.put("B", "banana");
        map.put("A", "apple");
        map.put("C", "coco");
        // map无序
        // 可以根据key的自然顺序 让map有序  => 一般用string作为key
        System.out.println(map);
        
        // entrySet
        Set<Entry<String, String>> entrySet = map.entrySet();
        for (Entry<String, String> entry : entrySet) {
            System.out.println(entry.getKey()+"=>"+entry.getValue());
        }
        
        Iterator<Entry<String, String>> it2 = entrySet.iterator();
        while(it2.hasNext()) {
            Entry<String, String> entry = it2.next();
            System.out.println(entry.getKey()+"=>"+entry.getValue());
        }
    }

 

Map接口的实现类HashMapLinkedHashMapTreeMap

 

1.10 HashMap

 

HashMap Map的实现类,keyHashSet存储。

 

 

public static void main(String[] args) {
        
        /*
        HashMap<String, Object> map = new HashMap<String,Object>();
        
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("alex");
        list1.add("alice");
        list1.add("allen");
        map.put("A", list1);
        
        
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("ben");
        list2.add("bill");
        map.put("B", list2);
        
        System.out.println(map);
        */
        
        
        HashMap<Student, Object> map = new HashMap<Student,Object>();
        
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("alex");
        list1.add("alice");
        list1.add("allen");
        Student s1 = new Student("001", "大狗", 20);
        map.put(s1, list1);
        
        
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("ben");
        list2.add("bill");
        Student s2 = new Student("001", "大狗", 20);
        // 修改
        map.put(s2, list2);
        System.out.println(map);
        
    }

[1] HashMap中存储元素时,key一定要实现hashCodeequals

[2] 一般建议使用String作为Map接口key

1.11 LinkedHashMap

LinkedHashMapMap接口的实现类,keyLinkedHashSet存储。

哈希表散列key,链表维持key的添加顺序。

 

public static void main(String[] args) {
        
        
        /*LinkedHashMap<String, Object> map = new LinkedHashMap<String,Object>();
        
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("ben");
        list2.add("bill");
        map.put("B", list2);
        
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("alex");
        list1.add("alice");
        list1.add("allen");
        map.put("A", list1);
        
        System.out.println(map);*/
        
        
        
        HashMap<Student, Object> map = new HashMap<Student,Object>();
        
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("alex");
        list1.add("alice");
        list1.add("allen");
        Student s1 = new Student("001", "大狗", 20);
        map.put(s1, list1);
        
        
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("ben");
        list2.add("bill");
        Student s2 = new Student("001", "大狗", 20);
        // 修改
        map.put(s2, list2);
        System.out.println(map);
        
    }

 

1.12 TreeMap

TreeMapMap的实现类,keyTreeSet存储。

 

public static void main(String[] args) {
        
        
        /*TreeMap<String, Object> map = new TreeMap<String,Object>(new Comparator<String>() {

            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        });
        
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("ben");
        list2.add("bill");
        map.put("Aa", list2);
        
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("alex");
        list1.add("alice");
        list1.add("allen");
        map.put("B", list1);
        
        System.out.println(map);*/
        
        
        
        TreeMap<Student, Object> map = new TreeMap<Student,Object>(new Comparator<Student>() {

            @Override
            public int compare(Student o1, Student o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        
        ArrayList<String> list1 = new ArrayList<String>();
        list1.add("alex");
        list1.add("alice");
        list1.add("allen");
        Student s1 = new Student("001", "大狗", 20);
        map.put(s1, list1);
        
        
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("ben");
        list2.add("bill");
        Student s2 = new Student("001", "2狗", 20);
        // 修改
        map.put(s2, list2);
        System.out.println(map);
        
    }

 

posted @ 2019-05-05 22:50  斗罗大陆  阅读(254)  评论(0编辑  收藏  举报