Java之简单的集合

还有一天半就要换个地方了,所以这短暂的时间里需要进行一些扫尾工作,上次的Java还有集合和反射没有更新完,还有深入理解Java虚拟机有几章还没来得及整理,所以时间上比较急,开始介绍一下Java集合

Java集合定义

集合之所以会诞生,是因为Java数组虽然可以存放基本数据类型也可以存放引用数据类型,但是数组的长度是固定的,很不方便,集合的长度是不固定的,所以就引入了集合的概念。

集合和数组很像,但是有明显区别,集合只能存储引用数据类型,不能存放基本数据类型,且集合的长度没有固定。

集合又称之为类集或容器

集合类主要由两个接口派生:Collection和Map,还有个集合工具类Collections

这里写图片描述

Collection接口
Java.util.Collection中Collection接口的定义

public interface Collection<E> extends Iterable<E>

可以发现Collection采用的是泛型技术,故而在操作时必须指定具体的操作类型,利于集合的安全性,Collection时List和Set接口的父接口。

虽然Collection是集合类的基本接口,但一般不会直接使用Collection接口进行操作,而是使用其子接口。Collection接口的主要子接口有如下几个。

  • List< E> :集合 中的元素按照索引值来排序,允许存放重复的元素。List集合和数组相似。
  • Queue< E>:队列接口,通常以先进先出的方式排序各个元素。
  • Set< E>:集合中的元素不按特定方式排序,不能存在重复对象,但其有些实现类能对集合中的元素按照特定的方式排序。
  • SortedSet< E>:可以对集合中的元素进行排序。

List接口

一个有序集合,其元素以线性方式存储,集合中允许存放重复元素,包括null,旗下有Array List和ListedList。

ArrayList类

ArrayList类实现List接口,可以直接通过ArrayList为List接口实例化,允许对集合中的元素进行快速访问,但向ArrayList集合中插入或删除速度较慢。

示例:

package zhao_test;
import java.util.Collection;
import java.util.List;
import java.util.ArrayList;
public class ArrayListDemo {
    public static void main(String []args){
        Collection<String> collection =new ArrayList<String>();
        List<String> list=new ArrayList<String>();
        collection.add("1");
        collection.add("2");
        collection.add("3");
        list.add("A");
        list.add("C");
        list.add(1,"B");
        list.addAll(0,collection);
        System.out.println("list集合:"+list);
        List<String> subList=list.subList(1,5);
        System.out.println("sublist(1,5)集合:"+subList);
        System.out.println("获得list的第3个元素值:"+list.get(2));
        list.set(2,"Set");
        System.out.println("设置list的第3个元素值:"+list.get(2));
        String arr[]=list.toArray(new String[]{});
        System.out.print("List转换为String数组:\n");
        for(String str:arr)
            System.out.print(str+" ");
        System.out.print("\nlist集合是否为空:"+list.isEmpty());
        list.clear();
        System.out.print("\nlist集合是否为空:"+list.isEmpty());
    }
}

这里写图片描述
ArrayList类提供将集合转换为数组的toArray()方法,并没有提供将数组转为集合的方法,但Arrays类提供了asList()方法可以将数组转换为List集合。

ListedList类

链表类,拥有链表的优点,方便插入和删除,但不易查询元素。

List接口中没有定义addFirst()和addLast()方法,所以不能使用List<String> link=new LinkedList<String>();

用法示例:

package zhao_test;
import java.util.LinkedList;
public class LinkedListDemo {
    public static void main(String []args){
        LinkedList<String> link=new LinkedList<String>();
        link.add("1");
        link.add("2");
        link.add("3");
        System.out.println("添加前:"+link);
        link.addFirst("F");
        link.addLast("L");
        System.out.println("添加后:"+link);
    }
}

这里写图片描述

LinkedList获取表头的方法:

package zhao_test;
import sun.awt.image.ImageWatched;

import java.util.LinkedList;
public class LinkedListDemo2 {
    public static void main(String[]args ){
        LinkedList<String> link=new LinkedList<String>();
        link.add("1");
        link.add("2");
        link.add("3");
        link.addFirst("F");
        link.addLast("L");
        LinkedList<String> newList=new LinkedList<String>(link);
        System.out.println("List:"+link);
        System.out.println("get()方法获取表头:"+link.getFirst());
        System.out.println("list: "+link);
        System.out.println("element()方法获取表头:"+link.element());
        System.out.println("list: "+link);
        System.out.println("peek()方法获取表头:"+link.peek());
        System.out.println("list: "+link);
        System.out.println("poll()方法获取表头:"+link.poll());
        System.out.println("list: "+link);
        System.out.println("pop()方法获取表头:"+link.pop());
        System.out.println("list: "+link);

        System.out.println("链表的先进先出:");
        for(int i=0;i<newList.size();i++)
            System.out.print(newList.poll()+" ");

    }
}

