集合

集合:

分为两类:一类是单个方式存储元素,这一类集合中超级父接口:java.util.Collection;一类是以键值对的方式存储元素,这一类集合中国超级父接口:java.util.Map

关于java.utils.Collection接口中常用的方法

  1. collection中能存放什么元素?没有使用“泛型”之前,collection中可以存放Object的所有子类型;使用了“泛型”之后,collection中只能存放某个具体的类型。(集合中不能直接存放基本数据类型,也不能存java对象,只是存储java对象的内存地址)。

  2. collection中常用的方法

    • boolean add(Object e)向集合中添加元素
    public static void f1(){
        //创建一个集合对象
        //Collection c= new Collection();//接口是抽象的,无法实例化
        //多态
    	Collection c= new ArrayList();
        c.add(1200);//自动装箱,实际上是放进去了一个java对象的内存地址
        c.add(3.14);//自动装箱
        c.add(new Object());
        c.add(new Student());
        c.add(true);//自动装箱
    }
    class Student{
        
    }
    
    • int size()获取集合中元素的个数
    System.out.println("集合中元素的个数是:"+c.size);//5
    
    • void clear()清空集合
    c.clear();
    System.out.println("集合中元素的个数是:"+c.size);//0
    
    • boolean contains(Object o)判断集合中是否包含元素o,包含返回true(它在底层怎么判断是否包含某个元素的?调用了equals方法进行对比,equals方法返回true,就表示包含这个元素)
    c.add("hello");
    c.add("world");
    c.add("浩克");
    c.add("绿巨人");
    c.add(1);
    boolean flag = c.contains("绿巨人");
    System.out.println(flag);//true
    boolean flag2 = c.contains("绿巨人2");
    System.out.println(flag);//false
    System.out.println(c.contains(1));//true
    System.out.println("集合中元素的个数是:"+c.size);//5
    
    • boolean remove(Object o)删除集合中某个元素(调用了equals方法进行对比)
    c.remove(1);
    System.out.println("集合中元素的个数是:"+c.size);//4
    
    • boolean isEmpty()判断该集合中元素的个数是否为空
    System.out.println(c.isEptya());//false
    
    • Object[] toArray()调用这个方法可以把集合转换成数组
    Object[] objs = c.toArrary();
    for(int i= 0;i<objs.length;i++){
        //遍历数组
        Object o=objs[i];
        System.out.println(o);
    }
    

    3.集合遍历/迭代器(集合结构发生变化,需要重新获取迭代器)删除集合中元素时,不能使用集合的对象调用removw()方法,应使用迭代器对象调用removw()方法,迭代器删除会自动更新迭代器,并跟新集合。

    public static void f2(){
        //以下的遍历方式/迭代方式,是所有Collection通用的一种方式
        //在Map集合中不能用,在所有的Collection以及子类中使用
        //创建集合对象
        Collection  c = new ArrayList();
        //添加元素
        c.add("abc");
        c.add("def");
        c.add(100);
        c.add(new Object());
        //对集合COllection进行遍历
        //第一步:获取集合对象的迭代器对象Iterator
        Iteartor it = c.iterator();//迭代器对象it最初并没有指向第一个元素
        //第二步:通过以上获取的迭代器对象开始迭代
        /*
        	以下两个方法是迭代器对象Iteartor中的方法:
        	boolean hasNext()如果有元素可以迭代返回true
        	Object next()返回迭代的下一个元素
        */
        boolean hasNext =it.hasNext();
        while(hasNext){
            //存进去是什么类型,取出来还是什么类型
            Object obj = it.next();
            //只不过在输出的时候会转成字符串,因为println会调用toString()方法
            System.out.println(obj);
        }
        
        
        
        //HashSet集合 :无序不可重复
        Collection  c2 = new HashSet();
        c2.add(100);
        c2.add(200);
        c2.add(300);
        c2.add(90);
        c2.add(400);
        c2.add(50);
        c2.add(60);
        c2.add(100);
        Iteartor it2 = c.iterator();
        while(it2.hasNext){
            System.out.println(it2.next());
        }
        //400  50   100  200  90  300  60
    }
    

List接口中常用的方法

对List集合中的元素排序,需要保证List集合中的元素实现了Comprarable接口

1.List集合存储元素特点:有序可重复

有序:List集合元素有下标

从0开始,以1递增

可重复:存储一个1,还可以再存储1

2.List既然是Collection接口的子接口,那么肯定List接口有自己“特色”的方法,以下只列出List接口特有的常用方法

void add(int index,Object element)

Object get(int idex)

int indexOf(Object 0)

Object remove(int index)

