首页 > 编程语言 > 详细

Java集合入门

时间:2020-03-16 15:36:42      阅读:42      评论:0      收藏:0      [点我收藏+]

Collection中的常用方法

boolean add(E e) 在集合中添加元素
boolean addAll?(Collection<? extends E> c)

往集合中添加另一个集合

 void clear()  清空集合
boolean contains?(Object o)  该集合是否包含指定的元素
boolean containsAll?(Collection<?> c) 集合是否包含指定合c中的全部元素
boolean isEmpty() 判断集合是否为空
boolean remove?(Object o) 移除集合中的元素
boolean removeAll?(Collection<?> c) 移除集合对象中的和集合c中相同的元素
boolean retainAll?(Collection<?> c) 返回和集合c的交集
int size() 返回集合的大小
Iterator<E> iterator() 返回集合的迭代器对象

集合典型继承体系树

   Collection

    |--List:元素是有序的,元素可以重复,因为该集合体系有索引。需要注意的是,contains和remove方法底层使用的是equals方法。因此,在去除集合中的重复元素时一定要在自定义的类中覆盖Object类中的equals方法,实现自己的子类方法,这时就不需要逐个去比较了,直接用集合的contains方法

      |--ArrayList:底层使用的是数组结构。特点:查询速度快,但是增删速度慢。线程不同步。

      |--LinkedList:底层使用的是链表结构。特点:增删速度快,查询速度慢。

 

      |--Vector:底层是数组数据结构。元老级。Vector是同步的。被ArrayList替代了。枚举是Vector特有的取出方式。其实枚举和迭代器是相同的。

    |--Set:元素不保证顺序(存入和取出的顺序不一定一致),不包含重复元素。

      |--HashSet:底层使用的是哈希表。线程非同步。该集合通过hashCode和equals方法来判断集合中的元素是否相同。先调用hashCode方法,如果该方法的返回值相同,再调用equals方法。对于判断元素是否相同,删除集合中的元素等,底层使用的方法还是hashCode和equals方法。

      |--TreeSet:底层使用的是二叉树结构。可以对传入的元素进行自动排序,排序使用的是Comparable接口中的compareTo方法。如果方法返回值是0,则代表传入的数据相同,则忽略该元素。

        对元素的排序有两种方式:

         1.元素自身具备自然排序,其实就是自定义的类实现了Comparable接口重写了compareTo方法

         2.比较器排序,在创建TreeSet集合时,在构造函数中指定具体的比较器方法。需要定义一个类实现Comparator接口,重写compare方法

 List集合特有方法:

  由于List集合体系带有索引,所以可以使用常规取出数组的操作来取出List集合中的元素。

 

void add?(int index, E element) 在指定位置添加元素
boolean addAll?(int index, Collection<? extends E> c) 在指定位置添加集合
E remove?(int index) 删除指定位置上的元素
E set?(int index, E element) 修改指定位置上的元素
E get?(int index) 获取指定位置上的元素
List<E> subList?(int fromIndex, int toIndex) 获取指定范围内的集合
ListIterator<E> listIterator() 在迭代时可以进行增删改操作

  eg:常规取出方式:    

public class Test {
    public static void main(String[] args) {
        ArrayList<String> s1 = new ArrayList<String>();
        s1.add("java1");
        s1.add("java2");
        s1.add("java3");
        s1.add("java4");
        for (int i = 0; i < s1.size(); i++) {
            System.out.println(s1.get(i));
        }
    }

}

    迭代器方式:

public class Test {
    public static void main(String[] args) {
        ArrayList<String> s1 = new ArrayList<String>();
        s1.add("java1");
        s1.add("java2");
        s1.add("java3");
        s1.add("java4");
        for (Iterator<String> iterator = s1.iterator(); iterator.hasNext();) {
            String string = (String) iterator.next();
            System.out.println(string);
            
        }
        
    }

}

去除ArrayList集合中的重复元素

  LinkedList集合特有方法

    根据removeFirst()方法会返回并删除第一个元素,也可以实现元素的迭代。

void addFirst(); 升级版JDK1.6后 boolean offerFirst?(E e)  
void addLast();   boolean offerLast?(E e)  
E getFirst(); 如果没有元素会抛出NoSuchElementException异常。 E peekFirst() 如果没有元素会返回null
E getLast(); 如果没有元素会抛出NoSuchElementException异常。 E peekLast() 如果没有元素会返回null
E removeFirst(); 如果没有元素会抛出NoSuchElementException异常。 E pollFirst() 如果没有元素会返回null
E removeLast(); 如果没有元素会抛出NoSuchElementException异常。 E pollLast() 如果没有元素会返回null

    使用LinkedList的特有方法实现堆栈、队列结构

