Collect集合

集合的概念:对象的容器,实现了对对象常用的操作,类似数组的功能。

集合与数组的区别:数组长度固定,集合长度不固定;数组可以存储基本类型与引用类型,集合只能存储引用类型,存储基本类型需要采用“装箱”操作。


collection体系集合:

ArrayList:数据结构实现,查询快,增删慢;JDK1.2版本,运行效率快,线程不安全。

Vector:数据结构实现,查询快,增删慢。JDK1.0版本,运行效率慢,线程安全。

LinkedList:链表实现,增删快,查询慢。


collection常用方法:

collection集合再添加对象时,添加的是对象的地址,因此,collection调用clear或者remove方法时,只是将对象从集合中移除出去,但是对象依旧存在。


collection的demo如下:

package CollectionDemo;

import Student.Student;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

public class CollectionDemoFunction {

    public static void listFunction1() {
        Collection collection = new ArrayList();
        collection.add("苹果0");
        collection.add("苹果1");
        collection.add("苹果2");
        collection.add("苹果3");

        System.out.println("元素个数" + collection.size());
        System.out.println(collection);

        System.out.println("~~~~~~增强for~~~~~~");
        for (Object o: collection) {
            System.out.println(o);
        }

        System.out.println("~~~~~~迭代器~~~~~~");
        Iterator iterator = collection.iterator();
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }

        System.out.println("元素个数" + collection.size());

        System.out.println("~~~~~~迭代器删除~~~~~~");
        Iterator iterator1 = collection.iterator();
        while(iterator1.hasNext()) {
            iterator1.next(); // 迭代器得先取出来,再删除
           // collection.remove("苹果0"); // 迭代器中不能中collection的方法
            iterator1.remove();
        }
        System.out.println("元素个数" + collection.size());
    }

    public static void listFunction2() {
        Collection collection = new ArrayList();
        Student s1 = new Student("张三1",16);
        Student s2 = new Student("张三2",17);
        Student s3 = new Student("张三3",18);
        Student s4 = new Student("张三4",19);

        collection.add(s1);
        collection.add(s2);
        collection.add(s3);
        collection.add(s4);

        System.out.println("元素个数:" + collection.size());
        System.out.println(collection.toString());

        collection.remove(s1);
        System.out.println("删除一个元素后的元素个数:" + collection.size());
        System.out.println(collection.toString());

        System.out.println("~~~~~~~~~~增强for~~~~~~~~~");
        for(Object o : collection) {
            Student s = (Student)o;
            System.out.println(s.toString());
        }

        System.out.println("~~~~~~~~~~迭代器~~~~~~~~~");
        Iterator iterator = collection.iterator();
        while(iterator.hasNext()) {  // 迭代器中不能使用clooection的删除方法,迭代器中的remove方法的前面要有next方法
            Student s = (Student)iterator.next();
            System.out.println(s.toString());
        }

        System.out.println("s2是否存在?" + collection.contains(s2));
    }
}

ArrayList是一个连续地址空间,它的demo如下:

package List;

import Student.Student;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;

public class ArrayListFunction {
    public static void ArrayListTest1() {
        ArrayList arrayList = new ArrayList();
        Student s1 = new Student("路的话0", 160);
        Student s2 = new Student("路的话1", 161);
        Student s3 = new Student("路的话2", 162);
        Student s4 = new Student("路的话3", 163);
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        arrayList.add(s4);

        System.out.println("元素个数:" + arrayList.size());
        System.out.println(arrayList.toString());

        arrayList.remove(new Student("路的话0", 160));

        System.out.println("元素个数:" + arrayList.size());
        System.out.println(arrayList.toString());

        System.out.println("~~~~~~~迭代器~~~~~~~~");
        Iterator iterator = arrayList.iterator();
        while(iterator.hasNext()) {
            Student s = (Student) iterator.next();
            System.out.println(s.toString());
        }

        System.out.println("~~~~~~~列表迭代器:顺序执行~~~~~~~~");
        ListIterator listIterator = arrayList.listIterator();
        while(listIterator.hasNext()) {
            Student s = (Student) listIterator.next();
            System.out.println(s.toString());
        }

        System.out.println("~~~~~~~列表迭代器:逆序执行~~~~~~~~");
        while(listIterator.hasPrevious()) {
            Student s = (Student) listIterator.previous();
            System.out.println(s.toString());
        }

        System.out.println("s2的位置:" + arrayList.indexOf(s2));
    }
}

Vector是线程安全的,它的添加,移除,判空操作和上面是一样的,但是他除了可以用for,iterator来遍历外,也可以用如下方式进行遍历:

public class VectorTest {
    public static void main(String[] args) {
        Vector t =new Vector();
        t.add("H");
        t.add("k");
        t.add("q");
        System.out.println("元素个数:" + t.size());
        System.out.println("元素:" + t.toString());

        // 遍历
        System.out.println("~~~~~~~~~~~~~~遍历~~~~~~~~~~~");
        Enumeration enumeration =  t.elements();
        while(enumeration.hasMoreElements()) {
            String s = (String)enumeration.nextElement();
            System.out.println(s);
        }
    }
}

linklist是一个双向链表,遍历时可以采用ListIterator进行从前往后,从后往前的遍历,demo如下:

    public static void main(String[] args) {
        LinkedList<Student> linkedList = new LinkedList<Student>();
        Student s1 = new Student("张三", 16);
        Student s2 = new Student("李四", 17);
        Student s3 = new Student("王五", 18);

        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);

        System.out.println("元素个数:" + linkedList.size());


        System.out.println("~~~~~~~~~~~for循环遍历:~~~~~~~~~~");
        for (int i = 0; i < linkedList.size(); i++) {
            Student s = (Student)linkedList.get(i);
            System.out.println("名字:"+ s.getName() + "; 年龄: "+ s.getAge());
        }

        System.out.println("~~~~~~~~~~~增强for循环遍历:~~~~~~~~~~");
        for (Object l: linkedList) {
            Student s = (Student)l;
            System.out.println(s.toString());
        }

        System.out.println("~~~~~~~~~~~迭代遍历:~~~~~~~~~~");
        Iterator iterator = linkedList.iterator();
        while(iterator.hasNext()) {
            Student s = (Student)iterator.next();
            System.out.println("名字:"+ s.getName() + "; 年龄: "+ s.getAge());
        }

        System.out.println("~~~~~~~~~~~list迭代遍历:~~~~~~~~~~");
        System.out.println("first-->last:");
        ListIterator listIterator = linkedList.listIterator();
        while(listIterator.hasNext()) {
            Student s = (Student)listIterator.next();
            System.out.println(s.toString());
        }

        System.out.println("last-->first:");
        while(listIterator.hasPrevious()) {
            Student s = (Student)listIterator.previous();
            System.out.println(s.toString());
        }

        System.out.println("是否包含张三?"+linkedList.contains(s1));

        System.out.println("是否为空?"+linkedList.isEmpty());

    }

泛型的本质:参数化类型,把类型作为参数传递,语法是<T...>,T称为类型占位符,表示一种引用类型。好处是:提高代码的重用性;防止装换异常,提高代码使用的安全性。有三种类型:

泛型类:

public class myGeneric<T> {
    T t;

    public void show(T t) {
        System.out.println(t);
    }

    public T getT() {
        return t;
    }
}

泛型接口:

public interface myInterface<T> {
    T server(T t);
}

泛型方法:

public class myMethod {
    public <T> T show(T t) {
        System.out.println("泛型方法的使用:" + t);
        return t;
    }
}

泛型集合:参数化类型,类型安全的集合,强制集合元素的类型必须一致。

    public static void main(String[] args) {
        LinkedList<Student> linkedList = new LinkedList<Student>();
        Student s1 = new Student("张三", 16);
        Student s2 = new Student("李四", 17);
        Student s3 = new Student("王五", 18);

        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);

        System.out.println("元素个数:" + linkedList.size());


        System.out.println("~~~~~~~~~~~for循环遍历:~~~~~~~~~~");
        for (int i = 0; i < linkedList.size(); i++) {
            Student s = (Student)linkedList.get(i);
            System.out.println("名字:"+ s.getName() + "; 年龄: "+ s.getAge());
        }

        System.out.println("~~~~~~~~~~~增强for循环遍历:~~~~~~~~~~");
        for (Object l: linkedList) {
            Student s = (Student)l;
            System.out.println(s.toString());
        }

        System.out.println("~~~~~~~~~~~迭代遍历:~~~~~~~~~~");
        Iterator iterator = linkedList.iterator();
        while(iterator.hasNext()) {
            Student s = (Student)iterator.next();
            System.out.println("名字:"+ s.getName() + "; 年龄: "+ s.getAge());
        }

        System.out.println("~~~~~~~~~~~list迭代遍历:~~~~~~~~~~");
        System.out.println("first-->last:");
        ListIterator<Student> listIterator = linkedList.listIterator();
        while(listIterator.hasNext()) {
            Student s = listIterator.next();
            System.out.println(s.toString());
        }

        System.out.println("last-->first:");
        while(listIterator.hasPrevious()) {
            Student s = listIterator.previous();
            System.out.println(s.toString());
        }

        System.out.println("是否包含张三?"+linkedList.contains(s1));

        System.out.println("是否为空?"+linkedList.isEmpty());

    }