Object set(int index,Object element)

public static void f1(){
    //创建list类型集合
    //List myList = new LinkedList();
    //List myList = new Vector();
    List myList = new ArrayList();
    //添加元素
    myList.add("A");//默认向集合末尾添加
    myList.add("B");
    myList.add("C");
    myList.add("C");
    myList.add("D");
    //第一个参数是下标,使用不多,效率低
    myList.add(1,"KING");
    //迭代
    Iterator it = myList.iterator();
    while(it.hasnext()){
        Object elt = it.next();
        System.out.println(elt);
    }
    //A
    //KING
    //B
    //C
    //D
    
    //根据下标来取元素
    Object firstObj= myList.get(0);
    System.out.println(firstObj);
    //因为有下标,所以List集合有自己比较特殊的遍历方式
    //通过下标遍历,List集合特有,Set没有
    for(int i;i < myList.size();i++){
        Object obj = myList.get(i);
        System.out.println(obj);
    }
    
    //获取指定对象第一次出现处的索引
    System.out.println(myList.indexOf("C"));//3
    //获取指定对象最后一次出现处的索引
    System.out.println(myList.lastIndexOf("C"));//4
    
    //删除指定下标位置的元素
    //删除下标为0的元素
    myList.remove(0);
    System.out.println(myList.size());//5
    //修改指定位置的元素
    myList.set(2,"soft");
    //遍历集合
    for(int i = 0;i < myList.size();i++){
        Object obj = myList.get(i);
        System.out.println(obj);
    }
    //KING
    //B
    //soft
    //C
    //D
}

ArrayList类

1.默认初始化容量是10(底层先创建了一个长度为0的数字,当添加一个元素时,初始化容量是10)

2.集合底层是一个Object[]数组,相当于顺序表

3.构造方法:new ArrayList(); new ArrayList(20);

4.ArrayList集合的扩容:原容量的1.5倍。底层是数组,如何优化?尽可能少的扩容,建议使用ArrayList集合的时候预估计元素的个数,给定一个初始化容量。

5.数组优点:检索效率比较高;数组缺点:随机增删元素效率比较低,无法存储大数据量。向数组末尾添加元素,效率很高,不受影响。

6.面试:这么多集合中使用ArrayList最多

7.构造方法

public static void f3(){
    //默认初始化容量10
    List myList = new ArrayList();
    //指定初始化容量100
    List myList2 = New ArrayList(100);
    //创建一个HashSet集合
    Collection c = new HashSet();
    c.add(100);
    c.add(200);
    c.add(900);
    c.add(50);
    //通过这个构造方法就可以将HashSet集合转换成List集合
    List myList3 = new ArrayList(c);
    for(int i=0;i < myList.size();i++){
        System.out.println(myList.get(i));
    }
    //50
    //100
    //90
    //50
}

LinkedList

底层是双向链表,若增删集合中元素较多时,使用LinkedList

public class LinkedListDemo {   
	//顺序表:便于查找  O(1) 增加删除移动元素O(n)
	//链表:便于增删  O(1),查询O(n)
	public static void main(String[] args) {
		LinkedList<String> list=new LinkedList<String>();		
		list.addLast("aaa");
		list.addFirst("bbb");
		System.out.println(list);
		//栈(先进后出 addLast入栈 removeLast出栈)和队列(先进先出addLast入队 removeFirst出队)
		//iterator()从前往后 hasNext   listIterator()从前往后hasNext,从后向前hasPrevious
		Iterator<String> it= list.iterator();
		while(it.hasNext()){
			System.out.print(it.next()+ "   ");
		}
		System.out.println(); //bbb   aaa
		
		ListIterator<String> listIt2=list.listIterator();
		while(listIt2.hasNext()){
			System.out.print(listIt2.next()+ "   ");
		}
		System.out.println();//bbb   aaa 
		
		ListIterator<String> listIt3=list.listIterator();
		while(listIt3.hasPrevious()){
			System.out.print(listIt3.previous()+ "   ");
		}
		System.out.println();//  空的,没有值 ,从第一个开始向前,没有元素,所以为空
		
		ListIterator<String> listIt4=list.listIterator(list.size());
		while(listIt4.hasPrevious()){
			System.out.print(listIt4.previous()+ "   ");
		}
		System.out.println();//aaa   bbb
	}

}

泛型

private static void f1() {
        //可以存放任意类型,但是后期处理数据会带来很多问题
        ArrayList list1 = new ArrayList();
        list1.add(10);
        list1.add("张三");
        list1.add(3.15);
        //确定数据是String类型
        ArrayList<String> list2 = new ArrayList<String>();
        list2.add("张三");

        ArrayList<Integer> list3 = new ArrayList<Integer>();
        list3.add(10);
        //list3.add("张三");//错误,只能存放integer类型
    }

