黑马黄埔班基础进阶考试
第一题(15)
需求
- 某小型商城系统的订单信息在素材下的orders.xml文件中,现在要求把xml中的订单信息,封装成一个一个的订单对象,将订单对象保存到ArrayList集合中。
具体功能点要求
- 定义订单类Order,创 建ArrayList集合,用于存储订单Order对象 (解析XML 4分,封装成对象2分)
2)请使用Stream流找出今天之前的订单,并遍历输出。(3分)
请使用Stream流找出集合中价格最贵的订流单,把这个订单的详细信息打印出来。(3分)
请使用Stream流遍历集合中的每个订单,要求按照价格降序输出每个订单的详情。(3分)
package com.wuxuan.Exams.End;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
/**
* **具体功能点要求**
*
* 1) 定义订单类Order,创建ArrayList集合,用于存储订单Order对象 (解析XML 4分,封装成对象2分)
*
* 2) 请使用Stream流找出今天之前的订单,并遍历输出。(3分)
*
* 3) 请使用Stream流找出集合中价格最贵的订流单,把这个订单的详细信息打印出来。(3分)
*
* 4) 请使用Stream流遍历集合中的每个订单,要求按照价格降序输出每个订单的详情。(3分)
*/
public class Problem1 {
public static void main(String[] args) throws DocumentException {
//1.定义一个List集合存储全部订单对象
List<Order> orders = new ArrayList<Order>();
//2.导入dom4j框架
SAXReader saxReader = new SAXReader();
//3.读取xml文件成为一个Document对象
Document document = saxReader.read(Problem1.class.getResourceAsStream("/orders.xml"));
//4.提取根元素
Element root = document.getRootElement();
//5.提取一级子元素(order订单元素)
List<Element> orderEles = root.elements();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//6.遍历每个订单元素
for (Element orderEle : orderEles) {
//7.每个订单元素是一个订单对象
Order order = new Order();
order.setId(Integer.valueOf(orderEle.attributeValue("id")));
order.setName(orderEle.elementText("name"));
order.setTime(LocalDateTime.parse(orderEle.elementText("time"),dtf));
order.setPrice(Double.valueOf(orderEle.elementText("double")));
//8.把订单对象存入集合中
orders.add(order);
}
System.out.println("订单内容如下:");
System.out.println(orders);
//9.使用Stream流找出今天之前的订单,并遍历输出。(3分)
System.out.println("今天之前的订单如下:");
orders.stream().filter(o -> o.getTime().isBefore(LocalDateTime.now())).forEach(o -> System.out.println(o));
//实例方法的引用
// orders.stream().filter(o -> o.getTime().isBefore(LocalDateTime.now())).forEach(System.out::println);
//10. 请使用Stream流找出集合中价格最贵的订流单,把这个订单的详细信息打印出来。(3分)
System.out.println("最贵的订单如下:");
Order order = orders.stream().max((o1,o2) -> Double.compare(o1.getPrice(),o2.getPrice())).get();
System.out.println(order);
//11.请使用Stream流遍历集合中的每个订单,要求按照价格降序输出每个订单的详情。(3分)
System.out.println("根据价格降序如下:");
orders.stream().sorted((o1,o2) -> Double.compare(o2.getPrice(),o1.getPrice())).forEach(System.out::println);
}
}
package com.wuxuan.Exams.End;
import java.time.LocalDateTime;
public class Order {
private int id;
private String name;
private LocalDateTime time;
private double price;
public Order() {
}
public Order(int id, String name, LocalDateTime time, double price) {
this.id = id;
this.name = name;
this.time = time;
this.price = price;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public LocalDateTime getTime() {
return time;
}
public void setTime(LocalDateTime time) {
this.time = time;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Order{" +
"id=" + id +
", name='" + name + '\'' +
", time=" + time +
", price=" + price +
'}' ;
}
}
<?xml version="1.0" encoding="UTF-8" ?>
<orders>
<order id="1">
<name>Java入门</name>
<time>2023-11-11 09:23:11</time>
<double>45.4</double>
</order>
<order id="2">
<name>黑枸杞</name>
<time>2023-11-21 13:33:23</time>
<double>28.9</double>
</order>
<order id="3">
<name>决明子</name>
<time>2023-03-21 09:30:00</time>
<double>36.5</double>
</order>
<order id="4">
<name>菊花</name>
<time>2023-05-11 19:30:00</time>
<double>16.5</double>
</order>
</orders>
第二题(10)
需求
某个班级组织团建活动,班长给出了几个去处给大家选择,分别是 “农家乐” , “轰趴”,“野外拓展”,“健身房”,本次活动每个学生是可以多选的。
现在有如下5名学生选择了如下去处。
张全蛋儿 农家乐,野外拓展
李二狗子 轰趴,野外拓展,健身房
翠花 野外拓展,
小帅 轰趴,健身房
有容 农家乐
具体的功能点如下:
1、请找出每个去处想去的人数是多少,并输出投票最多的去处是哪个。
2、请找出哪些人没有选择投票最多的去处,输出他们的名字。(本案例用不用stream流做都给分)
比如:小帅,有容没有选择野外拓展。
package com.wuxuan.Exams.End;
import java.util.*;
import java.util.stream.Collectors;
/**
* 张全蛋儿 农家乐,野外拓展
* 李二狗子 轰趴,野外拓展,健身房
* 翠花 野外拓展,
* 小帅 轰趴,健身房
* 有容 农家乐
*/
public class Problem2 {
public static void main(String[] args) {
//1.拿数据到程序中来,用对象封装可以,用Map集合封装也可以
Map<String, List<String>> selects = new HashMap<String, List<String>>();
List<String> data1 = new ArrayList<String>();
Collections.addAll(data1, "农家乐", "野外拓展", "轰趴");
selects.put("张全蛋儿", data1);
List<String> data2 = new ArrayList<String>();
Collections.addAll(data2, "轰趴", "野外拓展", "健身房");
selects.put("李二狗子", data2);
List<String> data3 = new ArrayList<String>();
Collections.addAll(data3, "野外拓展", "轰趴");
selects.put("翠花", data3);
List<String> data4 = new ArrayList<String>();
Collections.addAll(data4, "健身房");
selects.put("小帅", data4);
List<String> data5 = new ArrayList<String>();
Collections.addAll(data5, "农家乐");
selects.put("有容", data5);
System.out.println(selects);
//2.找出每个去处选择的人数,输出人数最多的地方
Map<String, Integer> infos = new HashMap<>();
selects.forEach((name, datas) -> {
for (String data : datas) {
infos.put(data, infos.containsKey(data) ? infos.get(data) + 1 : 1);
}
});
System.out.println("每个去处的人数是:");
System.out.println(infos);
//3.输出去处最多的地方
System.out.println("选择的人最多的去处是:");
Map.Entry<String, Integer> entry =
infos.entrySet().stream().max((e1, e2) -> e1.getValue() - e2.getValue()).get();
List<String> names = infos.entrySet().stream().filter(e -> e.getValue() == entry.getValue()).map(e -> e.getKey()).collect(Collectors.toList());
System.out.println(names);
//4.哪些人没有选择去处最多的地方
System.out.println("没有去人数最多的去处的人如下:");
selects.entrySet().stream().filter(e -> {
boolean flag = true;//没有包含
for (String s : e.getValue()) {
if (names.contains(s)) {
flag = false;
break;
}
}
return flag;
}).forEach(e -> System.out.println(e.getKey()));
}
}
第三题 (15)
需求
- 黑马程序员教学管理系统的菜单信息如下(图1所示),菜单的详细数据存储在给的素材文件“系统菜单.txt”中。
具体要实现的功能点如下所示
1、请从系统菜单.txt中读取这些菜单信息,将这些菜单信息在控制台展示成图1的样子(必须确保展示的顺序是正确的)
00010001-班级学员管理
00030001-就业班管理
00030002-就业学员管理
0001-班级管理
00020001-班级每日反馈
00020002-班级入学测评
00010002-班级学员就业管理
0003-就业业务管理
00020003-班级讲师评分
00020004-班级授课视频
0002-教学业务管理
00020005-班级作息时间设置
00030003-学员面试记录
2、将正确的菜单顺序,写出到一个新文件**“系统菜单2.txt”**中保存起来,详细格式如下
评分细则
- 能把数据读取出来:3分
- 能展示成控制台的样子:8分
- 能写出去:4分。
package com.wuxuan.Exams.End;
import java.io.*;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Problem3 {
public static void main(String[] args) {
try (
//1.使用流读取文件中的全部数据
BufferedReader br = new BufferedReader(new FileReader("Basic\\src\\系统菜单.txt"));
PrintStream ps = new PrintStream("Basic\\src\\系统菜单2.txt");
){
//2.按照行读取菜单,存入到集合中去
List<String> menus = new ArrayList<String>();
String line;
while((line = br.readLine()) != null){
menus.add(line);
}
//3.对菜单进行排序
Collections.sort(menus);//可以
//4.遍历集合
for (String menu : menus) {
String[] menuNumAndName = menu.split("-");
// if(menuNumAndName[0].length() == 4){
// System.out.println(menuNumAndName[1]);
// }else{
// System.out.println("\t" + menuNumAndName[1]);
// }
//简化如下:
System.out.println(menuNumAndName[0].length() == 4 ? menuNumAndName[1] : "\t" + menuNumAndName[1]);
}
//5.写出菜单到新文件中去
for (String menu : menus) {
ps.println(menu);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
第四题(20)
需求
- 红包雨游戏,某企业有100名员工,员工的工号依次是1, 2,3, 4,…到100。现在公司举办了年会活动,活动中有一个红包雨环节,要求共计发出200个红包雨。其中小红包在[1 - 30] 元之间,总占比为80%,大红包[31-100]元,总占比为20%。
具体的功能点如下
1、系统模拟上述要求产生200个红包。
2、模拟100个员工抢红包雨,需要输出哪个员工抢到哪个红包的过程,活动结束时需要提示活动结束。
3、活动结束后,请1对100名员工按照所抢红包的总金额进行降序排序展示,例如:3号员工抢红包总计:293元、1号员工抢红包总计250元,…
package com.wuxuan.Exams.End;
import java.util.List;
import java.util.Random;
public class PeopleThread extends Thread {
private List<Integer> moneys;
private int totalMoney;
public PeopleThread(List<Integer> moneys,String name) {
super(name);
this.moneys = moneys;
}
private Random r = new Random();
@Override
public void run() {
//100个线程来抢钱
while(true){
String name = Thread.currentThread().getName();
synchronized(moneys){
//注意!if,esle放锁里面好,否则会出问题!!!放里面的话,最后一个红包被抢之后,后面几个再继续抢锁的话不会出问题
if(moneys.size() == 0){
break;
}
r.nextInt(moneys.size());
//取红包给当前这个人
int money = moneys.remove(r.nextInt(moneys.size()));
System.out.println(name + "抢到:" + money);
totalMoney += money;
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public int getTotalMoney() {
return totalMoney;
}
public void setTotalMoney(int totalMoney) {
this.totalMoney = totalMoney;
}
}
package com.wuxuan.Exams.End;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;
public class Problem4 {
public static void main(String[] args) throws Exception {
//目标:红包雨游戏
//1.拿红包进来
List<Integer> moneys = getMoneys();
System.out.println(moneys);
//打乱顺序
Collections.shuffle(moneys);
System.out.println(moneys);
//2.创建100个员工
List<PeopleThread> peopleThreads = new ArrayList<>();
for (int i = 1; i <= 100; i++) {
PeopleThread peopleThread = new PeopleThread(moneys,i + "号");
peopleThreads.add(peopleThread);
peopleThread.start();
}
//3.统计谁抢的最多,降序排名
for (PeopleThread peopleThread : peopleThreads) {
peopleThread.join();
}
System.out.println("活动结束...");
peopleThreads.stream().sorted((o1,o2) -> o2.getTotalMoney() - o1.getTotalMoney())
.forEach(p -> System.out.println(p.getName() + "抢红包总计:" + p.getTotalMoney()));
}
public static List<Integer> getMoneys(){
//1.拿红包进来
List<Integer> moneys = new ArrayList<>();
Random r = new Random();
//2.按照权重随机红包
for (int i = 0; i < 160; i++) {
moneys.add(r.nextInt(30) + 1);
}
for (int i = 0; i < 40; i++) {
moneys.add(r.nextInt(70) +31);
}
return moneys;
}
}
第五题(24)
需求
在实际开发中,很多系统都要完成用户登录和注册功能,但需要注意的是,用户注册的登录名和密码必须是发送给服务端进行保存的,并且注册的登录名是不能重复的,同时登录也是需要到服务端进行认证的。
功能点具体要求
1、开发一个客户端,具备注册,和登录功能,除非用户输入exit,否则不退出这个界面。
2、注册功能要求:可以发送登录名和密码给服务端,服务端要响应是否注册成功的结果给客户端。如果注册没有问题,服务端需要将用户注册的登录名和密码保存到文件中去。(注:是什么文件,可自行确定)
3、登录功能要求:用户输入登录名和密码,需要发送给服务端,服务端认证后需要把登录的结果发送给客户端接收。
评分细则
- 能开发出客户端,并成功发送注册信息给服务端接收 4
- 服务端能接收注册信息,并成功写出去到属性文件中去 9
- 客户端能正确收到服务端响应的注册信息。 2
- 客户端能成功发出登录信息,服务端能成功收到 3
- 服务端能正确认证登录是否成功 4
- 客户端能收到登录后的结果。 2
package com.wuxuan.Exams.End;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private Socket socket;
Scanner sc = new Scanner(System.in);
public static void main(String[] args) {
//1.创建客户端对象
Client client = new Client();
try {
client.start();
} catch (Exception e) {
e.printStackTrace();
}
}
private void start() throws Exception {
socket = new Socket("127.0.0.1",8888);
System.out.println("连接服务端成功~~~");
//1.开发界面
//2.提示功能
while(true){
System.out.println("请您输入操作命令:");
System.out.println("1.注册");
System.out.println("2.登录");
System.out.println("清选择:");
String command = sc.next();
switch (command) {
case "1":
//注册
register();
break;
case "2":
//登录
login();
break;
case "exit":
System.out.println("退出系统");
socket.close();
break;
default:
System.out.println("default...");
}
}
}
private void register() throws Exception {
System.out.println("==================注册===============");
System.out.println("请您输入注册信息");
//1.提示用户输入登录名和密码
System.out.println("登录名称:");
String loginName = sc.next();
System.out.println("登录密码:");
String passWord = sc.next();
//2.发送登录名和密码给服务端保存
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeInt(1);//注册
dos.writeUTF(loginName);
dos.writeUTF(passWord);
dos.flush();
//3.马上接收服务端响应
DataInputStream dis = new DataInputStream(socket.getInputStream());
//这里会等待服务端响应
System.out.println(dis.readUTF());
}
private void login() throws Exception{
System.out.println("==================登录===============");
System.out.println("请您输入登录信息");
System.out.println("登录名称:");
String loginName = sc.next();
System.out.println("登录密码:");
String passWord = sc.next();
//2.发送登录名和密码给服务端保存
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeInt(2);//登录
dos.writeUTF(loginName);
dos.writeUTF(passWord);
dos.flush();
//3.马上接收服务端响应
DataInputStream dis = new DataInputStream(socket.getInputStream());
//这里会等待服务端响应
System.out.println(dis.readUTF());
}
}
package com.wuxuan.Exams.End;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static final String USERS_FILE_PATH = "Basic\\src\\users.properties";
public static void main(String[] args) {
try {
//1.注册端口
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
//2.开始接收客户端的管道连接
Socket socket = serverSocket.accept();
//3.分配一个独立的线程来处理客户端的socket
new ServerReaderThread(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
package com.wuxuan.Exams.End;
import java.io.*;
import java.net.Socket;
import java.util.Properties;
public class ServerReaderThread extends Thread {
private Socket socket;
public ServerReaderThread(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
//1.处理的信息:注册 登录
try {
//1.得到输入流
DataInputStream dis = new DataInputStream(socket.getInputStream());
while (true) {
//2.消息类型
int type = dis.readInt();
//3.区别消息,不同处理
switch (type) {
case 1:
//注册
register();
break;
case 2:
//登录
login();
break;
default:
System.out.println("default...");
break;
}
}
} catch (Exception e) {
//离线逻辑
e.printStackTrace();
}
}
private void register() throws Exception {
DataInputStream dis = new DataInputStream(socket.getInputStream());
String loginName = dis.readUTF();
String password = dis.readUTF();
//开始做判断,登录名是否重复的问题
String result = "注册成功";
if(exist(loginName)) {
result = "注册失败,您注册的登录名称已被占用!";
}else{
//保存登录名和密码
Properties prop = new Properties();
prop.setProperty(loginName, password);
prop.store(new FileWriter(Server.USERS_FILE_PATH,true),"");
}
//响应结果回去
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(result);
dos.flush();
}
private void login() throws Exception {
DataInputStream dis = new DataInputStream(socket.getInputStream());
String loginName = dis.readUTF();
String password = dis.readUTF();
String result = "登录成功";
File file = new File(Server.USERS_FILE_PATH);
if(file.exists()){
//提取全部的用户名和密码
Properties prop = new Properties();
prop.load(new FileReader(Server.USERS_FILE_PATH));
if(prop.size() > 0){
//校验登录名称:根据登录名获取密码
String OKpwd = prop.getProperty(loginName);
if(OKpwd == null){
result = "登录名称错误";
}else{
//比较密码
if(!OKpwd.equals(password)){
result = "密码错误!";
}
}
} else{
result = "当前无任何用户信息,无法登录!";
}
}else{
result = "当前无任何用户信息,无法登录!";
}
//响应结果回去
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
dos.writeUTF(result);
dos.flush();
}
private boolean exist(String loginName) throws Exception {
File file = new File(Server.USERS_FILE_PATH);
if(file.exists()){
//提取全部的用户名和密码
Properties prop = new Properties();
prop.load(new FileReader(Server.USERS_FILE_PATH));
if(prop.containsKey(loginName)){
return true;
}
}
return false;
}
}
第六题 (16)
需求
- 在素材demo6包下,有生成链表的代码,目前Test类中已经为您创建了两个链表,分别是链表 head1 -> 2 → 4 → 1,链表head2 → 4→ 1 → 3 。
具体功能点如下
1、在MyLinkedList类中,开发一个sort方法,支持对链表进行升序排序,写完后需要分别测试对这两个链表排序,并分别遍历输出。
2、在MyLinkedList类中,开发一个mergeSort方法,支持将这两个升序排序的链表,再次合并成一个新链表,要求新链表中的节点仍然是递增排序的。
示例1:
输入:head1 -> 2 → 4 → 1, head2 → 4 → 1 → 3
返回:head3 -> 1->1->2->3->4->4
评分细则
能正确排序并遍历链表:6分
能合并并排序:10分
package com.wuxuan.Exams.End.Problem6;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MyLinkedList<E extends Comparable> {
// 封装一个链表
Node<E> head = null;
/**
* 定义了一个私有的内部类,作为链表的结点。
*/
public static class Node<E> {
E data;
Node<E> next;
public Node(E data, Node<E> next) {
this.data = data;
this.next = next;
}
}
public Node<E> add(E e) {
if (head == null) {
head = new Node(e, null);
} else {
// 往后面插入结点。(尾插法)
Node<E> temp = head;
// 让temp走到尾部结点
while (temp.next != null) {
temp = temp.next;
}
// 把当前结点创建出来,加入到尾部结点
temp.next = new Node(e, null);
}
return head;
}
public Node<E> sorted(){
if(head == null){
return head;
}
List<E> number = new ArrayList<>();
Node<E> temp = head;
while(temp != null){
number.add(temp.data);
temp = temp.next;
}
Collections.sort(number);
Node<E> temp2 = head;
for (E e : number) {
temp2.data = e;
temp2 = temp2.next;
}
return head;
}
public void forEach(Node<E> node){
if(head == null){
System.out.println(head);
return;
}
Node<E> temp = head;
while(temp != null){
System.out.print(temp.data + " ");
temp = temp.next;
}
System.out.println();
}
public Node<E> mergeSort(Node<E> head2){
if(head == null && head2 == null){
return null;
}
if(head == null && head2 != null){
return head2;
}
if(head != null && head2 == null){
return head;
}
if(head != null && head2 != null){
Node<E> temp = head;
while(temp.next != null){
temp = temp.next;
}
//此时temp.next == null
temp.next = head2;
sorted();
}
return head;
}
}
package com.wuxuan.Exams.End.Problem6;
public class Test {
public static void main(String[] args) {
// 第一个链表:
MyLinkedList<Integer> list1 = new MyLinkedList<>();
list1.add(2);
list1.add(4);
list1.add(1);
// 第一个链表的头结点:head1
MyLinkedList.Node<Integer> head1 = list1.head;
// 第二个链表:
MyLinkedList<Integer> list2 = new MyLinkedList<>();
list2.add(4);
list2.add(1);
list2.add(3);
// 第二个链表的头结点:head1
MyLinkedList.Node<Integer> head2 = list2.head;
// 功能1:在MyLinkedList类中,开发一个sort方法,对两个链表分别排序,并分别遍历输出
MyLinkedList.Node<Integer> first1 = list1.sorted();
MyLinkedList.Node<Integer> first2 = list2.sorted();
list1.forEach(first1);
list2.forEach(first2);
// 功能2:在MyLinkedList类中,开发一个mergeSort方法,支持将这两个升序排序的链表,合并成一个新链表,要求新链表中的节点仍然是递增排序的。
// ,然后对新链表遍历输出
MyLinkedList.Node<Integer> allFirstHead = list1.mergeSort(first2);
list1.forEach(allFirstHead);
}
}