特点:

编译时即可检查,而非运行时抛出异常。

访问时,不必类型转换(拆箱)。

不同泛型之间的引用不能相互赋值,泛型不存在多态。


HashSet的Demo如下,hashSet是中用到了hashcode,它是由数组+链表+红黑树组成,其中有用到一个数31,用到这个数的原因有两个:一是它数一个质数,能减少散列冲突;其次,31*i = (i<<5)-1,将乘法转为移位运算与减法,减少计算量。

    public static void hashSetDemo() {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("苹果");
        hashSet.add("栗子");
        hashSet.add("香蕉");
        hashSet.add("哈密瓜");

        System.out.println("元素个数:" + hashSet.size());
        System.out.println("元素:" + hashSet.toString());

        System.out.println("迭代:");
        Iterator<String> it = hashSet.iterator();
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }

TreeSet的结构是红黑树,认为是重复元素的依据是compareTo()方法,因此元素需要自己实现Comparable接口。我定义一个Person类,继承了Comparable接口,并实现compareTo()方法,然后在demoh中添加Person元素,如果不继承并实现这个方法,则无法添加成功:

package SetDemo;

import java.util.Objects;

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

    public Person() {
    }

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age && Objects.equals(name, person.name);
    }

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

    @Override
    public int compareTo(Person o) {
        int n = this.getName().compareTo(o.getName());
        int m = this.age - o.age;

        return n == 0 ? m : n;
    }
}

demo:

    public static void treeSetDemo1() {
        TreeSet<Person> treeSet = new TreeSet<>();
        Person p1 = new Person("张三", 10);
        Person p2 = new Person("张si", 9);
        Person p3 = new Person("张w", 12);
        Person p4 = new Person("张lui", 8);

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

        System.out.println("元素个数:" + treeSet.size());
        System.out.println("元素:" + treeSet.toString());

        Iterator<Person> iterator = treeSet.iterator();
        while(iterator.hasNext()) {
            Person p = iterator.next();
            System.out.println("人名:"+ p.getName() + "年龄:" + p.getAge());
        }
    }

当然,也可以不采用继承的方式,而是采用匿名内部类的方式实现:

    public static void treeSetDemo2() {
        TreeSet<Person> treeSet = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int n = o1.getAge() - o2.getAge();
                int m = o1.getName().compareTo(o2.getName());
                return n == 0 ? m : n;
            }
        });

        Person p1 = new Person("张sam", 10);
        Person p2 = new Person("张si", 9);
        Person p3 = new Person("张w", 12);
        Person p4 = new Person("张lui", 8);

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

        System.out.println("元素个数:" + treeSet.size());
        System.out.println("元素:" + treeSet.toString());

        Iterator<Person> iterator = treeSet.iterator();
        while(iterator.hasNext()) {
            Person p = iterator.next();
            System.out.println("人名:"+ p.getName() + "年龄:" + p.getAge());
        }
    }

Map的特点:存储键值对,键不能重复,值可以重复;无序。

map的简单demo:

        // 创建Map集合
        Map<String, String> map = new HashMap<String, String>();

        // 添加元素
        map.put("cn", "中国");
        map.put("uk", "英国");
        map.put("usa", "美国");
        map.put("cn", "zhongguo");

        System.out.println("元素个数:" + map.size());

        System.out.println("~~~~~~~~~~~~~增强for~~~~~~~~~~~~");
        for(String key : map.keySet()) {
            System.out.println(key + "-------------" + map.get(key));
        }

        System.out.println("~~~~~~~~~~~~entrySet~~~~~~~~~~~~");
        Set<Map.Entry<String, String>> entrySet =  map.entrySet();
        for (Map.Entry<String, String> entry : entrySet) {
            System.out.println(entry.getKey() +"------------"+  entry.getValue());
        }

        System.out.println(map.containsKey("cn"));
        System.out.println(map.containsValue("美国"));
    }

