集合-3
来源:互联网 发布:apache下载安装 win7 编辑:程序博客网 时间:2024/06/03 19:13
集合-3
1.HashSet存储字符串并遍历
* A:Set集合概述及特点
*通过API查看即可
*Set集合,无索引,不可以重复,无序(存取不一致)
* B:案例演示
*HashSet存储字符串并遍历
HashSet<String>hs = new HashSet<>();
booleanb1 = hs.add("a");
booleanb2 = hs.add("a");
System.out.println(b1);
System.out.println(b2); //当向set集合中存储重复元素的时候,返回false
for(Strings : hs) {
System.out.println(s); //输出是无序的,不是存入的顺序!!
}
2.HashSet存储自定义对象保证元素唯一性图解及代码优化
* 代码优化
*为了减少比较,优化hashCode()代码写法。
*最终版就是自动生成即可。
3.HashSet如何保证元素唯一性的原理
* 1.HashSet原理
*我们使用Set集合都是需要去掉重复元素的, 如果在存储的时候逐个equals()比较, 效率较低,哈希算法提高了去重复的效率, 降低了使用equals()方法的次数
*当HashSet调用add()方法存储对象的时候, 先调用对象的hashCode()方法得到一个哈希值, 然后在集合中查找是否有哈希值相同的对象
*如果没有哈希值相同的对象就直接存入集合
*如果有哈希值相同的对象, 就和哈希值相同的对象逐个进行equals()比较,比较结果为false就存入, true则不存,只有两个对象的hashcode值一样,它才会去调用equals方法作比较
* 2.将自定义类的对象存入HashSet去重复
*类中必须重写hashCode()和equals()方法!!!!!
*hashCode(): 属性相同的对象返回值必须相同, 属性不同的返回值尽量不同(提高效率)
*equals(): 属性相同返回true, 属性不同返回false,返回false的时候存储
* A:案例演示
*HashSet存储自定义对象保证元素唯一性
HashSet<Person>hs = new HashSet<>();
hs.add(newPerson("张三", 23));
hs.add(newPerson("张三", 23)); @@当你添加对象的时候会自动调用hashcode方法,当hashcode值一样的时候它就会去掉调用equals方法
hs.add(newPerson("李四", 23));
hs.add(newPerson("赵六", 23));
4.LinkedHashSet的概述和使用
* LinkedHashSet的特点
*可以保证怎么存就怎么取
* 底层是链表实现的,是set集合中唯一一个能保证怎么存就怎么取的集合对象
*因为是HashSet的子类,所以也是保证元素唯一的,与HashSet的原理一样
LinkedHashSet<String>lhs = new LinkedHashSet<>();
lhs.add("a");
lhs.add("b");
lhs.add("b");
lhs.add("c");
System.out.println(lhs); //输出[a,b,c,]
5.编写一个程序,获取10个1至20的随机数,要求随机数不能重复。并把最终的随机数输出到控制台。
* 分析:
* 1,有Random类创建随机数对象
* 2,需要存储10个随机数,而且不能重复,所以我们用HashSet集合
* 3,如果HashSet的size是小于10就可以不断的存储,如果大于等于10就停止存储
* 4,通过Random类中的nextInt(n)方法获取1到20之间的随机数,并将这些随机数存储在HashSet集合中
* 5,遍历HashSet
HashSet<Integer>hs = new HashSet<>(); //创建集合对象
Randomr = new Random(); //创建随机数对象
while(hs.size()< 10) {
intnum = r.nextInt(20) + 1; //生成1到20的随机数
hs.add(num); @@自动装箱
}
for(Integer integer : hs) { //遍历集合
System.out.println(integer); //打印每一个元素
}
6.集合框架(练习)
* 使用Scanner从键盘读取一行输入,去掉其中重复字符, 打印出不同的那些字符,aaaabbbcccddd
* 分析:
* 1,创建Scanner对象
* 2,创建HashSet对象,将字符存储,去掉重复
* 3,将字符串转换为字符数组,获取每一个字符存储在HashSet集合中,自动去除重复
* 4,遍历HashSet,打印每一个字符
Scannersc = new Scanner(System.in); //创建键盘录入对象
System.out.println("请输入一行字符串:");
Stringline = sc.nextLine(); //将键盘录入的字符串存储在line中
char[]arr = line.toCharArray(); //将字符串转换成字符数组
HashSet<Character>hs = new HashSet<>(); //创建HashSet集合
for(charc : arr) { //遍历字符数组
hs.add(c); //将字符数组中的字符添加到集合中
}
for(Character ch : hs) { //遍历集合,同样这里写成char,也可以,叫自动拆箱
System.out.println(ch);
}
7.集合框架(练习)
* 将集合中的重复元素去掉 (两种方法,另一种是创建新集合的方式!!!)
* * 分析:
* 1,创建List集合存储若干个重复元素
* 2,单独定义方法去除重复
* 3,打印一下List集合
publicstatic void main(String[] args) {
ArrayList<String>list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("b");
list.add("c");
list.add("c");
getSingle(list);
System.out.println(list);
}
* 分析
* 去除List集合中的重复元素
* 1,创建一个LinkedHashSet集合
* 2,将List集合中所有的元素添加到LinkedHashSet集合
* 3,将list集合中的元素清除
* 4,将LinkedHashSet集合中的元素添加回List集合中
publicstatic void getSingle(List<String> list) {
LinkedHashSet<String>lhs = new LinkedHashSet<>();
lhs.addAll(list); //将list集合中的所有元素添加到lhs
list.clear(); //清空原集合
list.addAll(lhs); //将去除重复的元素添回到list中
}
8.TreeSet存储Integer类型的元素并遍历
* TreeSet存储Integer类型的元素并遍历 @@TreeSet底层是二叉树
*会去除重复元素,并排好序输出
TreeSet<Integer>ts = new TreeSet<>();
ts.add(3);
ts.add(1);
ts.add(1);
ts.add(2);
System.out.println(ts);//输出[1,2,3]!!!!!
9.集合框架()
* TreeSet存储自定义对象
当向TreeSe集合中添加自定义对象时会报错,所以person这个类必须实现Comparable接口,并重写里面的compareTo方法才可以; 另外,当你向TreeSet中添加对象时,它会自动调用compareTo方法,并根据compareTo的返回值决定如何存储元素.
* TreeSet存储自定义对象并遍历练习1(按照姓名排序)
* TreeSet存储自定义对象并遍历练习2(按照姓名的长度排序)
附:Person.java
public class Person implementsComparable<Person> {
privateString name;
privateint age;
publicPerson() {
super();
}
publicPerson(String name, int age) {
super();
this.name= name;
this.age= age;
}
@Override
publicString toString() {
return"Person [name=" + name + ", age=" + age + "]";
}
@Override
publicboolean equals(Object obj) {
Personp = (Person)obj;
returnthis.name.equals(p.name) && this.age == p.age;
}
@Override
publicint hashCode() {
finalint NUM = 38;
returnname.hashCode() * NUM + age; //要尽可能的让hashcode的值不同,这样就可以少调用equals方法,提高运行效率; 在开发的时候hashcode和equals方法不用自己写,alt+shift+s
}
按照年龄排序
publicint compareTo(Person o) {
intnum = this.age - o.age; //年龄是比较的主要条件
returnnum == 0 ? this.name.compareTo(o.name) : num;//姓名是比较的次要条件,num大于0或小于0都返回num,等于0返回名字的比较结果,这里的compareTo是string中的方法,被重写了,按照字典顺序比较!!!!!!
}
按照姓名排序
publicint compareTo(Person o) {
intnum = this.name.compareTo(o.name); //姓名是主要条件
returnnum == 0 ? this.age - o.age : num; //年龄是次要条件,如果姓名一样,返回年龄差,否则返回num
}
publicint compareTo(Person o) {
intlength = this.name.length() - o.name.length(); //比较长度为主要条件
intnum = length == 0 ? this.name.compareTo(o.name) : length; //比较内容为次要条件
returnnum == 0 ? this.age - o.age : num; //比较年龄为次要条件
}
}
* TreeSet保证元素唯一和比较器排序的原理及代码实现
public static void main(String[] args) {
//需求:将字符串按照长度排序
TreeSet<String>ts = new TreeSet<>(new CompareByLen()); //Comparator c = new CompareByLen();
ts.add("aaaaaaaa");
ts.add("z");
ts.add("wc");;
System.out.println(ts);
}
class CompareByLen /*extends Object*/implements Comparator<String> {
@Override
publicint compare(String s1, String s2) { //按照字符串的长度比较
intnum = s1.length() - s2.length(); //长度为主要条件
returnnum == 0 ? s1.compareTo(s2) : num; //内容为次要条件
}
10.TreeSet原理
* 1.特点
*TreeSet是用来排序的, 可以指定一个顺序, 对象存入之后会按照指定的顺序排列
* 2.使用方式
*a.自然顺序(Comparable)需要你存储的这个类去实现Comparable接口,并重写里面的Comparable方法
*TreeSet类的add()方法中会把存入的对象提升为Comparable类型
*调用对象的compareTo()方法和集合中的对象比较
*根据compareTo()方法返回的结果进行存储
*b.比较器顺序(Comparator)
*创建TreeSet的时候可以制定一个Comparator
*如果传入了Comparator的子类对象, 那么TreeSet就会按照比较器中的顺序排序
*add()方法内部会自动调用Comparator接口中compare()方法排序
*调用的对象是compare方法的第一个参数,集合中的对象是compare方法的第二个参数
*c.两种方式的区别
*TreeSet构造函数什么都不传, 默认按照类中Comparable的顺序(没有就报错ClassCastException)类型转换异常
*TreeSet如果传入Comparator, 就优先按照Comparator
11.集合框架(练习)
* 在一个集合中存储了无序并且重复的字符串,定义一个方法,让其有序(字典顺序),而且还不能去除重复
* 分析:
* 1,定义一个List集合,并存储重复的无序的字符串
* 2,定义方法对其排序保留重复
* 3,打印List集合
publicstatic void main(String[] args) {
ArrayList<String>list = new ArrayList<>();
list.add("ccc");
list.add("ccc");
list.add("aaa");
list.add("aaa");
list.add("bbb");;
list.add("ddd");
sort(list);
System.out.println(list);
}
* 定义方法,排序并保留重复
* 分析:
* 1,创建TreeSet集合对象,因为String本身就具备比较功能,但是重复不会保留,所以我们用比较器
* 2,将list集合中所有的元素添加到TrreSet集合中,对其排序,保留重复
* 3,清空list集合
* 4,将TreeSet集合中排好序的元素添加到list中
publicstatic void sort(List<String> list) {
TreeSet<String>ts = new TreeSet<>(new Comparator<String>() { //定义比较器(newComparator(){}是Comparator的子类对象)
@Override
publicint compare(String s1, String s2) { //重写compare方法
intnum = s1.compareTo(s2); //比较内容
returnnum == 0 ? 1 : num; //如果内容一样返回一个不为0的数字即可
}
});
ts.addAll(list); //将list集合中的所有元素添加到ts中
list.clear(); //清空list
list.addAll(ts); //将ts中排序并保留重复的结果在添加到list中
}
12.集合框架(练习)
* 从键盘接收一个字符串, 程序对其中所有字符进行排序,例如键盘输入:helloitcast程序打印:acehillostt
* 分析:
*1,键盘录入字符串,Scanner
* 2,将字符串转换为字符数组
*3,定义TreeSet集合,传入比较器对字符排序并保留重复
*4,遍历字符数组,将每一个字符存储在TreeSet集合中
*5,遍历TreeSet集合,打印每一个字符
Scannersc = new Scanner(System.in); //创建键盘录入对象
System.out.println("请输入一行字符串:");
Stringline = sc.nextLine(); //将键盘录入的字符串存储在line中
char[]arr = line.toCharArray(); //将字符串转换成字符数组
TreeSet<Character>ts = new TreeSet<>(new Comparator<Character>() {
@Override
publicint compare(Character c1, Character c2) {
//intnum = c1.compareTo(c2); //1
intnum = c1 - c2; // 2 自动拆箱!!!!!!!! 1,2意思相同
returnnum == 0 ? 1 : num;
}
});
for(charc : arr) {
ts.add(c); //自动装箱
}
for(Characterch : ts) {
System.out.print(ch);
}
13.集合框架(练习)
* 程序启动后,可以从键盘输入接收多个整数,直到输入quit时结束输入. 把所有输入的整数倒序排列打印.
*1,创建Scanner对象,键盘录入
*2,创建TreeSet集合对象,TreeSet集合中传入比较器
*3,无限循环不断接收整数,遇到quit退出,因为退出是quit,所以键盘录入的时候应该都以字符串的形式录入
*4,判断是quit就退出,不是就将其转换为Integer,并添加到集合中
*5,遍历TreeSet集合并打印每一个元素
Scannersc = new Scanner(System.in); //创建键盘录入对象
System.out.println("请输入:");
TreeSet<Integer>ts = new TreeSet<>(new Comparator<Integer>() {//将比较器传给TreeSet的构造方法
@Override
publicint compare(Integer i1, Integer i2) {
//intnum = i2 - i1; //自动拆箱,正序就i1-i2!!!!!!!
intnum = i2.compareTo(i1);
returnnum == 0 ? 1 : num;
}
});
while(true){
Stringline = sc.nextLine(); //将键盘录入的字符串存储在line中
if("quit".equals(line)) { //如果字符串常量和变量比较,常量放前面,这样不会出现空指针异常,变量里面可能存储null
break;
try{
intnum = Integer.parseInt(line);//将数字字符串转换成数字
ts.add(num);
}catch (Exception e) {
System.out.println("您录入的数据有误,请输入一个整数");
}
}
for(Integer i : ts) { //遍历TreeSet集合
System.out.println(i);
}
14.键盘录入学生信息按照总分排序后输出在控制台
* 键盘录入5个学生信息(姓名,语文成绩,数学成绩,英语成绩),按照总分从高到低输出到控制台。
*分析:
*1,定义一个学生类
* 成员变量:姓名,语文成绩,数学成绩,英语成绩,总成绩
* 成员方法:空参,有参构造,有参构造的参数分别是姓名,语文成绩,数学成绩,英语成绩
* toString方法,在遍历集合中的Student对象打印对象引用的时候会显示属性值
* 2,键盘录入需要Scanner,创建键盘录入对象
* 3,创建TreeSet集合对象,在TreeSet的构造函数中传入比较器,按照总分比较
*4,录入五个学生,所以以集合中的学生个数为判断条件,如果size是小于5就进行存储
*5,将录入的字符串切割,用逗号切割,会返回一个字符串数组,将字符串数组中从二个元素转换成int数,
*6,将转换后的结果封装成Student对象,将Student添加到TreeSet集合中
*7,遍历TreeSet集合打印每一个Student对象
------------------------------------------------------------------------------------------
Scannersc = new Scanner(System.in);
System.out.println("请输入5个学生成绩格式是:(姓名,语文成绩,数学成绩,英语成绩)");
TreeSet<Student>ts = new TreeSet<>(new Comparator<Student>() {
@Override
publicint compare(Student s1, Student s2) {
intnum = s2.getSum() - s1.getSum(); //根据学生的总成绩降序排列
returnnum == 0 ? 1 : num;
}
});
while(ts.size()< 5) {
Stringline = sc.nextLine();
try{
String[]arr = line.split(",");
intchinese = Integer.parseInt(arr[1]); //转换语文成绩
intmath = Integer.parseInt(arr[2]); //转换数学成绩
intenglish = Integer.parseInt(arr[3]); //转换英语成绩
ts.add(newStudent(arr[0], chinese, math, english));
}catch (Exception e) {
System.out.println("录入格式有误,输入5个学生成绩格式是:(姓名,语文成绩,数学成绩,英语成绩");
}
}
System.out.println("排序后的学生成绩是:");
for(Student s : ts) {
System.out.println(s);
}
15.总结
* 1.List
*a.普通for循环, 使用get()逐个获取
*b.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
*c.增强for循环, 只要可以使用Iterator的类都可以用
*d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法
* 2.Set
*a.调用iterator()方法得到Iterator, 使用hasNext()和next()方法
*b.增强for循环, 只要可以使用Iterator的类都可以用
* 3.普通for循环,迭代器,增强for循环是否可以在遍历的过程中删除
- 集合3--Map集合
- 集合3
- 集合-3
- 集合3
- 集合框架3:Set集合
- 集合框架-Collection集合-3
- 集合框架-Collection集合-3
- 集合框架-List集合-3
- 集合(3)把一个集合插入到另一个集合中
- 集合(3) Map集合,工具类
- 集合和列表3
- C#3。0 集合
- Java 集合小结3
- 黑马程序员 集合 3
- 排序算法集合 -3
- java基础集合3
- groovy入门3 集合
- 图解集合3:CopyOnWriteArrayList
- java中将String和int转换的方法
- 八皇后
- 使用AsyncHttpClient 框架提交数据
- 仿魅族数字图案解锁
- STM32系列第8篇--串口配置步骤
- 集合-3
- 欢迎使用CSDN-markdown编辑器
- 如何对DataTable进行动态分组和动态统计[C#]
- blueGreen develop , 敏捷开发
- 【小镇的技术天梯】从头写数据结构,C语言实现双向链表
- linux下安装svn
- Google cardBoard Android的两个jar包,以及Demo
- JavaScrit常用的简单交互
- Mybatis使用generator自动生成映射配置文件信息