集合(Collection)

1、数组与集合的异同

数组与集合均为Java中用于存放数据的容器,但数组的长度是固定的,一旦对数组进行了初始化,其长度,或者说所占用的存储单元即固定,其不能进行动态扩展,且数组仅能存储同一数据类型的数值。而集合区别于数组最重要的一点即集合长度可变,且可以存储任何引用对象的数据,也包括了基本数据类型的包装类。

2、Java中的Collection为一个接口,不能使用其直接创建集合,一般用实现了该接口的类来实现进行对数据的操作。Collection接口的常用方法如下:

boolan add(E);//向集合中添加指定元素(如果尚未存在),其中的E为泛型
void clear();//删除集合中的所有元素
Object clone();//返回此HashSet实例的浅层副本,元素本身不被克隆
boolean contains(Object o);//返回集合是否包含指定元素
boolean isEmpty();//如果集合不包含元素,返回true(需要注意的是该方法仅能欧判断集合的元素个数为0,或者说size为0,实际开发中必须先对集合进行非空判断,再调用该方法!)
Iterator<E> iterator();//返回此集合中元素的迭代器
int size();//返回此集合中元素的个数
Object [] toArray();//返回包含此collection所有元素的数组
Spliterator<E> spliterator() ;//在此集合中的元素上创建late-binding和故障快速 Spliterator 。???这是个啥???

此外,Collection还包含了两个静态方法

public static void shuffle(List list);//打乱顺序
public static void sort(List list);//把集合元素按照自然顺序(123,abc)排序

3集合的遍历
集合的遍历常用方法有三种,一种是针对有下标的集合,如ArrayList,可以使用原始的for循环进行遍历获取其元素;第二种是使用foreach进行循环;第三种是使用迭代器对集合进行遍历。第二种及第三种的示例代码如下:

foreach遍历:(foreach也可以用于数组)
		Collection<Object> collection = new ArrayList<Object>();//多态
		for(Object obj:collection) {
			Object s = obj;
		}
迭代器遍历:
		Collection<Object> collection = new ArrayList<Object>();//多态
		Iterator<Object> it = collection.iterator();
		while(it.hasNext()){//判断有没有下一个元素
			Object s = it.next();//如果有取出下一个元素
		}

   对于这两中遍历方式,foreach方法的底层实现代码,实际上仍为迭代器。

注意事项:
a、在使用迭代器时,注意hasNext()方法必须与next()方法配合使用。hasNext()判断集合的下一个存储单元是否有元素,而调用next()将会使迭代器指向集合的下一个存储单元(说法不太准确)。如,在同一个while循环中调用两次next()方法,这会导致直接取出集合中的两个元素,无论这个元素是否会被使用,那么在下一次调用hasNext()方法时,会直接判断第三个元素的存储位置是否包含元素。
b、无论使用迭代器还是使用foreach对集合进行遍历,都必须注意在遍历的过程中绝不允许对集合的长度进行改变,例如进行add或者remove操作,这会导致并发修改异常(ConcurrentModificationException),切记不能在使用这两种方法遍历集合的时候一边遍历一边增加或者删除,这很stupid,我就干过。。。

4泛型

泛型为JKD1.5后的新特性,基本格式为、<K,V>,它用来灵活地将数据类型应用到类、接口、方法中,将数据类型作为参数进行传递,即上述基本格式中,E、K、V实际上就是一个变量,只是它们被用于接收数据类型。借助泛型可以在类中预支地使用未知的类型。
泛型的好处:泛型可以有效地将运行时的ClassCastException异常转换为编译时异常,可以及时尽快地被发现类型错误,且可以有效地避免类型强制转换的麻烦。

泛型的定义格式及使用(尖括号加E不显示怎么破,,老哥们评论一下解决办法~~导致这一段泛型描述像智障文章)
a、泛型用于类,则该类被称为泛型类
格式:public class 类名,如public class ArrayList
使用:当创建类的对象时,需要确定泛型的类型,如ArrayList = new ArrayList();
(自己创建的类可以用应用泛型,这样就可以在实际创建对象再进行对成员变量类型的确定)

b、泛型用于方法
格式:public 返回值类型 方法名(E e);
使用:当调用泛型方法时,需要确定泛型的类型,即方法传递的参数的类型

c、泛型用于接口
格式:public interface 接口名
使用:接口的实现类可以直接在实现接口时指明泛型的类型;或接口的实现类可以在实现时不指明泛型的类型,当使用实现类创建对象时,再确定泛型的类型。

泛型通配符
当使用泛型类或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合中元素自身方法无法使用。
定义:如ArrayList的构造方法ArrayList(Collection<? extends E> c)
含义:
? extends E代表只要是E类型的子类即可
? super E代表只要是E类型的父类即可

5常用数据结构及特点
1.堆栈结构
特点:先进后出
2.队列结构
特点:先进先出
3.数组结构
查询快
增删慢
4.链表结构
查询慢
增删快
5.哈希表结构:(数组结构+链表结构)
查询快
增删快