这里写图片描述

由上述结果可见,poll()和pop()方法获取表头是将表头弹出,最后的红箭头处值得注意,这也体现了集合的动态性。

Set 接口

Set是一个不包含重复元素的Collection,Set允许null,但只允许一个Set一个null,旗下有HashSet和TreeSet类.

散列集:HashSet类

使用哈希算法来存取集合中的元素,当向HashSet集合中添加元素时,就会调用该元素的hashCode()方法,获取其中的哈希值,然后根据这个哈希值计算出该元素的存放位置。同时需要重写equals()和hashCode()方法。

HashSet集合具有以下特点:

不能保证元素的排列顺序
集合中最多允许存放一个null元素
HashSet集合不是线程同步的。

如果没有重写equals()方法和hashCode()方法,示例:

package zhao_test;
import java.util.Set;
import java.util.HashSet;
class Person{
    private String name;
    private int age;
    public  Person(){
    }

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

    public String toString(){
        return ("name:"+name+",age:"+age+"\n");
    }
}
public class HashSetDemo1 {
    public static void main(String []args){
        Set<Person> set=new HashSet<Person>();
        set.add(new Person("你好",10));
        set.add(new Person("你好",10));
        System.out.print(set);
    }
}

这里写图片描述

运行结果如图所示,竟然能存在着相同的东西,不可思议,这与前面所讲的Set集合不允许存在两个相同的元素相违背,之所以会出现这种情况,是因为这2个new person(”你好“,10)不在同一个内存地址对象中,即Person类没有重写过equals和hahsCode方法,所以引用类型比较的是地址而不是对象本身。

重写了equals和hashCode方法的HashSet集合

package zhao_test;
import java.util.Set;
import java.util.HashSet;
   class Person2{
       private String name;
       private int age;
  public Person2(String name,int age){
           this.name=name;
           this.age=age;
       }
       public boolean equals(Object o){
           if(this==o){
               return true;
           }
           if (o==null)
               return false;
           if(!(o instanceof Person2)){
               return false;
           }
           Person2 per=(Person2)o;
           if(this.name.equals(per.name)&&this.age==per.age){
               return true;
           }else return false;
       }
     public int hashCode(){
           final int prime=13;
           int result=13;
           result =prime*result+((name==null)?0:name.hashCode());
           result=prime*result+age;
           return result;
     }
     public String toString(){
         return ("name:"+name+",age:"+age+"\n");
     }
   }
       public class HashSetDemo2 {
         public static void main(String []args){
             Set<Person2> set=new HashSet<Person2>();
             set.add(new Person2("你好",10));
             set.add(new Person2("你好",10));
             System.out.print(set);
         }
   }

这里写图片描述

从结果中可以看到,最终的Set中就只有这么一个了。

树集:TreeSet类

TreeSet类实现了java.util包中的Set接口和SortedSet接口。TreeSet集合中的元素在默认情况下是升序,当然如果想自定义自己的排序方式可以使用TreeSet类的构造方法TreeSet(Comparator comparator)。

验证下TreeSet集合的默认排序

package zhao_test;
import java.util.Set;
import java.util.TreeSet;
public class TreeSetDemo1 {
    public static void main(String []args){
        Set<Integer> test=new TreeSet<Integer>();
        test.add(1);
        test.add(1);
        test.add(2);
        test.add(5);
        test.add(4);
        test.add(3);
        System.out.print(test);
    }
}

这里写图片描述

从结果中可以看到,TreeSet默认为升序,且去重。

自定义的类排序

若想自定义的类创建的多个对象可以添加到TreeSet集合中,就需要让该自定义类实现Comparable接口,一个类实现Comparable接口必须实现该接口中的int
compareTo()方法;若没有实现Compareable接口的类,只能向TreeSet集合添加一个对象,若添加多个对象,则会产生ClassCastException异常

实现compareTo接口示例:

package zhao_test;
import java.util.Set;
import java.util.TreeSet;
class  Person3 implements Comparable<Person3>{
    private String name;
    private int age;
    public Person3(){
    }
    public Person3(String name,int age){
        this.name=name;
        this.age=age;
    }
    public int compareTo(Person3 per) {
        if (this.age > per.age)
            return 1;
        else if(this.age<per.age)
            return -1;
        else return this.name.compareTo(per.name);
    }
    public String toString(){
        return ("name:"+name+",age:"+age+"\n");
    }
}
public class TreeSetDemo3 {
    public static void main(String []args){
        Set<Person3> test=new TreeSet<Person3>();
        test.add(new Person3("我好",10));
        test.add(new Person3("你好",20));
        test.add(new Person3("我好",15));
        System.out.print(test);

    }

}

