我有一个称为会话的抽象类。讲座和教程扩展了会议。然后,我有一个称为注册的类,其中包含一个会话列表(讲座和教程)。如何在“注册”中的会话列表中循环浏览,并仅从会话列表中返回讲座列表?
我的下一个问题是,我是否应该存储2个列表。一个讲座列表和一个教程列表,而不是一个会话列表?这是因为会话列表对我来说毫无用处,我每次都必须遍历该列表以获取有关讲座和教程的信息。有没有一种我无法获得所有讲座对象的方法?我是Java新手。
public class Enrolment {
private List<Session> sessions;
public Enrolment() {
this.sessions = new ArrayList<>();
}
public addSession(Session session) {
this.sessions.add(session);
}
}
public class Session {
private int time;
public Session(int time) {
this.time = time;
}
}
public class Lecture extends Session {
private String lecturer;
public Lecture(int time, String lecturer) {
super(time);
this.lecturer = lecturer;
}
}
public class Tutorial extends Session {
private String tutor;
private int tutorScore;
public Tutorial(int time, String tutor, int tutorScore) {
super(time);
this.tutor = tutor;
this.tutorScore = tutorScore;
}
}
public class test {
public static void main(String[] args) {
Enrolment newEnrolment = new Enrolment();
Lecture morningLec = new Lecture(900, "Dr. Mike");
newEnrolment.addSession(morningLec);
Tutorial afternoonTut = new Tutorial(1400, "John Smith", 3);
newEnrolment.addSession(afternoonTut);
Lecture middayLec = new Lecture(1200, "Mr. Micheals");
newEnrolment.addSession(middayLec);
Tutorial NightTut = new Tutorial(1900, "Harry Pauls", 4);
newEnrolment.addSession(NightTut);
}
}
答案 0 :(得分:4)
流式传输sessions
列表并使用instanceof
过滤Lectures
类型的对象
List<Lecture> l = sessions.stream()
.filter(Lecture.class::isInstance)
.map(Lecture.class::cast)
.collect(Collectors.toList());
通过使用for
循环为每种类型使用两个不同的列表
List<Lecture> l = new ArrayList<>();
List<Tutorial> t = new ArrayList<>();
for (Session s : sessions) {
if (s instanceof Lecture) {
l.add((Lecture) s);
}
else if(s instanceof Tutorial) {
t.add((Tutorial) s);
}
}
答案 1 :(得分:2)
我的下一个问题是,我是否应该存储2个列表。一个清单 讲座和一个教程列表,而不是一个会话列表?这是 因为会话列表对我没用,我必须遍历 每次获取有关讲课和教程的信息。在那儿 一种我无法获得所有讲座对象的方式?
您回答了自己的问题。
当您开始编写过于复杂的样板代码以使应该变得简单的事情(例如,在刚刚添加的对象列表上进行迭代)时,表明您应该退后一步并重新设计它。
通过引入Enrolment.addSession(Session session)
,
您引入了不良的抽象:
public class Enrolment {
private List<Session> sessions;
public Enrolment() {
this.sessions = new ArrayList<>();
}
public addSession(Session session) {
this.sessions.add(session);
}
}
从Lecture
的角度来看,您不想统一处理Tutorial
和Enrolment
,所以只因为它们不合并在同一List
中它们依赖于相同的接口(Session
)。
在需要时必须使用抽象,而不是系统地使用抽象,因为这是可能的。
您不是将所有对象都添加到“对象列表”中,因为所有对象都是对象吗?否
而不是从API方法及其实现中创建这种区别:
public class Enrolment {
private List<Conference> conferences = new ArrayList<>();
private List<Tutorial> tutorials = new ArrayList<>();
public addConference(Conference conference) {
this.conferences.add(conference);
}
public addTutorial(Tutorial tutorial) {
this.tutorials.add(tutorial);
}
}
并使用它:
Lecture morningLec = new Lecture(900, "Dr. Mike");
newEnrolment.addLecture(morningLec);
Tutorial afternoonTut = new Tutorial(1400, "John Smith", 3);
newEnrolment.addTutorial(afternoonTut);
请注意,您可能会遇到需要对某些处理进行统一处理的Tutorial和Lecture,而对于其他处理则需要对其进行区分的情况。
在这种情况下,您可以使用一些常用方法:
instanceOf
:易于使用,但也易于使代码变脆。例如,稍后您可以在Session层次结构中添加一个新的子类,并且在不知道它的情况下,该子类的实例可以在某些处理中包括或排除,而编译器不会警告您。
提供了一个抽象方法,该方法返回布尔值或枚举来传达对象的性质(例如:isLecture()
)。比instanceOf
更强大,因为编译器限制您重写此方法,但是如果添加了多个子类并且过滤器不仅位于Lecture
上,而且还Lecture
上,则可能导致易于出错的代码和另一种类型。因此,我希望这种方式在过滤条件保持简单的同时。
定义了三个列表:一个用于演讲,另一个用于会议,另一个包含应统一处理的所有列表。更复杂的方法,但也更可靠。我只会在复杂/不断变化的过滤条件的情况下支持它。
答案 2 :(得分:1)
也许您应该将其存储在两个列表中,就像:
{{1}}
是您需要的吗?
答案 3 :(得分:0)
List<Lecture> l = newEnrolment.getSessions()
.stream()
.filter(s-> s.getClass().equals(Lecture.class))
.map(session -> (Lecture) session)
.collect(Collectors.toList());
!!!不要使用 typeof
答案 4 :(得分:0)
引用您的问题
这是因为会话列表对我无用。
因此,这可能不是拥有列表(?)的正确位置。
我的偏好是拥有
public interface Enrolment {
public abstract addSession(Session session);
public abstract getSessions();
}
并且List<LectureEnrolment>
和List<TutorialEnrolment>
必须在各自的类中。(我将Lecture
重命名为LectureEnrolment
,并将Tutorial
重命名为TutorialEnrolment
)
main()
必须具有类似的内容,
Enrolment lectureEnrolment= new LectureEnrolment()
Enrolment tutorialEnrolement = new TutorialEnrolment()
根据需要分别呼叫addSession()
或getSession()
。
答案 5 :(得分:-1)
将private List<Session> sessions;
中的public List<Session> sessions;
更改为class Enrolment
public static void main(String[] args) {
....
var lecturesAndTutorials = newEnrolment.sessions.where(x => x.getType() == typeof(Lecture) || x.getType() == typeof(Tutorial));
....
}