Stack과 Queue는 LinkedList를 이용해서 사용할 수 있다.
(Stack은 Stack이라는 클래스가 별도로 존재한다.)
Stack의 명령
1. 자료 입력 : push(입력데이터)
2. 자료 출력 :
pop() ==> 자료를 꺼내온 후 꺼내온 자료를 Stack에서 삭제한다. //실제 꺼내올 때 사용
peek() ==> 삭제없이 자료를 꺼내온다. //어떤 데이터가 있는지 검사(확인)할 때 사용
Stack<String> stack = new Stack<>();
LinkedList<String> stack2 = new LinkedList<>();
stack.push("홍길동");
stack.push("일지매");
stack.push("변학도");
stack.push("강감찬");
System.out.println("stack => " + stack);
String data = stack.pop();
System.out.println("꺼내온 값 : " + data); //변수에 저장해서 꺼내옴
System.out.println("꺼내온 값 : " + stack.pop()); //바로 꺼내옴
System.out.println("stack => " + stack);
stack.push("성춘향");
System.out.println("stack => " + stack);
System.out.println();
System.out.println("꺼내온 값 : " + stack.pop());
System.out.println("stack => " + stack);
System.out.println();
System.out.println("삭제 없이 꺼내온 값 : " + stack.peek());
System.out.println("stack => " + stack);
System.out.println();
System.out.println("------------------------------------------");
Queue의 명령
1. 자료 입력 : offer(입력데이터)
2. 자료 출력 :
poll() ==> 자료를 꺼내오고 그 자료를 Queue에서 삭제한다.
peek() ==> 삭제없이 자료를 꺼내온다.
LinkedList는 Queue 인터페이스를 구현한 List클래스이다.
Queue queue = new LinkedList<>();//Queue는 인터페이스 - 객체생성 안 됨. LinkedList로 생성
queue.offer("홍길동");
queue.offer("일지매");
queue.offer("변학도");
queue.offer("강감찬");
System.out.println("queue ==> " + queue);
String temp = queue.poll();
System.out.println("꺼내온 데이터 : " + temp);
System.out.println("꺼내온 데이터 : " + queue.poll());
System.out.println("queue ==> " + queue);
System.out.println();
queue.offer("성춘향");
System.out.println("queue ==> " + queue);
System.out.println();
System.out.println("꺼내온 데이터 : " + queue.poll());
System.out.println("queue ==> " + queue);
System.out.println();
System.out.println("삭제없이 꺼내오기 : " + queue.peek());
System.out.println("queue ==> " + queue);
System.out.println();
Stack은 꺼내올 때 pop(), 입력할 때 push()
Queue는 꺼내올 때 poll(), 입력할 때 offer()
둘 다 모두 어떤 값이 있는지 확인할 때는 peek()
public class StackTest {
public static void main(String[] args) {
Browser b = new Browser();
b.goURL("1. 네이버");
b.goURL("2. 야후");
b.goURL("3. 구글");
b.goURL("4. 다음");
b.history();
System.out.println("뒤로가기 후...");
b.goBack();
b.history();
System.out.println("뒤로가기 후...");
b.goBack();
b.history();
System.out.println("앞으로가기 후...");
b.goForward();
b.history();
System.out.println("새로운 사이트 방문 후...");
b.goURL("5. 네이트");
b.history();
}
}
//웹브라우저의 앞으로가기, 뒤로가기 기능 구현(스택 이용)
class Browser{
//앞으로가기 데이터가 저장될 주소
private Stack<String> back; //이전 방문 내역이 저장된 스택
private Stack<String> forward; //다음 방문 내역이 저장될 스택
private String currentURL; //현재 페이지
//생성자
public Browser() {
back = new Stack<>();
forward = new Stack<>();
currentURL = "";
}
//사이트를 방문하는 메서드 ==> 매개변수에는 방문할 URL이 저장된다.
public void goURL(String url) {
System.out.println(url + " 사이트에 접속합니다.");
//현재 페이지가 있으면...
if(currentURL != null && !"".equals(currentURL)) {
back.push(currentURL); //현재 페이지를 back 스택에 추가한다.
}
currentURL = url; //현재 페이지를 변경한다.
forward.clear(); //forward 스택 데이터 전체 삭제
}
//뒤로 가기
public void goBack() {
//isEmpty() ==> Stack이 비어있으면 true, 그렇지 않으면 false
if(!back.isEmpty()){//비어있지 않으면 동작
forward.push(currentURL); //현재 페이지를 forward 스택에 추가한다.
currentURL = back.pop(); //back에서 1개의 요소를 꺼내와 현재 페이지로 한다.
}
}
//앞으로 가기
public void goForward() {
if(!forward.isEmpty()) {
back.push(currentURL); //현재 페이지를 back 스택에 추가한다.
currentURL = forward.pop(); //forward에서 1개의 요소를 꺼내와 현재 페이지로 한다.
}
}
//방문 기록 확인하기
public void history() {
System.out.println("---------------------------------");
System.out.println(" 방 문 기 록 ");
System.out.println("---------------------------------");
System.out.println(" back ==> " + back);
System.out.println(" 현재 ==> " + currentURL);
System.out.println(" forward ==> " + forward);
System.out.println("---------------------------------");
}
}
정렬과 관련된 interface는 Comparable, Comparator 이렇게 두 가지가 있다.
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("일지매");
list.add("홍길동");
list.add("성춘향");
list.add("변학도");
list.add("이순신");
System.out.println("정렬전 : " + list);
//정렬은 Collections.sort()메서드를 이용하여 정렬한다.
//Collections.sort()메서드는 기본적으로 내부 정렬 기준으로 정렬한다.
//내부 정렬 기준
// ==> Collection에 추가되는 데이터 자체에 구성된 정렬 기준 (지금은 String의 내부 정렬기준)
// ==> 기본적인 자료형의 내부 정렬 기준은 오름차순으로 정렬되도록 만들어져 있다.
Collections.sort(list);
System.out.println("정렬후 : " + list); //가나다순으로 정렬됨
Collections.shuffle(list); //자료 섞기
System.out.println("자료 섞기 후 : " + list);
//외부 정렬 기준을 사용해서 정렬하기
Collections.sort(list, new Desc()); //정렬기준 객체를 생성해서 넣어주기
System.out.println("내림차순 정렬 후 : " + list);
}
}
// 정렬 방식을 정해주는 class만들기 (외부 정렬기준 class 만들기)
class Desc implements Comparator<String>{ //인터페이스에 선언된 메서드를 구현해야 함.
/*
compare메서드의 반환값
- 반환값이 0 ==> 두 값이 같다.
- 반환값이 양수 ==> 두 값의 순서를 바꾼다.
- 반환값이 음수 ==> 두 값의 순서를 바꾸지 않는다.
예) 오름차순일 경우
==> 앞의 값이 크면 양수, 같으면 0, 뒤의 값이 크면 음수가 반환되도록 구현한다.
*/
@Override
public int compare(String str1, String str2) { //반환값이 int - 순서를 바꿀지 그대로 둘지 정하는 것
//내림차순으로 구현하려고 한다.
// if(str1.compareTo(str2) > 0) { //앞이 크고 뒤가 작다.
// return -1;
// }else if(str1.compareTo(str2) < 0){
// return 1;
// }else {
// return 0;
// }
return str1.compareTo(str2) * -1; //오름차순의 부호를 반대로 : -1을 곱함.
}
public class ListSortTest02 {
public static void main(String[] args) {
ArrayList<Member> memList = new ArrayList<>();
memList.add(new Member(1, "홍길동", "010-1111-1111"));
memList.add(new Member(5, "이순신", "010-2222-1111"));
memList.add(new Member(9, "성춘향", "010-3333-1111"));
memList.add(new Member(3, "강감찬", "010-4444-1111"));
memList.add(new Member(6, "일지매", "010-5555-1111"));
memList.add(new Member(2, "변학도", "010-6666-1111"));
System.out.println("정렬전...");
for(Member mem : memList) {
System.out.println(mem);
}
System.out.println("---------------------------------------------");
//회원이름을 기준으로 오름차순 - 내부정렬기준
Collections.sort(memList); //내부 정렬 기준이 없을 때 정렬 불가(오류)
// - 정렬하고 싶으면 comparable이라는 인터페이스도 같이 구현해줘야 함.
// - 내부 정렬 기준은 한 가지 기준으로밖에 정렬할 수 없음.
System.out.println("정렬후...(내부정렬기준 - 회원이름을 기준으로 오름차순)");
for(Member mem : memList) {
System.out.println(mem);
}
System.out.println("---------------------------------------------");
//회원번호의 내림차순을 정렬하기
Collections.sort(memList, new SortNumDesc());
System.out.println("회원번호의 내림차순 정렬후...");
for(Member mem : memList) {
System.out.println(mem);
}
System.out.println("---------------------------------------------");
}
}
//Member클래스의 회원이름을 기준으로 오름차순 정렬이 되도록
//내부 정렬 기준 추가하기 => Comparable 인터페이스를 구현한다.
class Member implements Comparable<Member>{
private int num; //회원번호
private String name; //이름
private String tel; //전화번호
public Member(int num, String name, String tel) {
this.num = num;
this.name = name;
this.tel = tel;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
@Override
public String toString() {
return "Member [num=" + num + ", name=" + name + ", tel=" + tel + "]";
}
//내부 정렬 기준을 설정하는 메서드 구현하기
//(회원이름의 오름차순 기준 설정)
@Override
public int compareTo(Member mem) { //매개변수가 하나 - this(현재 Member클래스)와 mem(다른 Member클래스)과 비교
return this.getName().compareTo(mem.getName()); //this가 현재 값, mem.getName이 매개변수에서 온 값.
//이름 - String 타입이면 compareTo()라는 메서드를 쓸 수 있다.
}
}
// Member 클래스의 회원번호(num)를 기준으로 내림차순되는
// 외부정렬기준 class를 작성하시오.
class SortNumDesc implements Comparator{
@Override
public int compare(Member mem1, Member mem2) { //숫자형이기 때문에 비교연산자로 바로 비교할 수 있음
// if(mem1.getNum() > mem2.getNum()) { //앞이 크고 뒤가 작으면 => 바꾸지 않는다(음수)
// return -1;
// }else if(mem1.getNum() < mem2.getNum()){ //앞이 작고 뒤가 크면 => 바꾼다(양수)
// return 1;
// }else {
// return 0;
// }
//Wrapper클래스를 이용하는 방법1
// return new Integer(mem1.getNum()).compareTo(mem2.getNum()) * -1; //if문 쓰지 않아도 가능
//기본적으로 오름차순이기 때문에 반대로 하려면 부호를 반대로 하면 됨.
//Wrapper클래스를 이용하는 방법1
return Integer.compare(mem1.getNum(), mem2.getNum()) * -1; //위와 같은 의미, 같은 결과.
//compare가 static메서드. 오름차순 기준으로 반환값을 만들어줌.
}
}
문제) 학번(int), 이름(String), 국어점수, 영어점수, 수학점수, 총점, 등수를 멤버로 갖는 Student클래스를 만든다.
- 이름만 String, 나머지는 다 int
이 클래스의 생성자에서는 학번, 이름, 국어점수, 영어점수, 수학점수만 매개변수로 받아서 초기화 처리를 한다.
이 Student 객체는 List에 저장하여 관리한다. - memList처럼
List에 저장된 데이터(Student)는 학번의 오름차순으로 정렬할 수 있는 내부 정렬 기준을 구현한다.
그리고, 총점의 역순으로 정렬하는데 총점이 같으면 이름의 오름차순으로 정렬이 될 수 있는 외부 정렬 기준 클래스를 작성한다.
위 정렬 기준에 맞춰 정렬되는 프로그램을 작성하시오.
(단, 등수는 List에 전체 데이터가 추가된 후에 저장되도록 한다.)
내가 푼 답:
public class StudentTest {
public static void main(String[] args) {
//학생
ArrayList<Student> students = new ArrayList<>();
students.add(new Student(5, "홍길동", 50, 40, 60));
students.add(new Student(9, "김씨", 80, 10, 20));
students.add(new Student(8, "변학도", 20, 90, 60));
students.add(new Student(10, "이순신", 60, 50, 60));
students.add(new Student(7, "천재", 80, 50, 90));
for(Student student : students) {
System.out.println(student);
}
Collections.sort(students);
System.out.println("학번으로 정렬 후 : ");
for(Student student : students) {
System.out.println(student);
}
Collections.sort(students, new DescStudent());
System.out.println("총점으로 정렬 후(내림차순) : ");
for(int i = 0; i < students.size(); i++) {
System.out.println(students.get(i));
students.get(i).setRank(i+1);
}
System.out.println("순위부여 : ");
for(Student student : students) {
System.out.println(student);
}
}
}
class Student implements Comparable{
//멤버변수
int studentNo;
String name;
int korean;
int english;
int math;
@Override
public String toString() {
return "Student [studentNo=" + studentNo + ", name=" + name + ", korean=" + korean + ",
english=" + english + ", math=" + math + ", sum=" + sum + ", rank=" + rank + "]";
}
//학번을 가져오는
public int getStudentNo() {
return studentNo;
}
public void setStudentNo(int studentNo) {
this.studentNo = studentNo;
}
//총점을 가져오는
public int getSum() {
return sum;
}
public int getRank() {
return rank;
}
public void setRank(int rank) {
this.rank = rank;
}
public void setSum(int sum) {
this.sum = sum;
}
int sum;
int rank;
//생성자 초기화
public Student(int studentNo, String name, int korean, int english, int math) {
super();
this.studentNo = studentNo;
this.name = name;
this.korean = korean;
this.english = english;
this.math = math;
this.sum = korean + english + math;
}
//내부 정렬 기준 - 학번을 기준으로 오름차순
@Override
public int compareTo(Student s) {
return Integer.compare(this.getStudentNo(), s.getStudentNo());
}
}
//총점을 기준으로 내림차순 정렬
class DescStudent implements Comparator{
@Override
public int compare(Student s1, Student s2) {
return Integer.compare(s1.getSum(), s2.getSum()) * -1;
}
}
단축키
Ctrl + Shift + s 에서
get, set / toString / 생성자초기화 할 수 있음