zoukankan      html  css  js  c++  java
  • Java 类集初探

    类集

    • 类集:主要功能就是Java数据结构的实现(java.util)
    • 类集就是动态对象数组(链表也是动态数组)

    Collection 接口*

    • Collection是整个类集之中单值保存的最大 父接口 。即:每一次仅可以向集合中保存一个对象
    public interface Collection<E>
    extends Iterable<E>
    
    • 在Collection定义的常用操作方法

    常用操作方法

    • 向集合中保存数据
    public  boolean add(E e);
    
    • 追加一个集合
    public boolean addAll(Collection<? extends E>c);
    
    • 清空集合(根元素为null)
    public void clear();
    
    • 判断是否有指定的内容
    public boolean contains(Object o);
    
    • 判断是否为空集合
    public boolean isEmpty();
    
    • 删除对象
    public boolean remove(Object o);
    
    • 取得元素个数
    public int size();
    
    • 以对象数组保存集合
    public Object [] toArray();
    
    • 为Iterator接口实例化
    public Iterator<E> iterator();
    

    contains() 和 remove() 一定要依靠 equals() 的支持;

    List子接口

    • List子接口是Collection接口中最常用的子接口;
    • List对Collection接口进行了功能的扩充;

    常用操作

    • 取得索引编号的内容
    public E get(int index);
    
    • 修改索引的内容
    public E set(int index , E element);
    
    • 为LisIterator接口实例化对象
    public ListIterator<E> listIterator();
    

    List属于接口,如果想使用接口进行操作,就必须存在子类;使用 ArrayList 子类实现(和Vector子类)

    ArrayList子类

    	public static void main(String [] args) throws IOException {
    		List<String> all = new ArrayList<String>();
    		System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
    		all.add("Hello");
    		all.add("Hello");
    		all.add("World");
    		System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
    		// Collection接口定义了size()方法取得集合长度
    		// List子接口增加了 get() 方法,可取取得所有的数据
    		for (int x = 0 ; x < all.size() ; x++) {
    			String str = all.get(x);
    			System.out.println(str);
    		}
    	}
    }
    

    通过对ArrayList()子类的使用分析在:List集合中所保存的数据是按照保存的顺序存放的,而且允许重复数据;List子接口有get()方法,可以获得集合中指定序列的内容

    • 为Collection接口实例化
    public class TestDemo {
    	public static void main(String [] args) throws IOException {
    		Collection<String> all = new ArrayList<String>();
    		System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
    		all.add("Hello");
    		all.add("Hello");
    		all.add("World");
    		System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
    		Object[] obj = all.toArray();//变为对象数组读取数据
    		for (int x = 0 ; x < obj.length ; x ++) {
    			System.out.println(obj[x].toString());
    		}
    		/*for (int x = 0 ; x < all.size() ; x++) {
    			String str = all.get(x);// 由于Collection类中没有get()方法所以无法使用
    			System.out.println(str);
    		}*/
    	}
    }
    
    • List保存对象
    class Book {
    	private String title ; 
    	private double price ;
    	public Book(String title , double price) {
    		this.price = price;
    		this.title = title;
    	}
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj) {
    			return true ; 
    		}
    		if (obj == null) {
    			return false;
    		}
    		if(!(obj instanceof Book)) {
    			return false ; 
    		}
    		Book book = (Book) obj;
    		if (this.title.equals(book.title) && this.price == book.price){
    			return true;
    		}
    		return false;
    	}
    	@Override
    	public String toString() {
    		return this.title + "	" + this.price + "
    ";
    	}
    }
    
    public class TestDemo {
    	public static void main(String [] args) {
    		List<Book> all = new ArrayList<Book>();
    		all.add(new Book("Java",11.1));
    		all.add(new Book("python",22.2));
    		all.add(new Book("C/C++",33.3));
    		all.add(new Book("PHP",44.4));
    		// 切记:remove和contains方法需要在类中覆写equls()类
    		all.remove(new Book("PHP",44.4));
    		System.out.println(all);
    	}
    }
    

    Vector子类(旧)

    • 区别:

      Vector子类采用同步处理,线程安全;而ArrayList子类则采用非线程安全的异步处理机制。ArrayList支持Iterator、ListIterator、foreach输出,而Vector还支持Enumeration。

    总结:

    • List中的数据保存顺序就是数据的添加顺序
    • List集合中允许保存有重复的元素
    • List子接口比Collection扩充了get()、set()方法
    • List大多使用ArrayList子类进行操作

    Set 子接口

    Set子接口只是简单点额继承了Collection接口,并没有效仿List接口对原接口的功能方法进行扩充。

    • 常见子类:HashSet、TreeSet

    • 观察 HashSet 子类:

    public class TestDemo {
    	public static void main(String [] args) {
    		Set<String> all = new HashSet<String>();
    		all.add("Hello");
    		all.add("Hello");//不保存重复的数据
    		all.add("World");
    		all.add("HUAWEI");
    		System.out.println(all + ">>>" + all.size());
    	}
    }
    

    通过观察发现:Set集合下没有重复的数据元素(Set 子接口的特征)即:HashSet 子类特征属于 无序排列

    • 观察 TreeSet子类:
    public class TestDemo {
    	public static void main(String [] args) {
    		Set<String> all = new TreeSet<String>();
    		all.add("Hello");
    		all.add("Hello");//不保存重复的数据
    		all.add("World");
    		all.add("Array");
    		System.out.println(all + ">>>" + all.size());
    	}
    }
    

    分析得出:TreeSet子类没有重复数据,以及所保存的内容默认自动升序排序。

    数据排序问题

    class Book implements Comparable<Book>{
    	private String title ; 
    	private double price ; 
    	public Book(String title , double price) {
    		this.title = title;
    		this.price = price;
    	}
    	@Override
    	public String toString() {
    		return this.title + "	" + this.price;
    	}
    	/*
    	 * 集合本质上就是动态对象数组,而动态的对象数组排序使用的是比较器
    	 * 所以我们使用comparable比较器
    	 * 
    	 * 由于存在重复的元素,compareTo会认为是同一个对象,(Set子接口的特性)
    	 * 所以 set子接口的重复判读就是依靠Comparable
    	 * 为此我们可以使用String的compareTo方法进行同对象的比较
    	 */
    	@Override
    	public int compareTo(Book o) {
    		if (this.price > o.price) {
    			return 1;	
    		} else if(this.price < o.price) {
    			return -1;
    		} else {
    			// 我们调用String类的compareTo方法来比较
    			return this.title.compareTo(o.title);
    		}
    	}
    }
    
    public class TestDemo {
    	public static void main(String [] args) {
    		Set<Book> all = new TreeSet<Book>();
    		all.add(new Book("Java",11.1));
    		all.add(new Book("Java",11.1));		//信息完全重复
    		all.add(new Book("php",11.1));		//信息部分重复
    		all.add(new Book("Python",33.3));	//信息完全不重复
    		System.out.println(all);
    	}
    }
    

    通过观察发现,Comparable接口支持了TreeSet类的重复数据的判断,并不支持对HashSet类的重复数据的判读

    重复元素问题

    通过上述的各段代码发现:Comparable接口(比较器)只负责对TreeSet子类的重复元素的判断;(依靠comparTo()方法,如若发现数据相同则判断为是同样的对象元素,则 return 0;)

    如果要判断数据元素的重复,只能依靠Object中的方法:

    • 取得哈希码
    public int hashCode();
    
    • 对象比较
    public boolean equals(Object obj);
    

    代码:

    	@Override
    	public int hashCode() {
    		final int prime = 31;
    		int result = 1;
    		long temp;
    		temp = Double.doubleToLongBits(price);
    		result = prime * result + (int) (temp ^ (temp >>> 32));
    		result = prime * result + ((title == null) ? 0 : title.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;
    		Book other = (Book) obj;
    		if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
    			return false;
    		if (title == null) {
    			if (other.title != null)
    				return false;
    		} else if (!title.equals(other.title))
    			return false;
    		return true;
    	}
    
    • 总结:

      在不考虑排序问题情况下,判断元素是否重复,依靠Object方法中的 hashCode() 和 equals()

    总结:

    • 在开发中,Set子接口不建议首选,如果使用也是首选建议HashSet类;
    • Comparable 比较器普遍应用于Java理论中

    集合输出

    Collection、List、Set三个接口,List接口是最有利于输出操作的(ArrayList子类),故此集合的输出:

    Iterator*:迭代输出

    public interface Iterator<E> {
        public boolean hasNext();
        public E next<E>();
    } 
    

    Iterator是一个接口,如若取得接口的实例化需要依靠Collection接口iterator()方法

    public Iterator<E> iterator();// java.util.Collection
    
    public class TestDemo {
    	public static void main(String [] args) {
    		Set<String> all = new HashSet<String>();//Set子接口
    		all.add("Mirror");
    		all.add("wangyuyang");
    		all.add("wangyuyang");
    		Iterator<String> iter = all.iterator();// 实例化接口
    		while (iter.hasNext()) { //判断是否为空
    			String str = iter.next();// 获取元素数据
    			System.out.println(str);
    		}
    	}
    }
    

    Set的特性会自动不保留重复数据,并无序输出

    public class TestDemo {
    	public static void main(String [] args) {
    		List<String> all = new ArrayList<String>();//List子接口
    		all.add("Mirror");
    		all.add("wangyuyang");
    		all.add("wangyuyang");
    		Iterator<String> iter = all.iterator();// 实例化接口
    		while (iter.hasNext()) { //判断是否为空
    			String str = iter.next();// 获取元素数据
    			System.out.println(str);
    		}
    	}
    }
    

    显示添加的所有元素并原样添加的顺序输出

    • 集合的输出问题:

      在遇到集合的输出问题是,完全可以直接使用Iterator接口进行输出

    ListIterator:双向迭代

    • Iterator本身只具备”由前向后“的输出,而 ListLterator 子接口则支持双向迭代。

    • 判断是否有前一个元素:(逆向)

    public boolean hasPreviout();
    
    • 取得前一个元素:(逆向)
    public E previous();
    
    • 实例ListIterator接口的List方法:
    public ListIterator<E> listIterator();
    
    public class TestDemo {
    	public static void main(String [] args) {
    		List<String> all = new ArrayList<String>();//Set子接口
    		all.add("A");
    		all.add("B");
    		all.add("C");
    		System.out.println("正向迭代输出");
    		ListIterator<String> iter = all.listIterator();
    		while (iter.hasNext()) { //判断是否为空
    			String str = iter.next();// 获取元素数据
    			System.out.println(str);
    		}
    		System.out.println("***********");
    		System.out.println("逆向迭代输出");
    		while(iter.hasPrevious()) {
    			System.out.println(iter.previous());
    		}
    	}
    }
    

    上例程序实现了双向迭代的功能;利用hasNet()方法判断是否为空,next()方法输出元素内容,实现正向迭代输出;利用ListIterator接口中的hasPrevious()和Previous()方法来实现逆向迭代输出。

    • 注意:

    如果利用ListIterator接口实现逆向迭代输出,就需要先进行正向迭代输出;也就是说在实现逆向迭代输出前必须实现正向迭代输出。

    Enumeration:枚举输出

    Enumeration 和 Vector类同时发布的输出接口;早期的Vector类定义的集合就需要Enumeration 来输出。

    • 接口定义
    public interface Enumberation<E>{
        public boolean hasMoreElements(); //判断是否有下一个元素
        public E nextElement(); // 获取当前元素内容
    }
    
    • 实例化 Enumeration接口对象,只能依靠 Vector子类
    public Enumeration<E> elements() // 取得Enumeration接口对象
    
    public class TestDemo {
    	public static void main(String [] args) {
    		Vector<String> all = new Vector<String>();//Set子接口
    		all.add("A");
    		all.add("B");
    		all.add("C");
    		Enumeration<String> enu = all.elements();
    		while(enu.hasMoreElements()) {
    			System.out.println(new String(enu.nextElement()));
    		}
    	}
    }
    

    foreach 输出

    public class TestDemo {
    	public static void main(String [] args) {
    		List<String> all = new ArrayList<String>();//Set子接口
    		all.add("A");
    		all.add("B");
    		all.add("C");
    		for (String str : all) {
    			System.out.println(str);
    		}
    	}
    }
    

    Map接口

    Collection每次都会保存一个对象,而Map接口主要负责一对对象的信息。

    主要操作方法

    • 向集合中保存数据
    public V put(K key , V value);
    
    • 根据Key查找Value
    public V get(Object key);
    
    • 将Map结合转化为Set集合
    public Set<Map Entry<K,V>> entrySet();
    
    • 取出所有Key值
    public Set<K> keySet();
    
    • 常用子类:
      • HashMap
      • Hashtable

    观察HashMap

    public class TestDemo {
    	public static void main(String [] args) {
    		Map<String,Integer> map = new HashMap<String,Integer>();
    		map.put("壹", 1);
    		map.put("贰", 2);
    		map.put("叁", 3);
            map.put("叁", 33);
    		System.out.println(map);
    	}
    }
    

    通过代码分析可以发现:HashMap实现的输出是无序的;发现的重复的Key会进行覆盖,使用新的内容key的value覆盖原来的value

    • get方法的应用
    public class TestDemo {
    	public static void main(String [] args) {
    		Map<String,Integer> map = new HashMap<String,Integer>();
    		map.put("壹", 1);
    		map.put("贰", 2);
    		map.put(null, 3);
    		System.out.println(map.get("壹")); //返回 1
    		System.out.println(map.get("陸"));//key不存在返回 null
    		System.out.println(map.get(null));// 返回 3
    	}
    }
    

    通过HashMap和get()方法的代码观察发现,Map主要的目的是实现数据的信息的查找,Collection主要的目的是实现信息数据的输出。

    • 取得所有的key值:
    public class TestDemo {
    	public static void main(String [] args) {
    		Map<String,Integer> map = new HashMap<String,Integer>();
    		map.put("壹", 1);
    		map.put("贰", 2);
    		map.put("叁", 3);
    		Set<String> set = map.keySet();// 取得key
    		Iterator<String> iter = set.iterator();
    		while(iter.hasNext()) {
    			System.out.println(iter.next());//输出全部的key
    		}
    	}
    }
    

    观察Hashtable

    public class TestDemo {
    	public static void main(String [] args) {
    		Map<String,Integer> map = new Hashtable<String, Integer>();
    		map.put("壹", 1);
    		map.put("贰", 2);
    		map.put("叁", 3);
    		System.out.println(map);
    	}
    }
    

    通过设置key或value为Null值来比较Hashtable和HashMap两个子类之间区别:Hashtable子类不允许存在null值,而HashMap允许Key或Value中为null值。*

    Iterator输出的问题(重点)

    • 涉及到集合的输出,一定要使用Iterator进行输出;而Map接口中未定义返回Iterator接口对象的方法,故此Map数据使用Iterator输出就需要将Map集合转换为Set集合。

    • 在Collection接口中,Iterator得到的是一个Collection完整的对象;而Map则不同了,但是Map.put()向集合中存一对数据的时候,会自动的封装为Map.Entry接口对象

    public static interface Map.Entry<K,V>;//(等同于一个外部接口)
    
    • Map.Entry接口操作方法
      • getkey():获取Key值
      • getValue():获取Value值

    在Map中保存的实际上是被Map.Entry接口包装的一个对象,Map.Entry接口的对象包装的是:Key和Value值对数据元素。

    • 如上述,Iterator如取出输出的数据实取得是一个对象(Collection接口中就是实质上取得Collection的对象),而在Map接口中,则是取出一个Map.Entry接口对象,然后在得出Key和Value。
    • 在Map定义了一种将Map集合转为Set的方法:
    public Set<Map.Entry<K,V>> entrySet();
    
    • 转为Set集合后,就可以调用Iterator输出。

    • 利用Map接口EntrySet()方法将Map结合变为Set集合 ——> 利用Set结合中的iterator()方法将Set进行Iterator输出 ——> 每一次取出的Set元素都是Map.Entrty接口对象,利用此对象进行Key与Value的取出

    利用Iterator实现Map接口的输出 *

    public class TestDemo {
    	public static void main(String [] args) {
    		Map<String,Integer> map = new Hashtable<String, Integer>();
    		map.put("壹", 1);
    		map.put("贰", 2);
    		map.put("叁", 3);
    		// 将Map集合变为Set结合
    		Set<Map.Entry<String, Integer>> set = map.entrySet();
    		// 将Set集合实例化iterator接口对象
    		Iterator<Map.Entry<String, Integer>> iter = set.iterator();
    		while(iter.hasNext()) {
    			// 因为iter内容保存的是Map.Entry接口的对象,所以利用Map.Entry对象将Key和Value取出
    			Map.Entry<String, Integer> men = iter.next();
    			System.out.println(men.getKey() + "==" + men.getValue());
    		}
    	}
    }
    

    Map集合中的Key

    使用的Map集合,Key的类型可以自定义;那么这个自定义的类型必须覆写Object类之中的hashCode() 和 equals()方法,因为只有依靠这两个方法,才可以判断是否元素重复。【首先的Key类型是String,尽量不要使用自定义的对象类型去定义key;因为String类中默认了hashCode() 和 equals()】

    class Book{
    	private String title ; 
    	public Book(String title) {
    		this.title = title;
    	}
    	@Override
    	public String toString() {
    		return this.title;
    	}
    	@Override
    	public int hashCode() {
    		final int prime = 31;
    		int result = 1;
    		result = prime * result + ((title == null) ? 0 : title.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;
    		Book other = (Book) obj;
    		if (title == null) {
    			if (other.title != null)
    				return false;
    		} else if (!title.equals(other.title))
    			return false;
    		return true;
    	}
    	
    }
    
    public class TestDemo {
    	public static void main(String [] args) {
    		Map<Book,String> map = new HashMap<Book, String>();
    		map.put(new Book("java"),new String ("开发"));
    		System.out.println(map.get(new Book("java")));
    	}
    }
    

    或者:

    public class TestDemo {
    	public static void main(String [] args) {
    		Map<String,Book> map = new HashMap<String, Book>();
    		map.put(new String ("开发"),new Book("java"));
    		System.out.println(map.get(new String("开发")));
    	}
    }
    
    public class TestDemo {
    	public static void main(String [] args) {
    		Map<String,Book> map = new HashMap<String, Book>();
    		map.put("开发",new Book("java"));
    		System.out.println(map.get("开发"));
    	}
    }
    

    总结

    • Map集合保存数据更有利与查找,而Collection保存数据是为了输出
    • Map使用Iterator接口输出步骤:……
    • HashMap可以保存Null,Hashtable不可以保存null。
    • 可以不可以重复,一旦出现重复会覆盖原有内容(更新Key的Value值)

    Stack子类

    Stack 表示:栈操作;栈是一种先进后出的数据结构;而Stack是Vector的子类。

    public class Stack<E>
    extends Vector<E>
    

    需要注意:Stack虽是Vector子类,可是不会使用Vector方法。

    Stack栈操作:

    • 入栈:
    public E push(E item);
    
    • 出栈:
    public E pop();
    
    • 实现入栈、出栈操作
    public class TestDemo {
    	public static void main(String [] args) {
    		Stack<String> all = new Stack<String>();
    		all.push("A");
    		all.push("B");
    		all.push("C");
    		all.push("D");
    		System.out.println(all.pop());
    		System.out.println(all.pop());
    		System.out.println(all.pop());
    		System.out.println(all.pop());
    	}
    }
    

    如果栈中数据已经全部执行出栈而依旧继续执行出栈pop操作,则报错:空栈异常(栈中无数据则无法出栈执行操作)

    Properties子类

    Collections工具类

    • 向集合中追加一组数据
    public static <T> boolean addAll(Collection<E> c,……);
    
    public class TestDemo {
    	public static void main(String [] args) {
    		List<String> all = new ArrayList<String>();
    		Collections.addAll(all, "A","B","C","D");
    		System.out.println(all);
    	}
    }
    

    Collections工具类是负责给集合操作接口Collection提供辅助的操作方法

  • 相关阅读:
    面向对象定义
    xml与面上对象初识
    模块configparser/subprocess/表格处理模块
    python模块
    python-判断语句
    python了解
    Qt Qwdget 汽车仪表知识点拆解7 图像绘制,旋转
    Qt Qwdget 汽车仪表知识点拆解6 自定义控件
    Qt Qwdget 汽车仪表知识点拆解5 标题栏图标闪烁
    Qt Qwdget 汽车仪表知识点拆解4 另类进度条实现
  • 原文地址:https://www.cnblogs.com/wangyuyang1016/p/11219121.html
Copyright © 2011-2022 走看看