package second.study;

import java.util.LinkedList;

public class Test {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<String>();
        stack.myAdd("Java01");
        stack.myAdd("Java02");
        stack.myAdd("Java03");
        stack.myAdd("Java04");
        while(!stack.isNull()) {
            System.out.println(stack.myGet());
        }
        System.out.println("hello");
    }
}

class Stack<E>{//堆栈结构:先进后出
    private LinkedList<E> link;
    Stack(){
        link = new LinkedList<E>();
    }
    public boolean myAdd(E e) {
        return link.offerFirst(e);
    }
    public E myGet() {
        return link.pollFirst();
    }
    public boolean isNull() {
        return link.isEmpty();
    }
}

class Queue<E>{//队列结构,先进先出
    private LinkedList<E> link;
    Queue(){
        link = new LinkedList<E>();
    }
    public boolean myAdd(E e) {
        return link.offerFirst(e);
    }
    public E myGet() {
        return link.pollLast();
    }
    public boolean isNull() {
        return link.isEmpty();
    }
}

泛型

   好处:

    1.将运行时期出现的问题ClassCastException,转移到了编译时期。

    2.避免了强制转换的麻烦。

   格式:

    通过<>来定义要操作的引用数据类型。

  泛型方法:

    public <T> void show(T t);

    特殊:静态方法不可以访问类上定义的泛型。如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

  通配符 ?作用:一般用于程序的扩展,但也有局限性。

    ? extends E:可以接收E类型或E的子类型,上限;

    ? super E:可以接收E类型或E的父类型,下限;

 Map集合

  该集合存储键值对,一对一对往里存,而且要保证键的唯一性。Set集合底层就是调用的Map集合。

  添加元素时,如果出现相同的键,那么后添加的值会覆盖原有键对应的值。并返回被覆盖的值。

Map集合典型继承体系树

  Map集合的两种取出方式:

    1.Set<K> keySet()方法:将map中所有的键存入到Set集合中,因为Set具备迭代器,可以使用迭代器方式取出所有的键。再根据Map集合中的get方法,获取每个键对应的值。

    2.Set<Map.Entry<K,V>> entrySet()方法:将map集合中的映射关系存入到Set集合中,而这个关系的数据类型为Map.Entry。

  Map

    |--Hashtable:数据结构:哈希表,同步的,不允许null作为键和值。被HashMap替代。

      |--Properties:属性集,键和值都是字符串,而且可以结合流进行键值操作,等到了IO流,会更清楚。

    |--HashMap:数据结构:哈希表,不同步的,允许null作为键和值。

      |--LinkedHashMap:基于链表+哈希表,可以保证map集合有序(存入和取出的顺序一致)。

    |--TreeMap:数据结构:二叉树。不是同步的,可以对map集合中的键进行排序。

项目练习

  需求:

   每一个学生都有自己的归属地;

  学生属性:姓名,年龄;
  注意:姓名和年龄相同的视为同一个学生

package second.study;

public class Student implements Comparable<Student> {

    private String name;
    private int age;
    