HashSet

初始化容量是16,初始化容量建议2倍,扩容之后是原容量的2倍。

public class HashSetDemo {

	public static void main(String[] args) {
		//线性表 ,有重复的,无序的
		ArrayList<Integer> list=new ArrayList<Integer>() ;
		list.add(1);
		list.add(1);
		System.out.println(list.size());//2

		//集合中元素,没有重复的元素,元素是否有序(无序的,)
		//但是HashSet是有序的,因为它借助HashMap,键值对操作,比较大小的过程
		HashSet<Integer> set=new HashSet<Integer>();//导包 ctrl+shift+o
		set.add(1);
		set.add(1);		
		System.out.println(set.size());//1
		set.add(3);
		set.add(2);
		Iterator<Integer> it=set.iterator();
		while(it.hasNext()){
			System.out.print(it.next()+"  ");
		}
		System.out.println();//1  2  3
		System.out.println(set);//[1, 2, 3]

	}
}
public class HashSetDemo2 {

	public static void main(String[] args) {
		//f2();
		//什么情况下,认为两个学生是同一个,默认情况下同一个对象
		//我们想要这样认为::只要两个的学号相同,我们就认为是同一个,只存储一个
		//集合中,添加元素,首先获取HashCode,如果哈希码不同,直接添加;哈希码相同的情况下,再比较Equals方法,当该方法返回真的时候,不再添加,直接舍去新值。
		//取决于自定义类hashCode() equals方法的定义
		f1(); //1
		f11();//1
	}
	private static void f11() {
		HashSet<Student> set=new HashSet<Student> ();
		Student s1=new Student("001", "zhangsan");
		Student s2=new Student("001", "lisi");
		set.add(s1);
		set.add(s2);		
		System.out.println(set.size());
		System.out.println(set);//[Student [no=001, name=zhangsan]]
	}
	private static void f1() {
		HashSet<Student> set=new HashSet<Student> ();
		Student s1=new Student("001", "zhangsan");
		Student s2=new Student("001", "zhangsan");
		set.add(s1);
		set.add(s2);		
		System.out.println(set.size());
	}
	private static void f2() {
		HashSet<Student> set=new HashSet<Student> ();
		Student s1=new Student("001", "zhangsan");
		Student s2=s1;
		set.add(s2);
		set.add(s1);
		System.out.println(set.size());//1
	}
}

//学生类
public class Student {
	String no,name;

	public Student(String no, String name) {
		super();
		this.no = no;
		this.name = name;
	}
	public Student() {
	
	}
	public String getNo() {
		return no;
	}
	public void setNo(String no) {
		this.no = no;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public int hashCode() {		
		return no.hashCode(); //只考虑学号,不考虑姓名
	}
	@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(no.equals(other.getNo())){
			return true;
		}
		return false;
	}
	@Override
	public String toString() {
		return "Student [no=" + no + ", name=" + name + "]";
	}

}

关于java.utils.Collection接口中常用的方法

1.Map和Collection没有继承关系。

2.Map集合以key和value的方式存储数据:键值对

key和value都是引用数据类型

key和value都是存储对象的内存地址

key起主导地位,value是key的一个附属品

3.Map接口中常用方法

V put(K key,V value) 向Map集合中添加键值对

V get(Object key)通过key获取value

void clear()清空Map集合

boolean containsKey(Object key)判断Map中是否包含某个key

boolean containsValue(Object value)判断Map中是否包含某个value

boolean isEmpty() 判断Map集合中 元素个数是否为0

Set keySet() 获取Map集合所有的key

V remove(Object key)通过key删除键值对

int size()获取Map集合中键值对的个数

Collection values()获取Map集合所有value,返回一个Collection

Set<Map.Entry<K,V>> entrySet() 将Map集合转换成Set集合

假设现在有一个Map集合,如下所示

​ map1集合对象

​ key value


​ 1 zhangsan

​ 2 lisi

​ 3 wangwu

​ 4 zhouliu

Set set = map1.entrySet();

set集合对象

1=zhangsan【注意:Map集合通过entrySet()方法转换成的这个Set集合,Set集合中元素的类型是Map.Entry<K,V>】

2=lisi【Map.Entry和String一样,都是一种类型的名字,只不过:Map>Entry是静态内部类,是Map中的静态内部类】

3=wangwu

4=zhouliu------->这个东西是什么?是Map.Entry

HashMap

