java集合
list 实现
1.ArrayList
(1)采用动态数组对象实现,默认构造方法创建了一个新数组。
(2)第一次添加元素,默认初始容量为10,。之后扩充时,添加现在容量的1.5倍。
(3) jdk1.2之后引入。是线程不安全的,只适合在单线程操作,效率较高。
(4)为了防止多次动态调用扩充算法,建议加上初始值。
(5)适合查询,插入删除慢。
2.vector
(1)采用动态数组对象实现,默认构造方法创建了一个容量为10的新数组。
(2)扩充算法,当增量为0时,扩充为原一倍的容量,当增量大于0时扩充为原来容量加增量
(3)加了synchronize关键字,线程安全,且适合多线程,插入删除操作慢,效率较低。
(4)为了防止多次动态调用扩充算法,建议加上初始值。
linkdlist
(1)实现原理,采用双向链表是实现。
(2)插入删除快,性能高.
Set实现
1.hashset
(1)实现原理,基于哈希表(hashmap)实现(数组+链表的底层实现)。
(2)不允许重复,可以有多个null元素。
(3)存储的顺序是可变的
(4)当存入元素的哈希码(hashcode)相同时,会调用==或equals进行确认,结果为true,拒绝后者存入,所以set不能存在相同的元素 。如果有判断两个对象是否是相同的对象时要重写hascode方法和equals方法。
(5)哈希表是如何存储对象的,先计算对象的hashcode值,再对数组的长度求余数,来决定对象要求存储在数组的哪个位置。
2.treeset
treeset是有序且无重复的,基于二叉树实现。在使用treeset的时候对象需要实现对象比较器接口并且对象要重写compare指定对比类的属性。
TreeSet<Dog> treeSet = new TreeSet<>(new Comparator<Dog>() {
@Override
public int compare(Dog o1, Dog o2) {
return o1.age>o2.age;
}
});
3.linkedhasset
无序的,按照对象set的方法进行对象元素的插入,对象的排序也是按照元素的插入顺序进行迭代。
集合的选择
- 如果要保证顺序,也要进行排序,选择treeset。
- 如不要排序,不要保证顺序,选择hasset。
- 要顺序,不要排序,选择linkdehasset
Map家族
hashMap
1.以键值对的形式进行存储,键是唯一的,值可以有多个,为一对多的关系。
2.运行效率快,线程不安全。
3.底层存储结构为链表表+数组实现。
4.hashMap的数组初始大小为16,填充因子为0.75,也就是数组到了12个的时候会自动扩容,扩容的大小为初始容量大小的两倍。
5.hashMap每个数组的对应链表起始大小为8,如果大于会把链表的数据结构变为红黑树。
集合简单案例1
需求:
创建实体类Person,用户输入存入集合中,使用迭代器遍历输出集合,将输入的重复对象去除。
实体类:
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
return super.hashCode();
}
//需要去重,需要重写equals方法判断元素是否一样
@Override
public boolean equals(Object obj) {
if (obj==null)
return false;
if (!(obj instanceof Person))
return false;
Person p = (Person) obj;
if (p.name.equals(this.name)&&p.age==this.age){
return true;
}
return false;
}
@Override
public String toString() {
String s = "姓名:%s,年龄:%d\n";
String str = s.format(s, this.name,this.age);
return str;
//"姓名:"+this.name+"年龄:"+this.age+"\t";
}
测试类:
public class PersonList {
public static ArrayList<Person> personList = new ArrayList<>();
public static void main(String[] args) {
addPerson();
}
static void addPerson(){
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 5; i++) {
Person person = new Person();
System.out.println("请输入需要创建person的名字:");
String inputUsername = scanner.next();
System.out.println("请输入需要创建person的年龄:");
int inputAge = scanner.nextInt();
person.setName(inputUsername);
person.setAge(inputAge);
personList.add(person);
}
//创建迭代器
System.out.println("person集合元素为:");
Iterator iterator = personList.iterator();
while (iterator.hasNext()){
System.out.print(iterator.next());
}
dislodgeDuplication(personList);
}
//去除重复对象之后的person对象为
static void dislodgeDuplication(ArrayList<Person> personList){
//创建新集合
ArrayList<Person> newPersonList = new ArrayList<>();
for (Person person : personList) {
if (!(newPersonList.contains(person))){
newPersonList.add(person);
}
}
System.out.println();
//遍历新集合
System.out.println("去除重复person后的集合元素为:");
for (Person person : newPersonList) {
System.out.print(person);
}
}
}
集合简单案例2
需求:
新建Studen类,将学生信息存入集合中,对集合中的元素排序,成绩一样的按学号升序排列。
统计集合中的合格率(>60),及优秀率(>80)
实体类:
public class Student implements Comparable<Student>{
private int studentNumber;
private String studentName;
private int studentScore;
public Student() {
}
public Student(int studentNumber, String studentName, int studentScore) {
this.studentNumber = studentNumber;
this.studentName = studentName;
this.studentScore = studentScore;
}
public int getStudentNumber() {
return studentNumber;
}
public void setStudentNumber(int studentNumber) {
this.studentNumber = studentNumber;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public int getStudentScore() {
return studentScore;
}
public void setStudentScore(int studentScore) {
this.studentScore = studentScore;
}
@Override
public String toString() {
return
"学号:" + studentNumber +
"\t姓名:" + studentName +
"\t成绩:" + studentScore+"\n";
}
//先按成绩排序,再按学号升序排列,重写compareTo方法,比较大小
@Override
public int compareTo(Student o1) {
if (this.studentScore>o1.studentScore)
return 1;
if (this.studentScore==o1.studentScore){
if (this.studentNumber>o1.getStudentNumber()){
return 1;
}
}
return -1;
}
测试类:
static TreeSet<Student> studentTreeSet = new TreeSet<>();
static ArrayList<Student> studentArrayList = new ArrayList<>();
public static void main(String[] args) {
addStudentInfo();
statisticQualified(studentArrayList);
}
static void addStudentInfo() {
studentArrayList.add(new Student(3, "小明", 88));
studentArrayList.add(new Student(4, "小红", 94));
studentArrayList.add(new Student(5, "小强", 73));
studentArrayList.add(new Student(6, "小凯", 88));
studentArrayList.add(new Student(7, "小丽", 70));
studentArrayList.add(new Student(8, "小雪", 73));
System.out.println("排序前学生集合:");
for (Student student : studentArrayList) {
System.out.print(student);
}
//自动排序需要在实体类中实现Comparable接口,重写compareTo方法
studentTreeSet.addAll(studentArrayList);
studentSortByScore(studentTreeSet);
}
//排序
static void studentSortByScore(TreeSet<Student> studentTreeSet) {
System.out.println("排序后学生集合:");
for (Student student : studentTreeSet) {
System.out.print(student);
}
}
//统计合格率及优秀率
static void statisticQualified(ArrayList<Student> studentList) {
//存放合格学生
ArrayList<Student> qualifiedStudent = new ArrayList<>();
//存放优秀学生
ArrayList<Student> excellentStudent = new ArrayList<>();
for (Student student : studentList) {
if (student.getStudentScore() >= 80) {
excellentStudent.add(student);
}if (student.getStudentScore()>=60){
qualifiedStudent.add(student);
}
}
//double qualifiedRatio = qualifiedStudent.size()/studentList.size();
//double excellentRatio = excellentStudent.size()/studentList.size();
//int i = Integer.parseInt(new DecimalFormat("0").format(excellentRatio * 100) + "%");
//System.out.println(i);
//将double类型转换为%
DecimalFormat decimalFormat = new DecimalFormat("0.00%");
String qualifiedRatio = decimalFormat.format((double) qualifiedStudent.size()/(double)studentList.size());
String excellentRatio = decimalFormat.format((double) excellentStudent.size()/(double)studentList.size());
System.out.println("合格率为:"+qualifiedRatio+",优秀率为:"+excellentRatio);
}