Java学习笔记-基础语法Ⅶ-集合
集合
集合类特点:提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
这里需要回顾一下,因为数组和字符串一旦创建,就不可改变,需要区分一下
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("Hello");
c.add("World");
c.add("java");
System.out.println(c);
// 集合常用方法
// 长度size
System.out.println(c.size());
// 添加add,上文已使用
// 移除remove
c.remove("hello");
boolean hello = c.remove("Hello");
System.out.println(hello);
System.out.println(c);
// 包含
boolean world = c.contains("World");
System.out.println(world);
// 判空
boolean empty = c.isEmpty();
System.out.println(empty);
// 清空
c.clear();
System.out.println(c);
}
}
[Hello, World, java]
3
true
[World, java]
true
false
[]
用完之后发现这种多态方式使用Collection
并不好用,不如直接使用ArrayList
,而且ArrayList
常用的5个方法更好用:add
、get
、remove
、set
、size
如果想对Collection
进行遍历,需要使用迭代器
Iterator是集合的专用遍历方式,Collection可以用,ArrayList之类的也可以用
常用3个方法:next
、hasNext
、remove
// Iterator的使用
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class IteratorDemo {
public static void main(String[] args) {
Collection<String> c = new ArrayList<>();
c.add("Hello");
c.add("World");
c.add("Java");
c.add("100");
// c.add("101");
Iterator<String> iterator = c.iterator();
while(iterator.hasNext()) {
String s = iterator.next();
//
if(s.equals("100")){
iterator.remove();
System.out.println(s);
// iterator.add("Java");
}
// System.out.println(iterator.next());
}
System.out.println(c);
}
}
要注意,Iterator没有add方法,强行使用会导致并发修改异常
List集合特点:
有序集合,可重复
并发修改异常:迭代器遍历过程中,通过集合对象修改了集合中元素长度,造成迭代器获取元素中判断预期修改值和实际修改值不一致。解决:使用for循环
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
public class ListIteratorDemo {
public static void main(String[] args) {
List<String> str = new ArrayList<>();
str.add("Hello");
str.add("World");
str.add("Java");
ListIterator<String> listIterator = str.listIterator();
/*
while(listIterator.hasPrevious()){
// System.out.println(listIterator.previousIndex());
// System.out.println(listIterator.previous());
String previous = listIterator.previous();
System.out.println(previous);
}
*/
while(listIterator.hasNext()){
String next = listIterator.next();
if(next.equals("Java")){
listIterator.add("JavaEE");
}
}
while(listIterator.hasPrevious()){
System.out.println(listIterator.previousIndex());
// System.out.println(listIterator.previous());
String previous = listIterator.previous();
System.out.println(previous);
}
}
}
3
JavaEE
2
Java
1
World
0
Hello
ListIterator可以使用add方法,并且可以查看迭代器的索引
增强for循环
- 目的:简化数组和Collection集合的遍历
- 底层:Iterator,也就是不能使用add方法
- 格式:
for(元素数据类型变量名:数组或者Collection集合){//使用变量}
public class ForDemo {
public static void main(String[] args) {
int [] arr = {1,2,3,4,5};
for(int i:arr){
System.out.println(i);
}
}
}
栈
数据进入栈模型的过程称为:压/进栈,反之为弹/出栈
栈是先进后出的模型
队列
入队/出队
队列是先进先出的模型
数组
查询数据通过索引定位,查询效率高
删除和添加效率低
链表
增删快,查询慢
ArrayList
ArrayList是List接口的可调整大小的数组实现,数组特点是查询快,增删慢
LinkList
LinkList是双链表实现List和Deque接口,查询慢,增删快
常用方法:addFirst
、addLast
、getFirst
、getLast
、removeFirst
、removeLast
居然还可以在指定位置插入元素
add(int index, E element)
在列表中指定的位置上插入指定的元素。
Set
不包含重复元素的集合,且没有带索引的方法,不能使用普通for循环遍历
HashSet
对集合的迭代顺序不作任何保证
hashCode方法
,默认情况下,不同对象的hash值不同
// Student类
public class Student {
private int age;
public Student() {
}
public Student(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
// 测试类
import java.util.HashSet;
import java.util.Set;
public class My_Hash {
public static void main(String[] args) {
Set<String> s1 = new HashSet<>();
s1.add("java");
Set<String> s2 = new HashSet<>();
s2.add("java");
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println("--------");
Student s3 = new Student(18);
Student s4 = new Student(18);
System.out.println(s3.hashCode());
System.out.println(s4.hashCode());
}
}
3254818
3254818
--------
1324119927
990368553
但是可以在原来的类中重写hashCode方法,这样就可以返回指定hash值
如在上述学生类
中重写hashCode方法如下
@Override
public int hashCode(){
return age;
// return 0;
}
这样返回的hash值就都为自己创建对象的age值
HashSet
- 底层数据结构是哈希表
- 对集合的迭代顺序不作任何保证
- 没有索引方法,所以不能使用普通for循环遍历
- 不包含重复元素的集合
哈希表
LinkedHashSet
有哈希表和链表实现的Set接口,具有可预测的迭代次序
由链表保证元素有序,也就是说元素的存储和取出的顺序是一致的,这点和HashSet不同
由哈希表保证元素唯一性
TreeSet
元素按照一定的规则进行排序,无参构造方法按照自然顺序排序,带参构造方法按照指定规则排序
要进行自然排序,需Comparable
或者Comparator
- Comparable:此接口对实现它的每个类的对象进行了总排序。这个顺序被称为类的空自然排序,和类的 compareTo方法称为空自然比较方法。
- 一个比较函数,这对一些对象的集合,对总序。比较器可以通过某种方法(如 Collections.sort或 Arrays.sort)允许在排序顺序的精确控制。比较器也可以用来控制特定的数据结构顺序(如 sorted sets或 sorted maps),或提供的对象不集合排序有 natural ordering。
首先看一下TreeSet对Integer进行自然排序
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
TreeSet<Integer> ts = new TreeSet<>();
ts.add(5);
ts.add(10);
ts.add(1);
ts.add(7);
ts.add(20);
for(int i:ts){
System.out.println(i);
}
}
}
1
5
7
10
20
这是因为Integer实现了Comparable接口,不能想当然认为其他类也实现了
public final class Integer
extends Number
implements Comparable<Integer>
接下来对一般类实现自然排序
// 学生类
public class Student implements Comparable{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
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 String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Object o) {
// return 0;
return 1;
}
}
// 测试类
public class Demo {
public static void main(String[] args) {
TreeSet<Student> s = new TreeSet<>();
Student s1 = new Student("linqingxia",18);
Student s2 = new Student("zhangmanyu",48);
Student s3 = new Student("wangzuxian",38);
Student s4 = new Student("zhangmin",28);
s.add(s1);
s.add(s2);
s.add(s3);
s.add(s4);
for(Student st:s){
System.out.println(st);
}
}
}
继承Comparale,再重写CompareTo方法
int compareTo(T o)
``` 将此对象与指定的对象进行比较,以。返回一个负整数、零或一个正整数,因为这个对象小于、等于或大于指定的对象。
如果想要按照年龄进行排序,则需要把CompareTo进行如下改写
public class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
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 String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student s) {
// return 0;
int num1 = this.age - s.age;
int num2 = num1 == 0?this.name.compareTo(s.name):num1;
return num2;
}
}
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
TreeSet<Student> s = new TreeSet<>();
Student s1 = new Student("linqingxia",18);
Student s2 = new Student("zhangmanyu",48);
Student s3 = new Student("wangzuxian",38);
Student s4 = new Student("zhangmin",28);
Student s5 = new Student("qiushuzhen",28);
s.add(s1);
s.add(s2);
s.add(s3);
s.add(s4);
s.add(s5);
for(Student st:s){
System.out.println(st);
}
}
}
TreeSet结合存储自定义对象时,带参构造方法使用比较器排序对元素进行排序
同样,也可以让类继承Compareble,然后重写CompareTo来实现
上例中implements Compareble<Student>
是因为测试类中使用的是泛型
题目:用TreeSet集合存储多个学生信息(姓名,语文成绩,数学成绩),并遍历该集合,要求:按照总分从高到底出现
为了简化,就不写get和set方法
// 学生类
public class Student implements Comparable<Student>{
private String name;
private int mathScore;
private int chinesScore;
private int englishScore;
public int setTotalScore(){
return mathScore+chinesScore+englishScore;
}
public Student(String name, int mathScore, int chinesScore, int englishScore) {
this.name = name;
this.mathScore = mathScore;
this.chinesScore = chinesScore;
this.englishScore = englishScore;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", mathScore=" + mathScore +
", chinesScore=" + chinesScore +
", englishScore=" + englishScore +
", totalScore=" + setTotalScore() +
'}';
}
@Override
public int compareTo(Student student) {
int num1 = student.setTotalScore() - this.setTotalScore();
int num2 = num1 == 0?student.mathScore-this.mathScore:num1;
int num3 = num2 == 0?student.chinesScore-this.chinesScore:num2;
int num4 = num3 == 0?student.englishScore-this.englishScore:num3;
int num5 = num4 == 0?student.name.compareTo(this.name):num4;
return num5;
}
}
// 测试类
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
TreeSet<Student> ts = new TreeSet<>();
Student s1 = new Student("赵",99,98,99);
Student s2 = new Student("钱",98,99,100);
Student s3 = new Student("孙",99,98,100);
Student s4 = new Student("李",100,99,98);
ts.add(s1);
ts.add(s2);
ts.add(s3);
ts.add(s4);
for(Student s:ts){
System.out.println(s);
}
}
}
包装类如Integer和String是实现了Compareble的,所以可以直接使用CompareTo方法
Java学习笔记-基础语法Ⅶ-集合的更多相关文章
- Java学习笔记-基础语法Ⅳ
多态:同一个对象,在不同时刻表现出来的不同形态 例如: 猫 cat = new 猫(); 动物 animal = new 猫(); 这里的猫在不同时刻表现出来不同的形态,这就是多态 多态的前提和体现: ...
- Java学习笔记-基础语法Ⅷ-泛型、Map
泛型 泛型本质上是参数化类型,也就是说所操作的数据类型被指定为一个参数,即将类型由原来的具体的类型参数化,然后在使用/调用时传入具体的类型,这种参数类型可以用在类.方法和接口中,分别为泛型类.泛型方法 ...
- Java学习笔记-基础语法Ⅴ
学习一些Java常用的API Math:包含执行基本数字运算的方法 如果没有构造方法,一般类的成员都是静态的,通过类名可以直接调用 Java中有两种random函数,Math.Random()函数能够 ...
- Java学习笔记-基础语法
Java基础包含关键字,标识符,注释,常量和变量,运算符 关键字 关键字的定义和特点 定义:被Java语言赋予了特殊含义的单词 特点:关键字中所有字母都为小写 Java的关键字 用于定义数据类型的关键 ...
- Java学习笔记-基础语法Ⅹ-进程线程
学习快一个月了,现在学到了黑马Java教程的300集 打印流的特点: 只负责输出数据,不负责读取数据 有自己的特有方法 字节打印流:PrintStream,使用指定的文件名创建新的打印流 import ...
- Java学习笔记-基础语法Ⅱ
成员变量:类中方法外的变量 局部变量:方法中的变量 注意,成员变量有默认初始值,而局部变量需要赋初始值 Java中虽然没有明确规定类必须首字母大写,但为了规范最好大写(因为自己刚刚写的时候就没看清写错 ...
- JAVA 学习笔记 - 基础语法 2
---恢复内容开始--- 1.数组的申明和应用 数据类型 数组名称[] = null; //在堆栈中申明变量名称 数组名称 = new 数据类型[10]; // ...
- JAVA 学习笔记 - 基础语法1
1. 类的定义 public class 与 class的区别 一个java文件只有一个public class, 而且类名必须与文件名一致. 一个java文件可以有多个class定义,javac ...
- Java学习笔记-基础语法ⅩⅠ-UDP、TCP
网络编程 三要素:IP地址.端口.协议 IP地址:使用ipconfig查看,如果装了VM的话,会有VMnet1.VMnet8和WLAN,net1不能从虚拟机到主机,net8不能从主机到虚拟机,net0 ...
随机推荐
- 用maven建立一个工程4
在命令行里面输入cd C:\Users\admin\Documents\hello 然后按回车 再输入这行代码 mvn archetype:generate -DgroupId=com.liyongz ...
- nginx优化的一些建议
1.1隐藏Nginx header里版本号信息 1.查看版本号 curl -I 127.0.0.1 HTTP/1.1 200 OK Server: nginx/1.6.2 Date: Sat, 14 ...
- 攻防世界杂项MISCall
MISCall 下载下来是一个附件但是不清楚他是个什么东西我先拉入kali看看 发现是一个tar包不过这个包我们需要使用以下的指令来解压 tar -xjvf d02f31b893164d56b7a8e ...
- python模块 | 随机数模块—random模块
python随机数模块 random - 生成伪随机数,该模块实现了各种分布的伪随机数生成器. 对于整数,从范围中有统一的选择. 对于序列,存在随机元素的统一选择.用于生成列表的随机排列的函数.以及用 ...
- React+Webpack+ES6 兼容低版本浏览器(IE9)解决方案
虽然过了兼容IE6的噩梦时代,IE依旧阴魂不散,因为你可能还要兼容IE9.在ES6已经普及的今天,用ES6写react已经成了标配.但是babel编译的js语法,由于某些不规范的写法,可能在IE9下不 ...
- javaweb图书管理系统之账号密码验证登录
验证账号与密码是否正确功能 一.注册功能 首先,在验证账号与密码是否正确的前提下的,需要先注册一个账号,如果没有账号,就会进不去,也无法验证. 其实,注册功能就是一个添加的功能,仿照我的第一篇文章,往 ...
- 字符串反转&说反话
题目描述 写出一个程序,接受一个字符串,然后输出该字符串反转后的字符串.(字符串长度不超过1000) 输入描述: 输入N个字符 输出描述: 输出该字符串反转后的字符串 示例1 输入 abcd 输出 d ...
- EMS查看邮箱容量限制的方法
以Exchange管理员身份打开EMS控制台.在PowerShell命令行提示符下,输入以下命令. Get-MailboxDatabase | FL name,IssueWarningQuota,Pr ...
- Java实现单链表的反转
思路1:初始化一个新的头节点reverseHead,然后遍历旧链表,利用头插法向reverseHead进行插入 思路2: 1.反转相当于数据的更换(1和n,2和n-1,3和n-2)n为链表的长度 2. ...
- Linux下安装Typora
系统:Ubuntu16.0 下载链接:https://www.typora.io/#linux 参考链接:https://www.cnblogs.com/wenkangzero/p/13202415. ...