在jdk8之后,如果哈希表单向链表中元素个数超过8个,单向链表这种数据结构会变成红黑树数据结构,当红黑树上的结点数量小于6时,会重新把红黑树变成单向链表数据结构。初始化容量16,默认加载因子75扩容是:扩容之后的容量是原容量的2倍。key和value值允许为空。

public class HashMapDemo1 {
    //ArrayList LinkedList HashSet单列集合
	//HashMap是双列集合,键值对集合
	//商品管理,利用ArrayList实现,换用HashMap
	public static void main(String[] args) {
		HashMap<String,Goods>  map=new HashMap<String,Goods>();
		//1<<4  10000 16
		Goods goods=new Goods("001", "苹果", 3.0);
		map.put("001", goods);
		
		goods=new Goods("002", "梨", 3.8);
		//添加
		map.put("002", goods);
		
		goods=new Goods("003", "桃", 2);
		//添加
		map.put("003", goods);
		
		goods=new Goods("004", "芒果", 2);
		//添加
		map.put("004", goods);
		
		goods=new Goods("005", "葡萄", 4.5);
		//添加
		map.put("005", goods);
		
		//查找,利用线性表实现的需要逐个比较,但是利用哈希表不需要比较
		Goods goods2=map.get("001");
		System.out.println(goods2);
		
		//删除
		//map.remove("001");
		
		
		map.keySet();//键的集合
		map.values();//值的集合
		map.entrySet(); //键值对集合
		
		//获取到键,通过键可以获取值
		Set<String> set= map.keySet();
		System.out.println(set); //[004, 005, 001, 002, 003]
		for(String key:set){
			System.out.print(key+"--->"+map.get(key)+",  ");
		}
		System.out.println();//004--->004	芒果	2.0,  005--->005	葡萄	4.5
		
		//只能输出值,不能获取到键
		Collection<Goods> collection=map.values();
		System.out.println(collection);
		//[004	芒果	2.0, 005	葡萄	4.5, 001	苹果	3.0, 002	梨	3.8, 003	桃	2.0]
		for(Goods goods22:collection){
			System.out.println(goods22);
		}
		//键值对,获取到既有键又有值
		 Set<   Entry<String,Goods>   > set2= map.entrySet();
		 for(Entry<String,Goods> entry:set2){
			 System.out.println(entry.getKey()+"--->"+entry.getValue() );
		 }
	}
}

properties

线程安全的,key和value只支持string类型,称为属性类。

public class PropertiesDemo{

	//Property 属性  Properties 键值对集合 存储借助HashMap
	public static void main(String[] args) throws IOException {
		Properties props=new Properties();
		//设置值的方法
		props.put("color", "yello");
		props.setProperty("字体", "宋体");
		
		//获取值的方法
		String s1=props.getProperty("color");
		System.out.println(s1); //yello
		
		String s2=props.getProperty("字号","无");//获取属性,没有的话用默认值
		System.out.println(s2);//无
		
		String s3=(String) props.get("字体");
		System.out.println(s3);//宋体
		
		props.list(System.out);//所有的属性显示到屏幕上
		/*-- listing properties --
		color=yello
		字体=宋体*/
		
		props.list(new PrintStream("aaa.txt") );//获取所有属性,并输出到文件中
	
		//props.save(new FileOutputStream("bbb.txt"), "zhushi");//过时的  //获取所有属性,并输出到文件中
		//props.store(new FileOutputStream("bbb.txt"), "zhushi");  //获取所有属性,并输出到文件中
		props.load(new FileReader("bbb.txt"));  
		//装载的时候怎么,如果原属性有的话,覆盖,没有的话,新增
		System.out.println(props);//{color=黄色, 字号=5, 字体=宋体}
	}
}

TreeSet集合

1.底层实际 上是一个TreeMap

2.底层是一个二叉树

3.放到TreeSet集合中的元素,等同于放到TreeMap集合key部分了

4.集合中的元素:无序不可重复,但是可以按照元素的大小顺序自动排序

5.放在集合中的元素需要实现Comparable接口,并且实现compareTo方法,equals可以不写。

public static void f1(){
    //创建一个TreeSet集合
    TreeSet<String> ts = new TreeSet<>();
    //添加Stirng
    ts.add("zhangsan");
    ts.add("lisi");
    ts.add("wangwu");
    ts.add("zhangsi");
    ts.add("wangliu");
    //遍历
    for(Stirng s:ts){
        System.out.println(s);
    }
    //按字典序排序
    //lisi
    //wangliu
    //wangwu
    //zhangsan
    //zhangsi
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 游动-白 设计师:白松林 返回首页