这里写图片描述

迭代输出:Iterator接口

示例:

package zhao_test;
import java.util.List;
import java.util.LinkedList;
import java.util.Iterator;
public class IteratorDemo1 {
    public static void main(String []args){
        LinkedList<String> link=new LinkedList<String>();
        link.add("1");
        link.add("2");
        link.add("3");
        link.add("a");
        link.add("b");
        Iterator<String> it=link.iterator();
        while(it.hasNext())
            System.out.print(it.next()+" ");

    }
}

这里写图片描述

Map接口

Map集合中保存键值对,key和value都可以是任何引用数据类型。Map集合中的key不允许重复,每一个key只能映射一个value。key还决定着存储对象在映射中的存储位置,但这不是由key本身决定的,而是由散列技术进行处理的。

Map接口中有多个实现类,较为常用的为HashMap和TreeMap

HashMap

HashMap是基于哈希表的Map接口的实现,允许使用null键和null值,但必须保证键是唯一的。HahsMap是非同步的,也不保证映射顺序。

  • 获取Map集合中全部的key和value(Map是使用的二元偶对象,而Iterator一次只输出一个值,故需要进行处理)
package zhao_test;
import java.util.*;

public class HashMapDemo1 {
    public static void main(String []args){
        Map<Integer,String> map=new HashMap<Integer, String>();
        map.put(1,"清华大学");
        map.put(2,"北京大学");
        map.put(3,"复旦大学");
        Set<Integer> set=map.keySet();
        Iterator<Integer> itKey=set.iterator();
        System.out.println("Map集合中全部的key: ");
        while (itKey.hasNext()){
            System.out.print(itKey.next()+" ");
        }
        System.out.println();
        Collection<String> c=map.values();
        Iterator<String> itValues=c.iterator();
        System.out.println("map中的全部values");
        while(itValues.hasNext())
            System.out.print(itValues.next()+" ");
    }
}

这里写图片描述

Map.Entry接口

public static interface Map.Entry<K,V>

Map.Entry接口是静态的,所以可以直接使用

使用foreach输出Map集合

package zhao_test;
import java.util.Map;
import java.util.HashMap;
public class HashMapDemo2 {
    public static void main(String[]args){
        Map<Integer,String> map=new HashMap<Integer, String>();
        map.put(1,"清华大学");
        map.put(2,"北京大学");
        map.put(3,"复旦大学");
        System.out.println("key--Value");
        for(Map.Entry<Integer,String> mapEntry:map.entrySet())
            System.out.println(mapEntry.getKey()+"-----"+mapEntry.getValue());
    }
}

这里写图片描述

有序树映射类:Tree Map类

Tree Map集合主要是对所有的key进行排序,从而保证所有的key-value映射关系处于有序状态,其默认的排序方式为升序方式。

集合工具类:Collections

  • Collection和Collections的区别

Collection是Java.util包中的接口,是集合类的基本接口,主要子接口有List和Set。
Collections是Java.util包中的类,是针对集合的一个实用工具类,它包含各种集合的搜索、排序和线程安全等一系列的静态方法。

示例:

package zhao_test;
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Iterator;
public class CollectionDemo1 {
    public static void main(String []args){
        List<String> list=new ArrayList<String>();
        list.add("A");
        list.add("B");
        Collections.addAll(list,"1","2","3");
        Iterator<String> it=list.iterator();
        System.out.println("输出集合中的元素");
        while (it.hasNext())
            System.out.print(it.next()+" ");
        System.out.print("\n排序后:\n");
        Collections.sort(list);
        for(String s:list)
            System.out.print(s+" ");
        Collections.reverse(list);
        System.out.println("\n反序:");
        Iterator<String> it1=list.iterator();
        while(it1.hasNext())
            System.out.print(it1.next()+" ");
    }
}

这里写图片描述

关于ArrayList与Vector的区别

Vector是线程安全的,也就是说它的方法之间是线程同步的,而ArrayList是线程不安全的,方法也是线程不同步的,

关于HashMap和Hashtable的区别

Hash Map和Hashtable都是Map接口的实现类,而HashMap是Hashtable的轻量级实现(非线程安全的实现),即Hashtable是线程安全的,也就是说同步的,性能相对较低,而HashMap是线程不安全的,不是同步的,性能相对较高。
值: Hashtable不允许存在null值和null值,而HashMap允许存在一个null键和多个null值。

小结

最近真是乱,得赶快调整下心态,抓紧时间,毕竟大学只有三年

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值