HashMap的存储结构是数组+链表+红黑树,通过判断key不可重复,重复的依据是hashcode与equals函数,其demo如下:

    public static void haspMapDemo2() {
        HashMap<Student, String> students = new HashMap<Student, String>();
        Student s1 = new Student("孙1",1);
        Student s2 = new Student("朱2",2);
        Student s3 = new Student("傻3",3);

        students.put(s1, "昆仑");
        students.put(s2, "蓬莱");
        students.put(s3, "泰山");
        students.put(new Student("傻3",3), "泰山");

        System.out.println("元素个数:" + students.size());
        System.out.println("元素:" + students.toString());

        System.out.println("~~~~~~~~~KeySet遍历~~~~~~~");
        Set<Student> s = students.keySet();
        for(Student student : s) {
            System.out.println(student + "----------" + students.get(student));
        }

        System.out.println("~~~~~~~~~entrySet遍历~~~~~~~");
        Set<Map.Entry<Student,String>> entrys = students.entrySet();
        for(Map.Entry<Student,String> entry : entrys) {
            System.out.println(entry.getKey() + "-----------------" + entry.getValue());
        }
    }

TreeMap的存储结构是红黑树,因此,也需要引用Comparable类,需要重写compareTo接口:

    public static void treeMapDemo1() {
        TreeMap<Student, String> treeMap = new TreeMap<Student, String>();
        Student s1 = new Student("孙1",1);
        Student s2 = new Student("朱2",2);
        Student s3 = new Student("傻3",3);

        treeMap.put(s1, "长沙");
        treeMap.put(s2, "墨西哥");
        treeMap.put(s3, "纽约");

        System.out.println("元素个数:" + treeMap.size());
        System.out.println("元素:" + treeMap);

        System.out.println("------KeySet---------");
        Set<Student> set = treeMap.keySet();
        for(Student s : set) {
            System.out.println(s + "-----" + treeMap.get(s));
        }

        System.out.println("------entrySet---------");
        Set<Map.Entry<Student,String>> entries = treeMap.entrySet();
        for (Map.Entry<Student,String> entry : entries) {
            System.out.println(entry.getKey() +"----------"+ entry.getValue());
        }
    }
Student类,这个类也是上面HashMap的demo中用到的类:
public class Student implements Comparable<Student>{
    private String name;
    private int stuNo;

    public Student() {
    }

    public Student(String name, int stuNo) {
        this.name = name;
        this.stuNo = stuNo;
    }

    public String getName() {
        return name;
    }

    public int getStuNo() {
        return stuNo;
    }

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

    public void setStuNo(int stuNo) {
        this.stuNo = stuNo;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", stuNo=" + stuNo +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (this instanceof Student) {
            Student s = (Student)o;
            if (this.name.equals(s.name) && this.stuNo == s.stuNo) {
                return true;
            }
        }
        return false;
    }

    @Override
    public int hashCode() {
        int n = this.name.hashCode();
        int m = this.stuNo + 31;

        return n == 0 ? m : n;
    }

    public int compareTo(Student o) {
        int n = this.getStuNo() - o.getStuNo();
        return n;
    }
}


collections工具类的使用:

    public static void CollectionsToolsDemo1() {
        List<Integer> list = new ArrayList<Integer>();
        list.add(12);
        list.add(23);
        list.add(1);
        list.add(5);
        list.add(34);

        System.out.println("排序之前:" + list.toString());
        Collections.sort(list);
        System.out.println("排序之后:" + list.toString());

        // 二分查找,找到元素在表中的位置,找不到就返回小于0的值
        int i = Collections.binarySearch(list, 5);
        System.out.println("5所在的位置:" + i);

        // 拷贝
        List<Integer> dest = new ArrayList<Integer>();
        for (i = 0; i < list.size(); i++) {
            dest.add(0);
        }
        Collections.copy(dest, list);
        System.out.println("dest: " + dest.toString());

        // 反转
        Collections.reverse(list);
        System.out.println("反转之后:" + list.toString());

        // 打乱
        Collections.shuffle(list);
        System.out.println("打乱之后:" + list.toString());

        // list转为数组
        System.out.println("--------list转为数组--------");
        Integer[] arr = list.toArray(new Integer[0]);
        System.out.println("数组长度:" + arr.length);
        System.out.println("数组:" + Arrays.toString(arr));

        // 数组转为list,但是此时的集合是一个受限集合,无法做添加与删除操作
        System.out.println("--------数组转为list--------");
        String[] strings = {"张三", "里斯", "王武"};
        List<String> list1 = Arrays.asList(strings);
        System.out.println("list1 :" + list1);

        // 在进行转换时,不能用基本类型int,只能用包装类型
        System.out.println("--------integer转换--------");
        Integer[] nums = {100,200,300,400,500};
        List<Integer> list2 = Arrays.asList(nums);
        System.out.println(list2);
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值