知识总结
java.util包中的LinkedList
遍历:遍历链表,利用迭代器。链表对象可以使用iterator()方法获取一个Iterator对象,该对象就是针对当前链表的迭代器。
创建一个空的链表
List
向链表中添加新的结点
list.add(new Student(
删除结点
list.remove("
查找:
int binarySearch(List
将list中的元素按升序排序
public static sort(List
链表中数据的插入
list.add("
课上内容补做
数据结构-排序
在数据结构和算法中,排序是很重要的操作,要让一个类可以进行排序,有两种方法:
- 有类的源代码,针对某一成员变量排序,让类实现Comparable接口,调用Collection.sort(List)
- 没有类的源代码,或者多种排序,新建一个类,实现Comparator接口 调用Collection.sort(List, Compatator)
针对下面的Student类,使用Comparator编程完成以下功能:
- 在测试类StudentTest中新建学生列表,包括自己和学号前后各两名学生,共5名学生,给出运行结果(排序前,排序后
- 对这5名同学分别用学号和总成绩进行增序排序,提交两个Comparator的代码
课下提交代码到码云
代码链接:
https://gitee.com/BESTI-IS-JAVA-2018/20165305zhenlong/tree/master/java/Student
结果截图
数据结构-单链表
参见附件,补充MyList.java的内容,提交运行结果截图(全屏)
课下推送代码到码云
代码链接
https://gitee.com/BESTI-IS-JAVA-2018/20165305zhenlong/tree/master/java/MyList
结果截图
第十五章的代码分析
例子1
Example15_1.java ,Cone.java , Rect.java , Circle.java 中,声明了一个泛型类:Cone,一个Cone对象计算体积时,只关心它的底是否能计算面积,并不关心底的类型
Cone.java
public class Cone<E> {
double height;
E bottom; //用泛型类E声明对象bottom
public Cone(E b) { //参数b是泛型类型
bottom = b;
}
public void setHeight(double h) { //此方法给高height赋值
height = h;
}
public double computerVolume() { //计算体积的方法
String s = bottom.toString();//泛型变量只能调用从Object类继承的或重写的方法
double area = Double.parseDouble(s); //将string类型转换成double型
return 1.0 / 3.0 * area * height; //计算体积
}
}
Rect.java
public class Rect { //计算方形面积的类
double sideA, sideB, area;
Rect(double a, double b) { //构造方法将a,b值传给sideA,sideB
sideA = a;
sideB = b;
}
public String toString() {//泛型类中的泛型变量bottom只能调用Object类中的方法,Rect类重写了toString()方法
area = sideA * sideB; //计算面积
return "" + area;
}
}
Circle
public class Circle {//计算圆形面积的类
double area, radius;
Circle(double r) {//构造方法将r值传给radius
radius = r;
}
public String toString() { //泛型类中的泛型变量bottom只能调用Object类中的方法,Circle类重写Object类的toString()方法
area = radius * radius * Math.PI;//计算面积,Math.PI为圆周率
return "" + area;
}
}
Example15_1.java
public class Example15_1 {
public static void main(String args[]) {
Circle circle = new Circle(10);
Cone<Circle> coneOne = new Cone<Circle>(circle);//创建一个(圆)锥对象
coneOne.setHeight(16);//调用Cone类中setHeight()方法,将高设为16
System.out.println(coneOne.computerVolume());//调用Cone类中computerVolume()方法,计算体积;computerVolume()方法调用Circle类中的toString()方法,计算面积
Rect rect = new Rect(15, 23);
Cone<Rect> coneTwo = new Cone<Rect>(rect);//创建一个(方)锥对象
coneTwo.setHeight(98);
System.out.println(coneTwo.computerVolume());
//下面方锥体积和上面计算圆锥体积的道理相同
}
}
例子2
比较了使用迭代器遍历链表和get(int index)方法遍历链表的所用时间
import java.util.*;
public class Example15_2 {
public static void main(String args[]) {
List<String> list = new LinkedList<String>();//创建链表list
for (int i = 0; i <= 60096; i++) {
list.add("speed" + i);//添加结点
}
Iterator<String> iter = list.iterator();//创建迭代器iter
long starttime = System.currentTimeMillis();//获取当前时间
while (iter.hasNext()) {//hasNext()此方法检查链表中是否还有结点
String te = iter.next();//next()方法获取下一个结点
}
long endTime = System.currentTimeMillis();//获取遍历完链表的时间
long result = endTime - starttime;//时间差代表遍历链表的时间
System.out.println("使用迭代器遍历集合所用时间:" + result + "毫秒");
starttime = System.currentTimeMillis();
for (int i = 0; i < list.size(); i++) {//list.size()为链表结点数
String te = list.get(i);//list.get()依次得到链表中的结点数据
}
endTime = System.currentTimeMillis();
result = endTime - starttime;
System.out.println("使用get方法遍历集合所用时间:" + result + "毫秒");
}
}
例子3
代码中使用了JDK1.5版本之前的LinkedList。
import java.util.*;
public class Example15_3 {
public static void main(String args[]) {
LinkedList mylist = new LinkedList();//创建链表对象
mylist.add("你"); //链表中的第一个节点
mylist.add("好"); //链表中的第二个节点
int number = mylist.size(); //获取链表的长度
for (int i = 0; i < number; i++) {
String temp = (String) mylist.get(i); //必须强制转换取出的数据
System.out.println("第" + i + "节点中的数据:" + temp);
}
Iterator iter = mylist.iterator();
while (iter.hasNext()) {
String te = (String) iter.next(); //必须强制转换取出的数据
System.out.println(te);
//hasNext()方法和next()方法在前面解释过了
}
}
}
例子4
Student类通过实现Comparable接口规定该类的对象的大小关系(按height值的大小确定大小关系,即学生按其身高确定之间的大小关系)。链表添加了3个Student对象,Collections调用sort方法将链表中的对象按身其height值升序排序,并查找一个对象的height值是否和链表中某个对象的height值相同。
import java.util.*;
class Student implements Comparable {//Student类通过实现Comparable接口规定该类的对象的大小关系
int height = 0;
String name;
Student(String n, int h) {
name = n;
height = h;
}
public int compareTo(Object b) { // 两个Student对象相等当且仅当二者的height值相等
Student st = (Student) b;
return (this.height - st.height);
}
}
public class Example15_4 {
public static void main(String args[]) {
List<Student> list = new LinkedList<Student>();//创建链表list
list.add(new Student("张三", 188));
list.add(new Student("李四", 178));
list.add(new Student("周五", 198));//向链表中添加3个Student对象
Iterator<Student> iter = list.iterator();//创建迭代器
System.out.println("排序前,链表中的数据");
while (iter.hasNext()) {
Student stu = iter.next();//创建Student对象stu存放结点的数据
System.out.println(stu.name + "身高:" + stu.height);//调用成员变量
}
Collections.sort(list);//Collections类提供用于排序和查找的方法
System.out.println("排序后,链表中的数据");
iter = list.iterator();//再次创建迭代器
while (iter.hasNext()) {
Student stu = iter.next();
System.out.println(stu.name + "身高:" + stu.height);
}
Student zhaoLin = new Student("zhao xiao lin", 178);
int index = Collections.binarySearch(list, zhaoLin, null);//查找
if (index >= 0) {//没有找到index=-1,找到index>=0
System.out.println(zhaoLin.name + "和链表中" + list.get(index).name + "身高相同");
}
}
}
例子5
代码中使用了shuffle()方法、reverse()方法和rotate()。
import java.util.*;
public class Example15_5 {
public static void main(String args[]) {
List<Integer> list = new LinkedList<Integer>();//创建链表
for (int i = 10; i <= 50; i = i + 10)
list.add(new Integer(i));//添加结点
System.out.println("洗牌前,链表中的数据");
Iterator<Integer> iter = list.iterator();//创建迭代器
while (iter.hasNext()) {
Integer n = iter.next();
System.out.printf("%d\t", n.intValue());//输出下一下int类型的值
}
Collections.shuffle(list);//重新随机排列
System.out.printf("\n洗牌后,链表中的数据\n");
iter = list.iterator();
while (iter.hasNext()) {
Integer n = iter.next();
System.out.printf("%d\t", n.intValue());
}
System.out.printf("\n再向右旋转1次后,链表中的数据\n");
Collections.rotate(list, 1);//向右旋转一次
iter = list.iterator();
while (iter.hasNext()) {
Integer n = iter.next();
System.out.printf("%d\t", n.intValue());
}
}
}
例子6
代码中用堆栈输出该递归序列的若干项 。
import java.util.*;
public class Example15_6 {
public static void main(String args[]) {
Stack<Integer> stack = new Stack<Integer>();//建立一个堆栈对象
stack.push(new Integer(1));//压栈,第一项为1
stack.push(new Integer(1));//压栈,第二项为1
int k = 1;
while (k <= 10) {//实现Fibonacci整数序列的前12项
for (int i = 1; i <= 2; i++) {
Integer F1 = stack.pop();//取出栈顶对象
int f1 = F1.intValue();//得到对象的int值
Integer F2 = stack.pop();//取出栈顶对象
int f2 = F2.intValue();//得到对象的int值
Integer temp = new Integer(f1 + f2);//创建f1和f2之和的对象
System.out.println("" + temp.toString());
stack.push(temp);//压栈
stack.push(F2);//将刚才后取出的对象压栈
k++;//实现递归循环
}
}
}
}
例子7
这是一个英语单词查询的GUI程序,用户在界面的的一个文本框中输入一个英文单词回车确认,另一个文本框显示英文单词的汉语翻译。
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class WordPolice implements ActionListener {
JTextField showText;
HashMap<String, String> hashtable;//创建散列映射对象
File file = new File("word.txt"); //创建文件对象
Scanner sc = null;
WordPolice() {
hashtable = new HashMap<String, String>();
try {
sc = new Scanner(file);//使用Scanner解析word.txt中的单词
while (sc.hasNext()) {
String englishWord = sc.next();
String chineseWord = sc.next();
//根据word.txt文件可知先是英文单词才是汉语
hashtable.put(englishWord, chineseWord);
//将英文单词、汉语作为键/值对储存在散列映射中
}
} catch (Exception e) {
}
}
public void setJTextField(JTextField showText) {
this.showText = showText;
}
public void actionPerformed(ActionEvent e) {
String englishWord = e.getActionCommand();
if (hashtable.containsKey(englishWord))//若有使用englishWord这个键的键/值对 {
String chineseWord = hashtable.get(englishWord);
//返回使用englishWorld键所对应的值
showText.setText(chineseWord);
//将值输出
} else {
showText.setText("没有此单词");
}
}
}
例子8
代码中的树集按着英语成绩从底到高存放四个Student对象。
import java.util.*;
class Student implements Comparable {
//Student类通过实现Comparable接口规定按english确定大小关系
int english = 0;
String name;
Student(int english, String name) {
this.name = name;
this.english = english;
}
public int compareTo(Object b) {
Student st = (Student) b;
return (this.english - st.english);
}
}
public class Example15_8 {
public static void main(String args[]) {
TreeSet<Student> mytree = new TreeSet<Student>();
//创建树集对象
Student st1, st2, st3, st4;
st1 = new Student(90, "赵一");
st2 = new Student(66, "钱二");
st3 = new Student(86, "孙三");
st4 = new Student(76, "李四");
mytree.add(st1);
//以上几句代码可以简写为mytree.add(new Student(90,"赵一"));
mytree.add(st2);
mytree.add(st3);
mytree.add(st4);
Iterator<Student> te = mytree.iterator();//创建迭代器
while (te.hasNext()) {
Student stu = te.next();
System.out.println("" + stu.name + " " + stu.english);
//依次输出排序好的结点
}
}
}
例子9
使用了TreeMap,分别按着学生的英语成绩和数学成绩排序节点。
import java.util.*;
class StudentKey implements Comparable {
//StudentKey类通过实现Comparable接口规定按关键字进行排序
double d = 0;
StudentKey(double d) {
this.d = d;
}
public int compareTo(Object b) {
StudentKey st = (StudentKey) b;
if ((this.d - st.d) == 0)
return -1;
else
return (int) ((this.d - st.d) * 1000);
}
}
class Student {
String name = null;
double math, english;
Student(String s, double m, double e) {
name = s;
math = m;
english = e;
}
}
public class Example15_9 {
public static void main(String args[]) {
TreeMap<StudentKey, Student> treemap = new TreeMap<StudentKey, Student>();
//创建一个树映射,StudentKey为关键字,Student为数值
String str[] = {"赵一", "钱二", "孙三", "李四"};
double math[] = {89, 45, 78, 76};
double english[] = {67, 66, 90, 56};
Student student[] = new Student[4];
for (int k = 0; k < student.length; k++) {
student[k] = new Student(str[k], math[k], english[k]);
}
StudentKey key[] = new StudentKey[4];
for (int k = 0; k < key.length; k++) {
key[k] = new StudentKey(student[k].math); //关键字按数学成绩排列大小
}
for (int k = 0; k < student.length; k++) {
treemap.put(key[k], student[k]);//向树映射中添加键/值对
}
int number = treemap.size();//返回树映射中的键/值对个数
System.out.println("树映射中有" + number + "个对象,按数学成绩排序:");
Collection<Student> collection = treemap.values();
Iterator<Student> iter = collection.iterator();//创建迭代器
while (iter.hasNext()) {
Student stu = iter.next();
System.out.println("姓名 " + stu.name + " 数学 " + stu.math);
}
treemap.clear();//清空树映射,为下一轮排序进行准备
for (int k = 0; k < key.length; k++) {
key[k] = new StudentKey(student[k].english);//关键字按英语成绩排列大小
}
for (int k = 0; k < student.length; k++) {
treemap.put(key[k], student[k]);
}
number = treemap.size();
System.out.println("树映射中有" + number + "个对象:按英语成绩排序:");
collection = treemap.values();
iter = collection.iterator();
while (iter.hasNext()) {
Student stu = (Student) iter.next();
System.out.println("姓名 " + stu.name + " 英语 " + stu.english);
}
//按照英语成绩排序和按照数学成绩排序类似,只是更换了关键字
}
}
例子10
代码中使用了自动装箱与拆箱。
import java.util.*;
public class Example15_10 {
public static void main(String args[]) {
ArrayList<Integer> list = new ArrayList<Integer>();
for (int i = 0; i < 10; i++) {
list.add(i); //自动装箱,实际添加到list中的是new Integer(i)。
}
for (int k = list.size() - 1; k >= 0; k--) {
int m = list.get(k); //自动拆箱,获取Integer对象中的int型数据
System.out.printf("%3d", m);
}
}
}
例子11
代码中使用对象流实现商品库存的录入与显系示统。
Example15_11.java
public class Example15_11 {
public static void main(String args[]) {
WindowGoods win=new WindowGoods();
win.setTitle("商品的录入与显示");
}
}
Goods.java
public class Goods implements java.io.Serializable {
String name, mount,price;
public void setName(String name) {
this.name=name;
}
public void setMount(String mount) {
this.mount=mount;
}
public void setPrice(String price) {
this.price=price;
}
public String getName() {
return name;
}
public String getMount() {
return mount;
}
public String getPrice() {
return price;
}
}
InputArea.java
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class InputArea extends JPanel implements ActionListener {
File f=null; //存放链表的文件
Box baseBox ,boxV1,boxV2;
JTextField name,mount,price; //为Goods对象提供的视图
JButton button; //控制器
LinkedList<Goods> goodsList; //存放Goods对象的链表
InputArea(File f) {
this.f=f;
goodsList=new LinkedList<Goods>();
name=new JTextField(12);
mount=new JTextField(12);
price=new JTextField(12);
button=new JButton("录入");
button.addActionListener(this);
boxV1=Box.createVerticalBox();
boxV1.add(new JLabel("输入名称"));
boxV1.add(Box.createVerticalStrut(8));
boxV1.add(new JLabel("输入库存"));
boxV1.add(Box.createVerticalStrut(8));
boxV1.add(new JLabel("输入单价"));
boxV1.add(Box.createVerticalStrut(8));
boxV1.add(new JLabel("单击录入"));
boxV2=Box.createVerticalBox();
boxV2.add(name);
boxV2.add(Box.createVerticalStrut(8));
boxV2.add(mount);
boxV2.add(Box.createVerticalStrut(8));
boxV2.add(price);
boxV2.add(Box.createVerticalStrut(8));
boxV2.add(button);
baseBox=Box.createHorizontalBox();
baseBox.add(boxV1);
baseBox.add(Box.createHorizontalStrut(10));
baseBox.add(boxV2);
add(baseBox);
}
public void actionPerformed(ActionEvent e) {
if(f.exists()) {
try{
FileInputStream fi=new FileInputStream(f);
ObjectInputStream oi=new ObjectInputStream(fi);
goodsList= (LinkedList<Goods>)oi.readObject();
fi.close();
oi.close();
Goods goods=new Goods();
goods.setName(name.getText());
goods.setMount(mount.getText());
goods.setPrice(price.getText());
goodsList.add(goods);
FileOutputStream fo=new FileOutputStream(f);
ObjectOutputStream out=new ObjectOutputStream(fo);
out.writeObject(goodsList);
out.close();
}
catch(Exception ee) {}
}
else{
try{
f.createNewFile();
Goods goods=new Goods();
goods.setName(name.getText());
goods.setMount(mount.getText());
goods.setPrice(price.getText());
goodsList.add(goods);
FileOutputStream fo=new FileOutputStream(f);
ObjectOutputStream out=new ObjectOutputStream(fo);
out.writeObject(goodsList);
out.close();
}
catch(Exception ee) {}
}
}
}
WindowsGoods.java
import java.io.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class WindowGoods extends JFrame implements ActionListener {
File file=null;
JMenuBar bar;
JMenu fileMenu;
JMenuItem 录入,显示;
JTextArea show;
InputArea inputMessage;
JPanel pCenter;
JTable table;
Object 表格单元[][],列名[]={"名称","库存","单价"};
CardLayout card;
WindowGoods() {
file=new File("库存.txt"); //存放链表的文件
录入=new JMenuItem("录入");
显示=new JMenuItem("显示");
bar=new JMenuBar();
fileMenu=new JMenu("菜单选项");
fileMenu.add(录入);
fileMenu.add(显示);
bar.add(fileMenu);
setJMenuBar(bar);
录入.addActionListener(this);
显示.addActionListener(this);
inputMessage=new InputArea(file); //创建录入截面
card=new CardLayout();
pCenter=new JPanel();
pCenter.setLayout(card);
pCenter.add("录入",inputMessage);
add(pCenter,BorderLayout.CENTER);
setVisible(true);
setBounds(100,50,420,380);
validate();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
if(e.getSource()==录入) {
card.show(pCenter,"录入");
}
else if(e.getSource()==显示) {
try{
FileInputStream fi=new FileInputStream(file);
ObjectInputStream oi=new ObjectInputStream(fi);
LinkedList<Goods> goodsList=(LinkedList<Goods>)oi.readObject();
fi.close();
oi.close();
int length=goodsList.size();
表格单元=new Object[length][3];
table=new JTable(表格单元,列名);
pCenter.removeAll();
pCenter.add("录入",inputMessage);
pCenter.add("显示",new JScrollPane(table));
pCenter.validate();
Iterator<Goods> iter=goodsList.iterator();
int i=0;
while(iter.hasNext()) {
Goods 商品 =iter.next();
表格单元[i][0]= 商品.getName();
表格单元[i][1]=商品.getMount();
表格单元[i][2]=商品.getPrice();
i++;
}
table.repaint();
}
catch(Exception ee){}
card.show(pCenter,"显示");
}
}
}
第十五章课后编程题
3.编程题
1.使用堆栈结构输出an的若干项,其中an=2an-1+2an-2,a1=3,a2=8。
2.编写一个程序,将链表中的学生英语成绩单存放到一个树集中,使得按成绩自动排序,并输出排序结果。
3.有10个U盘,有两个重要的属性:价格和容量。编写一个应用程序,使用TreeMap
3-1
代码链接
https://gitee.com/BESTI-IS-JAVA-2018/20165305zhenlong/blob/master/java/XiTi/XiTi1.java
结果截图
3-2
代码链接
https://gitee.com/BESTI-IS-JAVA-2018/20165305zhenlong/blob/master/java/XiTi/XiTi2.java
结果截图
3-3
代码链接
https://gitee.com/BESTI-IS-JAVA-2018/20165305zhenlong/blob/master/java/XiTi/XiTi3.java