Java基础(十一)集合框架
一、集合框架
1、集合框架定义
集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:
- 接口:是代表集合的抽象数据类型。接口允许集合独立操纵其代表的细节。在面向对象的语言,接口通常形成一个层次。
- 实现(类):是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构。
- 算法:是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。
除了集合,该框架也定义了几个Map接口和类。Map里存储的是键/值对。尽管Map不是collections,但是它们完全整合在集合中。
二、List 接口
1、ArrayList 的使用
ArrayList 是一个集合容器类。
1、ArrayList 的构造方法
2、 ArrayList 方法
测试ArrayList:
import org.junit.Test; import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator; public class ArrayListTest { /**
* 测试ArrayList
*/
@Test
public void test() {
ArrayList<Object> list = new ArrayList<>(); list.add("test1");
list.add("test2");
list.add("test3");
list.add("test4"); list.add(1, "test5"); //插入 1 是索引
System.out.println(list); //[test1, test5, test2, test3, test4] 打印出值,因为ArrayList覆写了 toString方法
System.out.println("size:" + list.size()); //size:5 //遍历ArrayList 1、普通for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(" list = " + list.get(i));
}
System.out.println("=======");
for (Object o : list) { //2、增强for循环
System.out.println(" list = " + o);
}
System.out.println("=======");
//3.迭代器遍历ArrayList
Iterator<Object> iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(" list = " + iterator.next());
}
System.out.println("=======");
//ListIterator迭代
ListIterator<Object> listIterator = list.listIterator();
while (listIterator.hasNext()) {
System.out.println(" list = " + listIterator.next());
}
System.out.println("=======");
while (listIterator.hasPrevious()) {
//反向打印,顺序相反
System.out.println(" list = " + listIterator.previous());
}
}
}
2、LinkedList 使用
基于链表结构的集合 LinkedList。LinkedList 属于 java.util 包下面,也实现Iterable接口,说明可以使用迭代器遍历;LinkedList 还实现 Deque<E>,Queue<E> 操作。Deque 和 Queue 是 LinkedList 的父接口,那么 LinkedList 也可以看成一种 Deque 或者 Queue;Queue表示一种队列,也是一种数据结构,它的特点是先进先出,因此在队列这个接口里面提供了一些操作队列的方法,同时LinkedList也具有这些方法;Deque(Double ended queues双端队列),支持在两端插入或者移除元素; 那也应该具有操作双端队列的一些方法;LinkedList 是他们的子类,说明都具有他们两者的方法;LinkedList也可以充当队列,双端队列,堆栈多个角色。
1、 LinkedList 构造方法
2、 LinkedList 方法
测试 LinkedList:
import org.junit.Test; import java.util.LinkedList; public class LinkedListTest { /**
* 测试LinkedList
ArrayList : 基于数组,可以重复,有索引,记录添加顺序(有序), 查找比较快;
LinkedList: 基于链表,可以重复,有索引,记录添加顺序(有序),添加删除比较快;多了一些操作头尾的方法,可以充当堆栈,队列;
*/
@Test
public void test(){
LinkedList<Object> linkedList = new LinkedList<>();
linkedList.add("11");
linkedList.add("22");
linkedList.add("33");
linkedList.add("44"); System.out.println(linkedList);
//遍历LinkedList
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.pop());
}
System.out.println(linkedList);
}
}
3、 ArrayList 和 LinkedList 的区别
ArrayList 和 LinkedList 都是线程不安全的。
ArrayList 是 List 接口的一种实现,它是使用数组来实现的,即使用数组方式存储。
LinkedList 是 List 接口的一种实现,它是使用链表来实现的,即使用双向链表实现存储。
ArrayList 遍历和查找元素比较快。LinkedList 遍历和查找元素比较慢。
ArrayList 添加、删除元素比较慢。LinkedList 添加、删除元素比较快。
三、set 接口
1、HashSet
不能添加重复的元素,并且是无序的。
HashSet判断是否相同的规则: ①判断hashcode ②判断equals ,如果两个对象的hashCode值相等,并且equals返回为true 就表示相等(重复)。
import org.junit.Test; import java.util.HashSet; public class HashSetTest {
/**
* 测试HashSet
* 如果两个对象的hashCode值相等,并且equals返回为true 就表示相等(重复).
*/
@Test
public void testHashSet() {
HashSet<Object> hashSet = new HashSet<>();
hashSet.add("11");
hashSet.add("55");
hashSet.add("22");
hashSet.add("33");
hashSet.add("44");
hashSet.add("22"); System.out.println(hashSet); //[11, 55, 22, 33, 44] 和添加顺序不一样 } /**
* 测试HashSet1
* HashSet特点:
* ①不能添加重复元素,(通过调用对象的hashcode和equals);
* ②无序(添加顺序,和打印出来的顺序并不相同);
* <p>
* 区别
* HashSet :通过hashcode和equals判断重复;
* TreeSet : 判断重复
* ①使用元素的自然排序,(Comparable接口,使用其中的compareTo方法,返回0,表示相等,compareTo里面的参数只有一个);
* ②使用比较器Comparator接口,其中的方法compare(Object o1,Object o2)返回0,表示相等
*/
@Test
public void testHashSet1() {
HashSet set = new HashSet();
Student s1 = new Student("悟空", 500);
Student s2 = new Student("悟空", 500);
set.add(s1);
set.add(s2); System.out.println(set); //[Student{name='悟空', age=500}]
}
}
自定义类 Student :
public class Student {
private String name;
private Integer age; public Student(String name, Integer age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} /**
* 假设传入的对象也是student,根据业务对象的字段进行比较
*
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (this.name.equals(student.getName()) && this.age == student.getAge()) {
return true;
} else {
return false;
}
} @Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (age != null ? age.hashCode() : 0);
return result;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
2、TreeSet
TreeSet 和 HashSet 很多方面也是类似的;特点和 HashSet 也是一样的;
TreeSet 的特点:不能添加重复元素,无序的(不记录添加顺序)。
2.1 TreeSet 排序
1、自然排序
自然排序:此接口强行对实现它的每个类的对象进行整体排序,这种排序被称为类的自然排序。
可以让类实现 Comparable 接口,通过 compareTo(Object obj) 方法,如果方法返回 0 表示相等,否则不等。
实现了 Comparable 接口的 student 类:
public class Student implements Comparable<Student> {
private String name;
private Integer age; public Student(String name, Integer age) {
this.name = name;
this.age = age;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Integer getAge() {
return age;
} public void setAge(Integer age) {
this.age = age;
} /**
* 假设传入的对象也是student,根据业务对象的字段进行比较
*
* @param o
* @return
*/
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; if (this.name.equals(student.getName()) && this.age == student.getAge()) {
return true;
} else {
return false;
}
} @Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (age != null ? age.hashCode() : 0);
return result;
} @Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
} /**
* 覆写 compareTo
*
* @param s
* @return
*/
@Override
public int compareTo(Student s) {
if (this.age > s.getAge()) {
return -1;
} else if (this.age < s.getAge()) {
return 1;
} else {
//return this.name.compareTo(s.getName()); 自动比较
return 0;
}
}
}
2、定制排序
如果没有实现 Comparable 接口,需要自定义一个类,实现 Comparator 接口,覆写比较方法;
比较器的实现代码:
import java.util.Comparator; /**
* 定制排序
*/
public class StudentComparator implements Comparator {
@Override
public int compare(Object o1, Object o2) {
Student s1 = (Student)o1;
Student s2 = (Student)o2;
if (s1.getAge() > s2.getAge()){
return 1;
}else if(s1.getAge() < s2.getAge()){
return -1;
}else {
return 0;
}
}
}
3、TreeSet 自然排序和定制排序的区别
一般来说,先写一个比较规则,让它实现 Comparable 接口,作为默认的比较规则,如果不写比较器,则比较使用默认规则,如果觉得默认比较规则不够好,可以自己写个比较器,当通过存在默认比较规则和比较器时,优先选择使用比较器,因为比较器更能满足需求。
测试TreeSet:
import org.junit.Test; import java.util.TreeSet; public class TreeSetTest { /**
* 测试TreeSet
*/
@Test
public void testTreeSet() {
TreeSet<Object> treeSet = new TreeSet<>();
treeSet.add("11");
treeSet.add("33");
treeSet.add("22");
treeSet.add("44"); System.out.println(treeSet); //[11, 22, 33, 44]
} @Test
public void testTreeSet2() {
TreeSet<Object> treeSet = new TreeSet<>();
Student student1 = new Student("张", 8);
Student student2 = new Student("张", 10);
Student student3 = new Student("张", 7);
Student student5 = new Student("张", 9);
Student student4 = new Student("张", 11);
treeSet.add(student3);
treeSet.add(student4);
treeSet.add(student2);
treeSet.add(student1);
treeSet.add(student5); System.out.println(treeSet);
} /**
* 测试比较器TreeSet
*/
@Test
public void testTreeSet3() {
TreeSet<Object> treeSet = new TreeSet<>(new StudentComparator()); //优先选择比较器,如果选默认的,就不能满足要求呢;
Student student1 = new Student("张", 8);
Student student2 = new Student("张", 10);
Student student3 = new Student("张", 7);
Student student5 = new Student("张", 9);
Student student4 = new Student("张", 11);
treeSet.add(student3);
treeSet.add(student4);
treeSet.add(student2);
treeSet.add(student1);
treeSet.add(student5); System.out.println(treeSet);
}
}
3、HashSet 和 TreeSet 总结
HashSet特点:不重复,无序(通过 hashCode 方法和equals 方法,判断重复)。
TreeSet 特点:不重复,无序(添加顺序与打印顺序不一样),但是打印顺序按照一定规则排序;排序有自然排序和定制排序。
四、Map 接口
Map 简单理解成映射;
Map:将键映射到值的对象。一个映射不能包含重复的键;每个键最多只能包含一个值。
1、hashMap
1、hashMap 的构造方法
2、hashMap 的方法
3、测试 hashMap
具体测试代码:
import org.junit.Test; import java.util.*; public class HashMapTest {
/**
* Map是什么?
* 简单理解成是映射;
* 判断重复的标准和HashSet一致,通过键的hashCode和equals;
* 测试hashMap
*/
@Test
public void testHashMap() {
Map<Object, Object> hashMap = new HashMap<>();
hashMap.put("key1", "test1"); //存值
hashMap.put("key2", "test2");
hashMap.put("key2", "test3"); System.out.println(hashMap); //{key1=test1, key2=test3} 一个键只能有一个值,后面的值覆盖了前面的值
System.out.println(hashMap.get("key1")); //取值 test1
System.out.println(hashMap.containsKey("key")); //判断是否包含这个键 false
System.out.println(hashMap.containsValue("test")); //判断是否包含着个值 false Map<Object, Object> hashMap1 = new HashMap<>();
hashMap1.put("key3", "test3");
hashMap1.put("key4", "test4");
System.out.println(hashMap1); //{key3=test3, key4=test4} hashMap.putAll(hashMap1); //将hashMap1的所有映射关系复制到hashMap
System.out.println(hashMap); //{key1=test1, key2=test3, key3=test3, key4=test4}
System.out.println(hashMap.size()); // 4 //遍历方法一:获取所有映射
Set<Map.Entry<Object, Object>> entrySet = hashMap.entrySet();
for (Map.Entry<Object, Object> entry : entrySet) {
System.out.println("entry ==[" + entry);
} //遍历方法二:获取所有键的集合
Set<Object> keySet = hashMap.keySet();
for (Object o1 : keySet) {
//通过键返回值
System.out.println("key = [" + o1 + "] ---> value = " + "[" + hashMap.get(o1) + "]" ); }
}
}
2、Map小结
HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。该类实现了Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。
Map接口
HashMap 判断重复的标准和HashSet一致,通过键的 hashCode 和 equals;
TreeMap 判断重复的标准和TreeSet一致,1:通过自然排序(Comparable 接口),2:定制排序(Compartor 比较器)。
五、集合算法 Collections
完全由在 collection 上进行操作或返回 collection 的静态方法组成。它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。例如:搜索和排序。
1、Collections 的方法
上面是 Collections 类的一些常用方法,具体所有方法,可以自己查看API文档。
测试 Collections 的一些常用方法:
import org.junit.Test; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; /**
* 测试collections
*/
public class CollectionsTest {
@Test
public void testCollections(){
List list = new ArrayList(); //addAll 将所有指定元素添加到指定 collection 中。
Collections.addAll(list, 123, 456, false, null, "2333");
System.out.println(list); //[123, 456, false, null, 2333] List list2 = new ArrayList();
Collections.addAll(list2, 1, 1, 1, 1, 1, 2222222, 333333, "444444");
Collections.copy(list2, list); //复制
System.out.println(list2); //[123, 456, false, null, 2333, 2222222, 333333, 444444] List list3 = new ArrayList();
for (int i =0; i<10; i++){
list3.add(i);
}
System.out.println("list3 "+ list3); //list3 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Collections.shuffle(list3); //乱序
System.out.println("list3 " + list3); //list3 [4, 1, 9, 7, 2, 6, 3, 8, 0, 5] System.out.println(Collections.max(list3)); //数组中最大值 9
Collections.sort(list3); //排序
System.out.println(list3); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Collections.fill(list3, 2); // fill 使用指定元素替换指定列表中的所有元素。
System.out.println(list3); //[2, 2, 2, 2, 2, 2, 2, 2, 2, 2]
}
}
六、集合框架总结
1、List,Set,还有它们下面的子类都可以看成容器,都实现了超级的接口Collection;(查看API文档)
List,Set 和Collection之间的关系是继承关系,因为接口与接口之后,只能是继承的关系。
2、ArrayList,LinkedList,HashSet,TreeSet 四个容器类的特点:
ArrayList:实现 List 接口,基于数组,可以重复,有索引,记录添加顺序,即有序,查找比较快。
LinkedList:实现 List 接口,基于链表,可以重复,有索引,记录添加顺序,即有序,添加删除比较快,多了一些操作头尾的方法,可以充当堆栈,队列。
HashSet:实现 Set 接口,不重复,无序(通过 hashCode 方法和equals 方法,判断重复)。
TreeSet:实现 Set 接口,不重复,无序(添加顺序与打印顺序不一样),但是打印顺序按照一定规则排序;排序有自然排序和定制排序。①使用元素的自然排序,(Comparable 接口,使用其中的 compareTo 方法,返回0,表示相等,compareTo 里面的参数只有一个);②使用比较器 Comparator 接口,其中的方法 compare(Object o1,Object o2)返回0,表示相等。
3、Comparable 和 Comparator 的区别:
Comparable 是一个比较的标准,里面有比较的方法,对象要具有比较的标准,就必须实现 Comparable 接口;类实现这个接口,就有比较的方法;把元素放到 TreeSet 里面去,就会自动的调用 CompareTo 方法;但是这个 Comparable 并不是专为 TreeSet 设计的;只是说,TreeSet 顺便利用而已;就像 HashCode 和 equals 也一样,不是专门为 HashSet 设计一样;只是你顺便利用而已。
Compartor 是个比较器,也不是专门为TreeSet设计. 就是一个第三方的比较器接口;如果对象没有比较性,自己就可以按照比较器的标准,设计一个比较器,创建一个类,实现这个接口,覆写方法。
4、HashMap,TreeMap的特点:
HashMap:实现 Map 接口,是一个散列表,它存储的内容是键值对(key-value)映射。根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为null,不支持线程同步。判断重复的标准和 HashSet 一致,通过键的 hashCode 和 equals。
TreeMap:实现 Map 接口,判断重复的标准和TreeSet一致,1:通过自然排序(Comparable 接口),2:定制排序(Compartor 比较器)。
Java基础(十一)集合框架的更多相关文章
- Java基础--说集合框架
版权所有,转载注明出处. 1,Java中,集合是什么?为什么会出现? 根据数学的定义,集合是一个元素或多个元素的构成,即集合一个装有元素的容器. Java中已经有数组这一装有元素的容器,为什么还要新建 ...
- 黑马程序员——【Java基础】——集合框架
---------- android培训.java培训.期待与您交流! ---------- 一.集合框架概述 (一)集合框架中集合类关系简化图 (二)为什么出现集合类? 面向对象语言对事物的体现都是 ...
- java基础37 集合框架工具类Collections和数组操作工具类Arrays
一.集合框架工具类:Collections 1.1.Collections类的特点 该工具类中所有的方法都是静态的 1.2.Collections类的常用方法 binarySearch(List< ...
- Thinking in java基础之集合框架(转载)
集合简介(容器)把具有相同性质的一类东西,汇聚成一个整体,就可以称为集合,例如这里有20个苹果,我们把每一个苹果当成一个东西(一个对象),然后我们借用袋子把这20个苹果装起来,而这个袋子就是集合(也叫 ...
- Java基础之集合框架(Collection接口和List接口)
首先我们说说集合有什么作用. 一.集合的作用 1.在类的内部,对数据进行组织: 2.简单而快速的搜索大数量的条目: 3.有的集合接口,提供一系列排列有序的元素,并且可以在序列中间快速的插入或者删除有关 ...
- java基础之集合框架
6.集合框架: (1)为什么出现集合类? 面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储. 集合就是存储对象最常用的一种方式. (2)数组和集合都是容器,两者有何不同 ...
- Java基础之集合框架——使用堆栈Stack<>对象模拟发牌(TryDeal)
控制台程序. public enum Rank { TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, A ...
- Java基础之集合框架——使用集合Vector<>挑选演员(TryVector)
控制台程序. public class Person implements Comparable<Person> { // Constructor public Person(String ...
- Java基础之集合框架类及泛型简介
Collection接口 Collection 通用的常见方法 add()添加一个元素,可以指定脚标 addAll()将一个collection放入 clear()清除 remove()删除元素,返回 ...
- java基础之集合框架--使用ArrayList类动态 存储数据
一.ArrayList是List接口下的一个实现类,实现了长度可变的.连续的数组:拥有数组的特性. 遵循了LIst的规则:不唯一的.有序的. 如果没有增加泛型的话,集合中可以添加任何类型的数据. 使用 ...
随机推荐
- [ActionScript 3.0] AS3 绘制任意三角形任意顶点到对边的高
注:顶点坐标可以点击 package { import flash.display.Shape; import flash.display.Sprite; import flash.events.Mo ...
- 性能测试—认识JMeter(一)
性能测试—认识JMeter(一) <零成本web性能测试>第二章 JMeter基础知识总结和自己的理解 一.JMeter百度词条概念 Apache JMeter是Apache组织开发的基 ...
- JQuery easyui里面的自动完成autocomplete插件
默认功能 当您在输入域中输入时,自动完成(Autocomplete)部件提供相应的建议.在本实例中,提供了编程语言的建议选项,您可以输入 "ja" 尝试一下,可以得到 Java 或 ...
- Angular 2 中的 ViewChild 和 ViewChildren
https://segmentfault.com/a/1190000008695459 ViewChild ViewChild 是属性装饰器,用来从模板视图中获取匹配的元素.视图查询在 ngAfter ...
- 牛客网NOIP赛前集训营-提高组(第四场)B区间
牛客网NOIP赛前集训营-提高组(第四场)B区间 题目描述 给出一个序列$ a_1 \dots a_n$. 定义一个区间 \([l,r]\) 是好的,当且仅当这个区间中存在一个 \(i\),使得 ...
- 解决mysql最大允许传输包不足的问题
一.报错提示内容和原因 在执行“数据传输”或者“运行SQL文件”时报错误:Got a packet bigger than 'max_allowed_packet' bytes With,表明当前所传 ...
- 2016级算法第一次练习赛-E.AlvinZH的儿时回忆——蛙声一片
864 AlvinZH的儿时回忆----蛙声一片 题目链接:https://buaacoding.cn/problem/865/index 思路 中等题.难点在于理解题意!仔细读题才能弄懂题目规则.整 ...
- 机器学习中的范数规则化之 L0、L1与L2范数、核范数与规则项参数选择
装载自:https://blog.csdn.net/u012467880/article/details/52852242 今天我们聊聊机器学习中出现的非常频繁的问题:过拟合与规则化.我们先简单的来理 ...
- 搭建spring boot项目
1.建立maven项目 点击finish,完成创建maven项目 在pom.xml文件中添加如下代码: <parent> <groupId>org.springframewor ...
- OAuth2 .net MVC实现获取token
OAuth2 的原理这里不多讲,可以看:https://www.cnblogs.com/icebutterfly/p/8066548.html 直奔主题:这里要实现的功能为,统计微软的Owin程序集实 ...