    public Student(String name, int age) {
        super();
        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 int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        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 (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

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

    @Override
    public int compareTo(Student o) {//按年龄排序,年龄相同按姓名字典顺序排序
        int res =  Integer.valueOf(this.age).compareTo(Integer.valueOf(o.age));
        return res == 0?this.name.compareTo(o.name):res;
    }

}
package second.study;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
//使用HahMap存储
public class Test {
    public static void main(String[] args) {
        HashMap<Student,String> hashMap = new HashMap<Student, String>();
        hashMap.put(new Student("zhangsan1", 20), "shanghai");
        hashMap.put(new Student("zhangsan2", 30), "nanjing");
        hashMap.put(new Student("zhangsan3", 28), "zhejiang");
//        hashMap通过判断键中的hashCode和equals方法,来判断键是否相同,相同则覆盖值。
        hashMap.put(new Student("zhangsan3", 28), "tianjin");
        hashMap.put(new Student("zhangsan4", 25), "hangzhou");
//        通过获取hashMap中的键,来迭代。
        Set<Student> set = hashMap.keySet();
        for (Iterator<Student> iterator2 = set.iterator(); iterator2.hasNext();) {
            Student student = iterator2.next();
            String add = hashMap.get(student);
            System.out.println(student + "..." + add);
            
        }
//        获取迭代器中的键值关系来获取键值
        Set<Map.Entry<Student,String>> mapEntry = hashMap.entrySet();
        for (Iterator<Map.Entry<Student,String>> iterator = mapEntry.iterator(); iterator.hasNext();) {
            Map.Entry<Student, String> entry = iterator.next();
            System.out.println(entry.getKey() + "......" + entry.getValue());
            
        }
    }
}
Res:
Student [name=zhangsan4, age=25]...hangzhou
Student [name=zhangsan1, age=20]...shanghai
Student [name=zhangsan2, age=30]...nanjing
Student [name=zhangsan3, age=28]...tianjin
Student [name=zhangsan4, age=25]......hangzhou
Student [name=zhangsan1, age=20]......shanghai
Student [name=zhangsan2, age=30]......nanjing
Student [name=zhangsan3, age=28]......tianjin

  使用TreeMap存储

package second.study;

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

public class Test {
    public static void main(String[] args) {
        TreeMap<Student,String> treeMap = new TreeMap<Student, String>();
        treeMap.put(new Student("zhangsan1", 20), "shanghai");
        treeMap.put(new Student("zhangsan2", 30), "nanjing");
        treeMap.put(new Student("zhangsan3", 28), "zhejiang");
//        hashMap通过判断键中的hashCode和equals方法,来判断键是否相同,相同则覆盖值。
        treeMap.put(new Student("zhangsan3", 28), "tianjin");
        treeMap.put(new Student("zhangsan4", 25), "hangzhou");
        treeMap.put(new Student("zhangsan1", 25), "hangzhou");
//        通过获取hashMap中的键,来迭代。
        Set<Student> set = treeMap.keySet();
        for (Iterator<Student> iterator2 = set.iterator(); iterator2.hasNext();) {
            Student student = iterator2.next();
            String add = treeMap.get(student);
            System.out.println(student + "..." + add);
            
        }
//        获取迭代器中的键值关系来获取键值
        Set<Map.Entry<Student,String>> mapEntry = treeMap.entrySet();
        for (Iterator<Map.Entry<Student,String>> iterator = mapEntry.iterator(); iterator.hasNext();) {
            Map.Entry<Student, String> entry = iterator.next();
            System.out.println(entry.getKey() + "......" + entry.getValue());
            
        }
    }
}
Res:
Student [name=zhangsan1, age=20]...shanghai
Student [name=zhangsan1, age=25]...hangzhou
Student [name=zhangsan4, age=25]...hangzhou
Student [name=zhangsan3, age=28]...tianjin
Student [name=zhangsan2, age=30]...nanjing
Student [name=zhangsan1, age=20]......shanghai
Student [name=zhangsan1, age=25]......hangzhou
Student [name=zhangsan4, age=25]......hangzhou
Student [name=zhangsan3, age=28]......tianjin
Student [name=zhangsan2, age=30]......nanjing

集合框架工具类(Collections)全部是静态方法

  常见方法:

    1.static <T extends Comparable<? super T>> void sort?(List<T> list);//对List集合中的元素按照元素中的compareTo方法排序;

       static <T extends Comparable<? super T>> void sort?(List<T> list, Comparator<? super T> c);//对List集合中的元素按照自定义的compareTo方法排序;

    2.static <T extends Object & Comparable<? super T>> T max?(Collection<? extends T> coll);//对List集合中的元素按照元素中的compareTo方法的返回值大小获取最大值;

       static <T> T max?(Collection<? extends T> coll, Comparator<? super T> comp);//对List集合中的元素按照自定义的compareTo方法的返回值大小获取最大值;

    3.static <T> int binarySearch?(List<? extends Comparable<? super T>> list, T key);//List中的元素必须实现Comparable接口,然后用1.(1)的sort方法对集合进行排序后可返回正确结果。

       static <T> int binarySearch?(List<? extends T> list, T key, Comparator<? super T> c);//List中的元素必须实现Comparable接口,然后用1.(2)的sort方法对集合进行排序后可返回正确结果。

    4.static <T> Comparator<T> reverseOrder();//对该集合中的元素的排序方法强行逆转;

      static <T> Comparator<T> reverseOrder?(Comparator<T> cmp);//对自定义的比较器强行逆转。

数组集合工具类(Arrays)全部是静态方法

   常见方法:

     1.static <T> List<T> asList?(T... a); //将数组转成List集合,可以使用集合的思想操作字符串,但是不可以进行增删操作。

      注意:如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素。

         如果数组中的元素是基本数据类型时,那么会将该数组作为集合中的元素存在。eg:int[] arr = {2,3,4};List<int[]> list = Arrays.asList(arr);

   将集合变成数组,使用的是集合中的toArray方法(<T> T[] toArray?(T[] a),优势:为了限定对元素的操作,不能进行增删操作。

      注意:当传入参数类型的长度小于集合的size,内部会创建一个新数组,长度为集合的size。

         当传入参数类型的长度大于集合的size,就不会创建数组了,而是使用传递进来的数组。

Java集合入门

原文:https://www.cnblogs.com/star-491849224/p/12499778.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!