기말고사 담당교수 : 단국대학교응용컴퓨터공학박경신 답은반드시답안지에기술할것. 공간이부족할경우반드시답안지몇쪽의뒤에있다고명기한 후기술할것. 그외의경우의답안지뒤쪽이나연습지에기술한내용은답안으로인정안함. 답 에는반드시네모를쳐서확실히표시할것. 답안지에학과, 학번, 이름외에본인의암호 (4 자리숫자 ) 를기입하면성적공고시학번대신암호를 사용할것임. // ArithmeticOperator public enum ArithmeticOperator { PLUS, MINUS, TIMES, DIVIDE, REMAINDER, POWER; public int calculate(int x, int y) { // (1) switch (this) { case PLUS: return x + y; case MINUS: return x - y; case TIMES: return x * y; case DIVIDE: return x / y; case REMAINDER: return x % y; case POWER: return (int)math.pow(x, y); default: throw new AssertionError("Unknown operations " + this); public String getoperator() { // (1) switch (this) { case PLUS: return "+"; case MINUS: return "-"; case TIMES: return "*"; case DIVIDE: return "/"; case REMAINDER: return "%"; case POWER: return "^"; default: throw new AssertionError("Unknown operations " + this); public static ArithmeticOperator valueof(int value) { // (1) switch (value) { // switch case 0: return PLUS; case 1: return MINUS; case 2: return TIMES; case 3: return DIVIDE; case 4: return REMAINDER; case 5: return POWER; return null; public static String[] names() { // (1) return new String[] {"+", "-", "*", "/", "%", "^"; 1/10
public static ArithmeticOperator nameof(string name) { // (1) switch (name) { // switch case "+": return PLUS; case "-": return MINUS; case "*": return TIMES; case "/": return DIVIDE; case "%": return REMAINDER; case "^": return POWER; return null; // Value import java.util.*; public class Value implements Comparable<Value> { // (3) protected int a; protected int b; public Value() { this(0, 0); public Value(int[] value) { this(value[0], value[1]); public Value(int a, int b) { set(a, b); public void set(int a, int b) { // (2) this.a = a; this.b = b; public int geta() { return this.a; public int getb() { return this.b; public void seta(int a) { this.a = a; public void setb(int b) { this.b = b; public String tostring() { // (2) return a + "," + b; public int compareto(value other) { // (4) return Integer.compare(this.a, other.geta()); public static Comparator<Value> BComparator = new Comparator<Value>() { public int compare(value v1, Value v2) { // (4) return Integer.compare(v1.getB(), v2.getb()); ; 2/10
// ValueCalculator public class ValueCalculator extends Value { // (3) protected ArithmeticOperator op; protected int c; public ValueCalculator() { this(0, 0, ArithmeticOperator.PLUS); public ValueCalculator(int a, int b, ArithmeticOperator op) { set(a, b, op); public ValueCalculator(int a, int b, ArithmeticOperator op, int c) { super(a, b); this.op = op; this.c = c; public void set(int a, int b, ArithmeticOperator op) { // (2) this.a = a; this.b = b; this.op = op; this.c = op.calculate(a, b); public ArithmeticOperator getop() { return op; public int getc() { return c; public String tostring() { // (2) return this.a + "," + this.b + "," + this.op + "," + this.c; // ValueCalculatorComparator import java.util.*; public class ValueCalculatorComparator implements Comparator<ValueCalculator> { // (4) private int column = 0; public ValueCalculatorComparator() { this(0); public ValueCalculatorComparator(int column) { this.column = column; public int compare(valuecalculator c1, ValueCalculator c2) { if (!(c1 instanceof ValueCalculator)!(c2 instanceof ValueCalculator)) return 0; switch(this.column) { case 0: return Integer.compare(c1.getA(), c2.geta()); case 1: return Integer.compare(c1.getB(), c2.getb()); case 2: return c1.getop().compareto(c2.getop()); case 3: return Integer.compare(c1.getC(), c2.getc()); default: return 0; 3/10
// Utility public class Utility { public static int tryparseint(string str) { // (5) String -> int int val = 0; try { val = Integer.parseInt(str); catch (NumberFormatException e) { e.printstacktrace(); return val; // ValueImporter import java.io.*; import java.util.*; public class ValueImporter { public static List<Value> loadcsv(string filename) { List<Value> valuelist = new ArrayList<Value>(); try { BufferedReader in = new BufferedReader(new FileReader(filename)); //(6) String line; String delimiter = ","; while ((line = in.readline())!= null) { String[] items = line.split(delimiter); int a = Utility.tryParseInt(items[0]); // (5) int b = Utility.tryParseInt(items[1]); // (5) Value v = new Value(a, b); valuelist.add(v); in.close(); catch (IOException e) { e.printstacktrace(); System.exit(1); catch (Exception e) { e.printstacktrace(); return valuelist; public static void writecsv(string path, List<Value> valuelist) { FileWriter fw; // (6) try { fw = new FileWriter(path); for (Value v : valuelist) { fw.append(v.tostring() + "\n"); fw.flush(); fw.close(); catch (IOException e) { e.printstacktrace(); 4/10
// ValueCalculatorManager import java.util.*; import java.util.function.predicate; import java.util.stream.collectors; public class ValueCalculatorManager { private List<ValueCalculator> list = null; public ValueCalculatorManager() { this.list = new ArrayList<ValueCalculator>(); public ValueCalculatorManager(List<ValueCalculator> list) { this.list = list; public void add(valuecalculator value) { this.list.add(value); public int size() { return this.list.size(); public boolean isempty() { return this.list.isempty(); public ValueCalculator getat(int index) { return this.list.get(index); public void sort(int index) { this.list.sort(new ValueCalculatorComparator(index)); public String tostring() { return java.util.arrays.tostring(this.list.toarray()); public void load(string filename) { // (7) List<Value> vlist = ValueImporter.loadCSV(filename); for (Value v : vlist) { for (ArithmeticOperator op : ArithmeticOperator.values()) { add(new ValueCalculator(v.getA(), v.getb(), op)); // ValueCalculatorTableModel package ValueFrame; import javax.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.table.*; import ValueLib.ValueCalculator; import ValueLib.ValueCalculatorManager; public class ValueCalculatorTableModel extends AbstractTableModel { private ValueCalculatorManager manager; private String[] columnnames = { "A", "B", "OP", "C"; public ValueCalculatorTableModel(ValueCalculatorManager manager) { this.manager = manager; public int getrowcount() { return this.manager.size(); 5/10
public int getcolumncount() { return columnnames.length; public String getcolumnname(int columnindex) { return columnnames[columnindex]; public Class<?> getcolumnclass(int columnindex) { if (this.manager.isempty()) { return Object.class; return getvalueat(0, columnindex).getclass(); public Object getvalueat(int rowindex, int columnindex) { ValueCalculator calc = this.manager.getat(rowindex); Object value = null; switch (columnindex) { case 0: value = calc.geta(); break; case 1: value = calc.getb(); break; case 2: value = calc.getop().getoperator(); break; case 3: value = calc.getc(); break; return value; public void addrow(valuecalculator v) { this.manager.add(v); firetablerowsinserted(this.manager.size() - 1, this.manager.size() - 1); class ColumnListener extends MouseAdapter { private JTable table; public ColumnListener(JTable table) { this.table = table; public void mouseclicked(mouseevent e) { TableColumnModel colmodel = table.getcolumnmodel(); int columnmodelindex = colmodel.getcolumnindexatx(e.getx()); int modelindex = colmodel.getcolumn(columnmodelindex).getmodelindex(); if (modelindex < 0) return; for (int i = 0; i < getcolumncount(); i++) { TableColumn column = colmodel.getcolumn(i); column.setheadervalue(getcolumnname(column.getmodelindex())); table.gettableheader().repaint(); manager.sort(columnmodelindex); table.tablechanged(new TableModelEvent(ValueCalculatorTableModel.this)); table.repaint(); 6/10
// ValueCalculatorTableFrame package ValueFrame; import javax.swing.*; import java.awt.*; import javax.swing.table.*; import ValueLib.ValueCalculator; import ValueLib.ValueCalculatorManager; public class ValueCalculatorTableFrame extends JFrame { public ValueCalculatorTableModel model = null; public ValueCalculatorTableFrame(ValueCalculatorManager manager) { super("valuecalculatortableframe"); this.model = new ValueCalculatorTableModel(manager); JTable table = new JTable(this.model); table.setselectionmode(listselectionmodel.single_selection); table.setintercellspacing(new Dimension(10, 5)); JTableHeader header = table.gettableheader(); header.setupdatetableinrealtime(true); header.addmouselistener(model.new ColumnListener(table)); // (8) header.setreorderingallowed(true); JScrollPane scrollpane = new JScrollPane(table); this.add(scrollpane, BorderLayout.CENTER); this.setsize(600, 600); this.setvisible(true); this.setdefaultcloseoperation(jframe.exit_on_close); // ValueCalculatorFrame package ValueFrame; import java.awt.event.*; import javax.swing.*; import ValueLib.ArithmeticOperator; import ValueLib.Utility; import ValueLib.ValueCalculator; public class ValueCalculatorFrame extends JFrame implements ActionListener { JLabel label1 = new JLabel("A"); JLabel label2 = new JLabel("B"); JLabel label3 = new JLabel(" 연산자 "); JTextField textfield1 = new JTextField(20); JTextField textfield2 = new JTextField(20); JComboBox<String> combobox1 = new JComboBox<String>(ArithmeticOperator.names()); //(9) JButton button1 = new JButton(" 계산 "); ValueCalculatorTableFrame tableframe = null; public ValueCalculatorFrame(ValueCalculatorTableFrame tableframe) { settitle("valuecalculatorframe"); setlayout(null); // no layout this.tableframe = tableframe; label1.setbounds(20, 30, 100, 20); label2.setbounds(20, 60, 100, 20); label3.setbounds(20, 90, 100, 20); this.add(label1); this.add(label2); this.add(label3); textfield1.setbounds(120, 30, 150, 20); textfield2.setbounds(120, 60, 150, 20); this.add(textfield1); this.add(textfield2); combobox1.setbounds(120, 90, 150, 20); this.add(combobox1); button1.setbounds(60, 120, 160, 20); button1.addactionlistener(this); // (9) 7/10
this.add(button1); setsize(300, 200); this.setvisible(true); this.setdefaultcloseoperation(jframe.exit_on_close); public ArithmeticOperator select() { return ArithmeticOperator.valueOf(combobox1.getSelectedIndex()); // (9) public void actionperformed(actionevent e) { if ((JButton)e.getSource() == button1) { ValueCalculator calc = new ValueCalculator(); int a = Utility.tryParseInt(textfield1.getText()); // (9) int b = Utility.tryParseInt(textfield2.getText()); // (9) ArithmeticOperator op = select(); calc.set(a, b, op); tableframe.model.addrow(calc); valuelist.csv 10,6 8,4 9,2 // MainFrame package ValueFrame; // (10) 7,5 import ValueLib.ValueCalculatorManager; // (10) public class MainFrame { 8,3 public static void main(string args[]) { ValueCalculatorManager manager = new ValueCalculatorManager(); manager.load("valuelist.csv"); // (7) ValueCalculatorTableFrame tableframe = new ValueCalculatorTableFrame(manager); new ValueCalculatorFrame(tableFrame); 8/10
1. ArithmeticOperator 코드의빈칸을채워라. (10 점 ) 2. Method Overloading 과 Method Overriding 이무엇인지자세히설명하라. Value 와 ValueCalculator 클래스에서예시를찾아서적어라. (10 점 ) 메소드오버로딩은동일한메소드이름에매개변수가다른함수를둘이상정의하는것으로, 동일한함수기능을수행하지만다른매개변수의경우를처리할때사용예로, Value 클래스 void set(int, int) 와 ValueCalculator 클래스 void set(int, int, ArithmeticOperator) 메소드오버라이딩은상속관계에서상속받은파생클래스에서동일한메소드이름에동일한매개변수와반환자로정의하여함수를재정의하는것으로상속되어진함수의기능을변경해서재사용하고싶을때사용예로, Value 클래스와 ValueCalculator 클래스의 String tostring() 메소드는 Object 클래스의 tostring() 를재정의해서사용 3. implements 와 extends 가무엇인지예를들어자세히설명하라. (5 점 ) class Value implements Comparable<Value> 는 Comparable 인터페이스를상속받아서해당인터페이스의메소드즉 int compareto(value) 를구현하는것이다. class ValueCalculator extends Value 는 ValueCalculator 클래스가 Value 클래스를상속받아서확장한다는것이다. 즉, Value 클래스의 protected 와 public 필드와메소드를상속받아서사용가능하고추가적인메소드를더구현하는것이다. 4. Value 클래스와 ValueCalculatorComparator 클래스코드의빈칸을채워라. (15 점 ) 5. Utility 클래스의 int tryparseint(string) 메소드를 try/catch 를사용하여구현하라. (5 점 ) 6. ValueImporter 클래스에서사용한 FileReader, FileWriter, BufferedReader 클래스를설명하라. (5 점 ) FileReader 와 FileWriter 클래스는문자데이터파일을읽고처리하는클래스이다. BufferedReader 는문자데이터파일을읽고처리하는버퍼스트림클래스이다. 버퍼를가진입출력클래스들은입출력데이터를일시적으로저장하는버퍼를이용하여입출력효율을높이려고한다. 7. ValueCalculatorManager 클래스 void load(string) 메소드의동작원리를설명하라. (10 점 ) MainFrame 클래스의메인메소드에서 manager.load( valuelist.csv ) 에서호출 ValueImporter.loadCSV 를이용하여, 파일을읽어들여 List<Value> vlist 로받는다. 중첩 foreach 즉, vlist 에있는모든 Value 와모든 ArithmeticOperator 마다 ValueCalculator 연산을한다. 그리고, 그 ValueCalculator 를 List<ValueCalculator> 에 add 한다. 9/10
8. ValueCalculatorTableFrame 클래스에서사용한 addmouselistener 메소드의동작원리를설명하라. 만약이메소드를호출하지않았을경우 ( 즉, comment out 했을시 ) 실행결과가어떻게바뀌는지자세히설명하라. (10 점 ) addmouselistener 는 MouseListener 이벤트핸들러메소드를등록하는것으로 ValueCalculatorTableModel 클래스의내부클래스인 ColumnListener 클래스에 mouseclicked(mouseevent e) 를구현하였다. 만약 addmouselistener 를 comment out 해서호출하지않았을경우, 테이블컬럼헤더를마우스로클릭해도, 그해당컬럼 ( 즉, A, B, OP, C) 으로 sort 가되지않게된다. 9. ValueCalculatorFrame 클래스코드의빈칸을채워라. (10 점 ) 10. package 와 import 가무엇인지예를들어자세히설명하라. (10 점 ) Package 는서로관련된클래스와인터페이스등을하나의디렉토리에묶어놓은것하나의응용프로그램은여러개의패키지로작성가능하다. 예를들어, ValueLib 패키지에는 ArithmeticOperator, Value, ValueCalculator, ValueCalculatorComparator, Utility, ValueImporter, ValueCalculatorManager 를묶었고, ValueFrame 패키지에는 ValueCalculatorTableModel, ValueCalculatorTableFrame, ValueCalculatorFrame, MainFrame 을묶어서사용하였다. Import 는외부클래스를사용하여구현할때, 해당클래스가속해있는절대경로명 ( 즉, 패키지명과클래스이름또는패키지명.*) 을호출해야사용가능하다. Import 를사용하여소스의시작부분에사용하려는클래스의패키지를명시함. 11. 이응용프로그램의동작원리 ( 즉, 실행결과 ) 를자세히설명하라. (10 점 ) 이응용프로그램은 MainFrame 클래스의메인메소드에서 manager.load( valuelist.csv ) 에서호출하여 5 개의 Value 에대한 6 개의 ArithmeticOperator 연산을한 ValueCalculator 값이테이블 (ValueCalculatorTableFrame) 에출력된다. 테이블의컬럼헤더를마우스로클릭하면, 해당컬럼헤더의값으로 sort 가된다. 그리고, ValueCalculatorFrame 에서는 A, B 에텍스트로값을입력하고콤보박스에서 Operator 를선택하여 계산 버튼을누르면, ValueCalculator 연산한값이테이블에추가된다. - 끝 - 10/10