6、Collection接口的常用子接口为List接口和Set接口,List接口的常用实现类为ArrayList、LinkedList,Set接口的常用实现类为HashSet、LinkedHashSet、TreeSet

7List

List接口的特点为:有下标、有序(存取顺序)、可重复

实现类及其数据结构:

ArrayList:数组结构,查询快,增删慢
LinkedList:链表结构,查询慢,增删快
Vector:数组结构,查询快,增删慢

实现类的常用方法:
公有方法:

增: add(E e);add(int index,E e);
删: remove(Object obj);remove(int index);
改: set(int index,E e);
查: get(int index);
size(),clear(),contains(Object obj),toArray(),iterator();isEmpty()

ArrayList常用方法即对List接口的公有方法进行了实现,方法名一致
LinkedList特有方法:

第一组:
void addFirst(E e);
void addLast(E e);
第二组:
E removeFirst();//删除首个元素,返回被删除的元素
E removeLast();//删除尾部元素,返回被删除的元素
第三组:
E getFirst();
E getLast();
第四组:
E pop();//弹出,删除集合中的某一个元素,和 removeFirst功能是一样的
void push(E e);//推入,把一个元素添加到集合中, 和addFist功能是一样的

8Set
Set接口特点:元素是无序的(LinkedHashSet和TreeSet除外),无下标,不可重复
实现类:HashSet,LinkedHashSet,TreeSet
HashSet:底层采用哈希表结构,查询快,增删快,无序的
LinkedHashSet:底层采用 链表+哈希表,查询快,增删快,有序的
Set接口中和父接口Collection基本一模一样

9哈希值
任何对象都有一个哈希值,哈希值是一个对象的数字表示
String类中的hashCode方法,只要String字符串内容相同,那么这两个字符串对象调用String的hashCode返回值即一样。但需要注意的是,字符串内容相同,哈希值一定一样,但反过来则未必。

10哈希表结构

数组结构+链表结构,特点:查询快,增删快

哈希表结构判断元素是否重复的原理:
首先判断新元素和旧元素的哈希值是否相同,如不同直接判定为不同
如果哈希值相同,再调用equals方法进行判断,如果两个方法都返回true,则判定两个元素一样。
因此,当使用Set集合时,如果泛型为自定义类,那么需要重写Object类的hashCode方法和equals方法,才能正确地保证Set中的元素不会重复

contains()方法和add()方法使用了这一原理

11Map
Map集合中的元素以键值对的方式存在。
Map的常用实现类为:HashMap和LinkedHashMap
HashMap<K,V>:存储结构采用哈希表结构,元素的存取顺序不能保证一致,由于要保证键的唯一,重写了hashCode和equals方法。
LinkedHashMap<K,V>:该类为HashMap的子类,存储结构为哈希表+链表结构,该类可以保证元素的存取顺序一致。

Map接口的常用方法:
V get(Object key);//返回指定键所映射的值,如果不存在,则返回NULL
V put(K key,V value);
V remove(Object key);//根据key删除元素,返回被删除的元素的值

Map的两种遍历方式:
对Map的遍历可用keySet()方法或者entrySet()方法,前者会返回包含Map的key的Set,后者会返回Map中的映射关系组成的Set,遍历示例代码如下:

第一种keySet():
	Map<Object, String> map = new HashMap<Object, String>();
	Set<Object> keys = map.keySet();
	Iterator<Object> it = keys.iterator();
	while(it.hasNext()){
		 Object key = it.next();
		 Object value = map.get(key);
	}
第二种entrySet():
	Map<Object, Object> map = new HashMap<Object, Object>();
	Set<Map.Entry<Object, Object>> entrySet = map.entrySet();
	Iterator<Map.Entry<Object, Object>> it = entrySet.iterator();
	while(it.hasNext()){
		Map.Entry<Object, Object> entry = it.next();
		Object key = entry.getKey();
		Object value = entry.getValue();
	}

12Properties属性集合
class Propeties extends HashTable implements Map,其本质是一个Map,它是一个持久的属性集(可以自己写数据到文件),它的泛型固定,为<String,String>,它具有Map的一切方法,此外,该类具有一些特有的方法:

public String getProperty(String key)用指定的键在此属性列表中搜索属性的值,功能和Map中的get是一样
public Object setProperty(String key, String value);添加键值对,功能和Map的put方法是一样
public Set<String> stringPropertyNames()://和Map中的keySet方法是一样
store();//保存数据到文件,实际上不是保存到文件 而是写入到流中,由流写到文件
load();//从文件中加载数据,实际上不是直接加载文件,而是加载流中的数据,而流的数据是从该文件中读取的

利用Propertie读取Java工程中的Properties文件中的键值对代码示例

Properties pr = new Properties();
FileReader fr = new FileReader("test.properties");
pr.load(fr);
fr.close();
Set<String> set = pr.stringPropertyNames();
Iterator<String> it = set.iterator();
while(it.hasNext()) {
	String key = it.next();
	String value = pr.getProperty(key);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值