集合Collection
集合Collection
集合-属于 java.util包,包括List(I)【列表】,Set(I)【集】,Queue(I)【队列】,Map(I)【映射】;List可以用利用ArrayList©,LinkedList©,Vector©来实现;Set可以利用SortedSet(I)来实现,SortedSet(I)又可以利用HashSet©来实现;Queue可以用Deque(I),LinkedList©来实现
注:C为一般类(Class),I为接口(Interface)
其他还有枚举Enum、注解Annotation、数组
大致分类如下所示
接下来我将注重于代码解释,至于概念什么的网上搜一搜都有,写这个是因为感觉集合分类有点精辟所以写一写,万一以后忘了呢。
List接口
列表List属于接口,可以加入重复元素以及null,支持泛型。可以理解为存放对象的数组,只不过其元素个数可以动态的增加或减少
这之下又有ArrayList以及LinkedList子接口,分别用动态数组和链表的方式实现了List接口
ArrayList:更适合于随机访问
@Test
public void test04() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("java");
arrayList.add("cpp");
arrayList.add("php");
// get方法得到arraylist中的元素
System.out.println(arrayList.get(0));
// set会返回之前的字符串——“java”
String va = arrayList.set(0, "javascript");
System.out.println(va);
System.out.println(arrayList.get(0));
// 交换元素
arrayList.set(0, arrayList.set(2, arrayList.get(0)));
System.out.println(arrayList);
ArrayList<String> sub = (ArrayList<String>) arrayList.subList(0, 2);
System.out.println(sub);
System.out.println(arrayList);
}
@Test
public void test05() {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("java");
arrayList.add("cpp");
arrayList.add("php");
arrayList.add("C++");
System.out.println(arrayList);
List<String> sub = arrayList.subList(0, 2);
System.out.println(sub);
System.out.println(arrayList);
// subList获取的List与原List占有相同的存储空间
// 对子List的操作(删除等)会影响原List
sub.remove(1);
System.out.println(sub);
System.out.println(arrayList);
// list转换为数组
String[] strArr = arrayList.toArray(new String[] {});
System.out.println(Arrays.toString(strArr));
// 数组转换为list
List<String> list_from_array = Arrays.asList(strArr);
System.out.println(list_from_array);
// 返回的集合我们不能对其增删元素,否则会抛出异常
// 抛出异常:UnsupportedOperationException
// list_from_array.add("c#");
}
@Test
public void test06() {
/**
* List排序: Collection.sort方法实现排序
*/
List<Integer> list = new ArrayList<Integer>();
Random r = new Random(1);
for (int i = 0; i < 10; i++) {
list.add(r.nextInt(100));
}
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
@Test
public void test07() {
/**
* Comparable接口:在排序的操作中临时指定比较规则
*/
List<Cell> cells=new ArrayList<Cell>();
cells.add(new Cell(2,3));
cells.add(new Cell(5,1));
cells.add(new Cell(3,2));
Collections.sort(cells, new Comparator<Cell>() {
public int compare(Cell o1,Cell o2) {
return o1.col-o2.col;
}
});
for (Cell i :cells) {
System.out.println(i.col);
}
}
LinkedList:更适合于插入和删除
@Test
public void test08() {
/**
* Queue(队列)接口:特殊的线性表
* 队列限制了对线性表的访问方式:
* 只能从线性表的一端添加(offer)元素,
* 从另一端取出(poll)元素
* 遵循先进先出(FIFO)的原则
*/
Queue<String>queue=new LinkedList<String>();
//.offer()——将一个对象添加至队尾,如果添加成功则返回true
queue.offer("a");
queue.offer("b");
queue.offer("c");
System.out.println(queue);
//.peek()——返回队首元素(不删除)
String str=queue.peek();
System.out.println(str);
System.out.println(queue);
//.poll()——从队首删除并返回一个元素
String str1=queue.poll();
System.out.println(str1);
System.out.println(queue);
}
@Test
public void test09() {
/**
* Deque:Queue的子接口
* 从队列的两端分别可以入队(offer)
* 和出队(poll)
* 限制Deque一端出入——“栈” 入栈push 出栈pop
* 遵循先进后出(FILOt)的原则
*/
Deque<String> stack=new LinkedList<String>();
//.push()——将一个对象添加至队首,如果添加成功则返回true
stack.push("a");
stack.push("b");
stack.push("c");
System.out.println(stack);
//.peek()——返回队首(栈顶)元素(不删除)
String str=stack.peek();
System.out.println(str);
System.out.println(stack);
while(stack.size()>0) {
//.pop()——前端出栈(从队首删除并返回一个元素)
str=stack.pop();
System.out.println(str);
System.out.println(stack);
}
}
Map接口
Map接口定义的集合又称查找表,用于存储所谓“Key-Value”映射对。Key可以看成是Value的索引,作为Key的对象在集合中不可以重复。
根据内部数据结构的不同,Map接口有多种实现类,其中常用的有内部为hash表实现的HashMap和内部为排序二叉树实现的TreeMap。
HashMap
@Test
public <K, V> void test10() {
/**
* Map接口:(查找表)
* 存储所谓“Key-Value”映射对
* Key-索引,不可重复
* 常见内部类:内部为hash表实现的HashMap
* 内部为排序二叉树实现的TreeMap
*/
Map<String, Person> persons = new HashMap<String,Person>();
persons.put("one", new Person("one",25,"boy",5000));
persons.put("two", new Person("two",24,"girl",8000));
System.out.println(persons);
System.out.println(persons.get("one"));
System.out.println(persons.containsKey("one"));
}
@Test
public <K, V> void test11() {
/**
* Map遍历(三种方式)
*— 遍历所有的Key
*— 遍历所有的Key - Value对
*— 遍历所有的Value(不常用)
*/
Map<String, Person> persons = new HashMap<String,Person>();
persons.put("one", new Person("one",25,"boy",5000));
persons.put("two", new Person("two",24,"girl",8000));
// System.out.println(persons);
// System.out.println(persons.get("one"));
// System.out.println(persons.containsKey("one"));
//遍历所有Key
//Set<K> keySet()
//将当前Map中所有的key存入一个Set集合后返回
Set<String> keySet=persons.keySet();
System.out.println("遍历所有Key");
for(String key:keySet) {
System.out.println(key);
}
//遍历所有的Key - Value对
//将当前Map中每一组key-value对封装为一个Entry对象
// 并存入一个Set集合后返回
Set<Entry<String, Person>> entrySet=persons.entrySet();
System.out.println("遍历所有的Key - Value对");
for(Entry<String, Person> key_value:entrySet) {
System.out.println(key_value);
}
}
TreeMap
有序的Map:LinkedHashMap
@Test
public <K, V> void test12() {
/**
* 有序的Map — LinkedHashMap
*/
String[] positions= {"A","B","C","D","E","F","G"};
int[] datas= {2,5,7,6,4,3,2};
LinkedHashMap<String, Integer> map =new LinkedHashMap<String,Integer>();
for(int i=0;i<positions.length;i++) {
Integer data =map.get(positions[i]);
int max=data==null?0:data;
max=max>datas[i]?max:datas[i];
map.put(positions[i], max);
}
System.out.println(map);
}
Set接口
Java中使用Set接口描述一个集合(集合不允许有“重复值”,注意重复的概念),集合Set是Collection的子接口,Set不允许其数据元素重复出现,也就是说在Set中每一个数据元素都是唯一的。Set又有HashSet和TreeSet两个子接口。
HashSet(散列集)
@Test
public void test01() {
Set<User> set = new HashSet<User>();
//不会添加重复值
set.add(new User("lucy", 14));
set.add(new User("tom", 20));
set.add(new User("lucy", 14));
set.add(new User("tom", 19));
set.add(new User("jack", 14));
System.out.println(set.size());
System.out.println(set);
}
@Test
public void test02() {
Set<User> set = new HashSet<User>();
User u1 = new User("lucy", 14);
User u2 = new User("tom", 20);
set.add(u1);
set.add(u2);
System.out.println(set.size()); // 2
System.out.println(set);
//会移走内容相同的对象
User u3 = new User("lucy", 14);
set.remove(u3);
System.out.println(set.size()); // 1
System.out.println(set);
u2.setAge(23); // 属性值改变了,hashCode就改变了
set.remove(u2);
System.out.println(set.size());
System.out.println(set);
u2.setAge(20);
set.remove(u2);
System.out.println(set.size());
System.out.println(set);
}
@Test
public void test03() {
Set<User> set = new HashSet<User>();
User u1 = new User("lucy", 14);
User u2 = new User("lucy", 20);
User u3 = new User("lucyy", 21);
set.add(u1);
set.add(u2);
set.add(u3);
System.out.println(set.size()); // 2
System.out.println(set);
u2.setAge(14); //之后u1和u2内容一样,但是HashCode不同
System.out.println(set.size());
System.out.println(set);
//新建Set会重新处理重复值
Set<User> newSet = new HashSet<User>(set);
System.out.println(newSet.size());
System.out.println(newSet);
}
TreeSet(树集)
@Test
public void test04() {
/**
* TreeSet:对象元素进行排序,同样也可以保证元素的唯一
*/
Set<Integer> set = new TreeSet<Integer>();
set.add(13);
set.add(16);
set.add(9);
set.add(10);
set.add(3);
set.add(5);
set.add(13);
System.out.println(set);
}
@Test
public void test05() {
Set<String> set = new TreeSet<String>();
//按照首字符排序,首字符相同则下一字符排序
set.add("lucy");
set.add("marry");
set.add("david");
set.add("tom");
set.add("laozhang");
set.add("Lucy");
System.out.println(set);
}
@Test
public void test06() {
Set<User> set = new TreeSet<User>();
//按照HashCode排序
set.add(new User("lucy", 20));
set.add(new User("tom", 14));
set.add(new User("jarry", 19));
set.add(new User("marry", 21));
System.out.println(set);
}