KOSTA 11일차) startsWith / 상품관리프로그램 / equals 재정의 / 반복자 / Map

해버니·2023년 2월 28일
0

KOSTA

목록 보기
8/32
post-thumbnail

startsWith() & endsWith()

대상 문자열이 특정 문자 또는 특정 문자열로 시작하거나 끝나는지에 대해 체크할 수 있는 함수


public static void main(String[] args) {
	String s = "hiddenside";
	System.out.println(s.startsWith("hidden"));	
	System.out.println(s.startsWith("hidden ")); // 띄어쓰기를 넣음 → false
	System.out.println(s.endsWith("side"));

	// true
	// false
	// true
}










🔹 상품 관리 프로그램

메뉴
1. 추가  2.번호로 검색  3.제품명으로 검색  4.수정  5.삭제  6.전체 출력  6.종료
상품
번호(num),  이름(name),  링크(url),  제품 아이디(id),  가격(price),  수량(amount)





package Task_0227;

import java.util.Scanner;

public class Menu {
	private ProductService service;

	public Menu() {
		service = new ProductService();
	}

	public void run(Scanner sc) {
		
		boolean flag = true;
		int input;
		while (flag) {
			System.out.println("1.추가  2.번호로검색  3. 제품명으로검색  4.수정  5.삭제  6.전체출력  7.종료");
			input = sc.nextInt();

			switch (input) {
			case 1:
				service.allInput(sc);
				break;
			case 2:
				service.printProduct(sc);
				break;
			case 3:
				service.searchName(sc);
				//service.printByName(sc);
				break;
			case 4:
				service.modify(sc);
				break;
			case 5:
				service.delete(sc);
				break;
			case 6:
				service.allPrint();
				break;
			case 7:
				System.out.println("서비스 종료.");
				flag = false;
				break;
			default:
				System.out.println("😑 1 ~ 7 사이를 눌러주세요 😑");
			}
		}
	}
}





Product.java

package Task_0227;

public class Product {
	private int num;
	private String name;
	private String url;
	private String id;
	private int price;
	private int amount;

	public Product() {

	}

	public Product(int num, String name, String url, String id, int price, int amount) {
		this.num = num;
		this.name = name;
		this.url = url;
		this.id = id;
		this.price = price;
		this.amount = amount;
	}

	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 getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public int getAmount() {
		return amount;
	}

	public void setAmount(int amount) {
		this.amount = amount;
	}
	
	@Override
	public String toString() {
		return num + " / " + name + " / " + url + " / " + id + " / " + price + " / " + amount;
	}
	
}





ProductMain.java

package Task_0227;

import java.util.Scanner;

public class ProductMain {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		Menu m=new Menu();
		m.run(sc);
	}
}





ProductService.java

package Task_0227;

import java.util.ArrayList;
import java.util.Scanner;

public class ProductService {
	private ArrayList<Product> listProds;
	private ArrayList<Product> searchList;

	public ProductService() {
		listProds = new ArrayList<Product>();
		searchList = new ArrayList<Product>();
		// listProds = new ArrayList<>();
	}

	public void allInput(Scanner sc) { // 1.추가
		Product p = new Product();

		p.setNum(overlap(sc));
		System.out.print("제품명 입력 : ");
		p.setName(sc.next());
		System.out.print("사진경로 입력 : ");
		p.setUrl(sc.next());
		System.out.print("판매자id 입력 : ");
		p.setId(sc.next());
		System.out.print("가격 입력 : ");
		p.setPrice(sc.nextInt());
		System.out.print("수량 : ");
		p.setAmount(sc.nextInt());

		listProds.add(p);
		System.out.println(p);
	}

	public int overlap(Scanner sc) { // 번호 중복 체크
		System.out.print("제품 번호 입력 : ");
		int idx = overlapNumber(sc);
		if (idx == -1) {
			System.out.print("번호 중복! 다시 ");
			return overlap(sc);
		}
		return idx;
	}

	public int overlapNumber(Scanner sc) { // 2-1. 번호 중복 없으면 입력 계속 가능하게
		int s = sc.nextInt();

		for (int i = 0; i < listProds.size(); i++) {
			if (s == listProds.get(i).getNum()) {
				return -1;
			}
		}
		return s;
	}

	public int searchNumber(Scanner sc) { // 2-1. 번호 중복 있으면 그거 리턴
		int s = sc.nextInt();

		for (int i = 0; i < listProds.size(); i++) {
			if (s == listProds.get(i).getNum()) {
				return i;
			}
		}
		return -1;
	}

	public void printProduct(Scanner sc) { // 2. 번호로 검색
		System.out.print("검색하고 싶은 넘버를 입력하세요 : ");
		int idx = searchNumber(sc);

		if (idx < 0) {
			System.out.println("존재하지 않음");
		} else {
			System.out.println(listProds.get(idx));
		}
	}

	public void searchName(Scanner sc) { // 3. 제품명으로 검색
		System.out.print("검색하고 싶은 제품명을 입력하세요 : ");
		String s = sc.next();
		searchList.clear();
		Product p = new Product();

		for (int i = 0; i < listProds.size(); i++) {
			if (listProds.get(i).getName().equals(s)) {
				p = listProds.get(i);
				searchList.add(p);
			}
		}

		if (searchList.size() == 0) {
			System.out.println("검색한 제품이 존재하지 않습니다.");
		} else {
			for (int i = 0; i < searchList.size(); i++) {
				System.out.println(searchList.get(i));
			}
		}
	}

	// 3. 제품명으로 검색 (쌤.ver) 중복된 것 모두 찾아줌
	public ArrayList<Product> getByName(Scanner sc) {
		System.out.print("검색할 제품명 : ");
		String name = sc.next();
		ArrayList<Product> datas = new ArrayList<>();

		for (int i = 0; i < listProds.size(); i++) {
			Product p = listProds.get(i);
			if (name.equals(p.getName())) {
				datas.add(p);
			}
		}

		return datas;
	}

	public void printByName(Scanner sc) {
		ArrayList<Product> datas = getByName(sc);
		
		if (datas.isEmpty()) {
			System.out.println("검색된 제품이 없습니다.");
			return;
		}
		
		for (int i = 0; i < datas.size(); i++) {
			System.out.println(datas.get(i));
		}
	}

	public void modify(Scanner sc) { // 4. 수정
		System.out.print("수정하고 싶은 숫자를 입력하세요 : ");
		int idx = searchNumber(sc);

		if (idx < 0) {
			System.out.println("존재하지 않음");
		} else {
			System.out.println("수정전 데이터");
			System.out.println(listProds.get(idx));

			System.out.print("제품명 입력 : ");
			listProds.get(idx).setName(sc.next());

			System.out.print("가격 입력 : ");
			listProds.get(idx).setPrice(sc.nextInt());

			System.out.print("수량 : ");
			listProds.get(idx).setAmount(sc.nextInt());

			System.out.println("수정후 데이터");
			System.out.println(listProds.get(idx));
		}
	}

	public void delete(Scanner sc) { // 5.삭제
		System.out.println("*** 삭제 전 정보 ***");
		for (int i = 0; i < listProds.size(); i++) {
			System.out.println(listProds.get(i));
		}

		System.out.print("삭제하고 싶은 번호를 입력하세요 : ");
		int idx = searchNumber(sc);

		if (idx < 0) {
			System.out.println("데이터가 존재하지 않습니다.");
			return;
		} else {
			listProds.remove(idx);
		}

		System.out.println("*** 삭제 후 정보 ***");
		for (int i = 0; i < listProds.size(); i++) {
			System.out.println(listProds.get(i));
		}
	}

	public void allPrint() { // 6.전체출력
		//ArrayList<Product> data = listProds;
		//System.out.println(data); toString() 출력
		for (int i = 0; i < listProds.size(); i++) {
			System.out.println(listProds.get(i));
		}
	}
}









과제 체크

// 번호가 중복되는지 체크
public int getByNum(int num) {
	for (int i = 0; i < listProds.size(); i++) {
		Product p = listProds.get(i);
		if (num == p.getNum()) {
			return i;
		}
	}
	return -1;
}





// 번호로 검색하고 출력 
public void getProduct(Scanner sc) {
	System.out.println("검색할 제품 번호: ");
	int num = sc.nextInt();
	int idx = getByNum(num);
	if (idx < 0) {
		System.out.println("없다.");
		} else {
		Product p = listProds.get(idx);
		System.out.println(p);
	}
}





// 제품 수정
public void editProduct(Scanner sc) {
	System.out.println("수정할 제품 번호 : ");
	int num = sc.nextInt();
	int idx = getByNum(num);
	if (idx < 0) {
		System.out.println("업다.");
	} else {
		Product p = listProds.get(idx);
		System.out.println("이름 입력 : ");
		p.setName(sc.next());
		System.out.println("가격 입력 : ");
		p.setPrice(sc.nextInt());
		System.out.println("수량 입력 : ");
		p.setAmount(sc.nextInt());

	}
}









틀린 부분

ArrayList 삭제 부분에서 배열 삭제와 동일하게 코드를 짰다.
삭제하고자 하는 인덱스를 찾아서 바로 arraylist.remove(idx); 를 해주면 된다.


내가 작성한 코드

public void delete(Scanner sc) { // 5.삭제
	System.out.println("삭제하고 싶은 번호를 입력하세요");
	int idx = searchNumber(sc);

	System.out.println("삭제 전 정보");
	for (int i = 0; i < listProds.size(); i++) {
		System.out.println(listProds.get(i));
	}

	if (idx < 0) {
		System.out.println("데이터가 존재하지 않습니다.");
		return;
	} else {
		for (int i = idx; i < listProds.size() - 1; i++) {
			listProds.get(i).setAmount(listProds.get(i + 1).getAmount());
			listProds.get(i).setId(listProds.get(i + 1).getId());
			listProds.get(i).setName(listProds.get(i + 1).getName());
			listProds.get(i).setNum(listProds.get(i + 1).getNum());
			listProds.get(i).setPrice(listProds.get(i + 1).getPrice());
			listProds.get(i).setUrl(listProds.get(i + 1).getUrl());
		}
		listProds.remove(listProds.size() - 1);
	}

	System.out.println("삭제 후 정보");
	for (int i = 0; i < listProds.size(); i++) {
		System.out.println(listProds.get(i));
	}
}




고친 코드

public void delete(Scanner sc) { // 5.삭제
	System.out.println("삭제 전 정보");
	for (int i = 0; i < listProds.size(); i++) {
		System.out.println(listProds.get(i));
	}
		
	System.out.println("삭제하고 싶은 번호를 입력하세요");
	int idx = searchNumber(sc);

	if (idx < 0) {
		System.out.println("데이터가 존재하지 않습니다.");
		return;
	} else {
		listProds.remove(idx);
	}

	System.out.println("삭제 후 정보");
	for (int i = 0; i < listProds.size(); i++) {
		System.out.println(listProds.get(i));
	}
}









향상된 for문

🔹 int 배열 for문 🔹

int[] list = {1, 2, 3, 4, 5};

for ( int i = 0; i < list.length; i++) {
	System.out.println(list[i]);
}

for (int var : list){
	System.out.println(var);
}





🔹 위 상품 관리 프로그램에 있는 Product 클래스 for문 🔹

for (int i = 0; i < list.size(); i++) {
	
}

for (Product p: list){
	// iterator : 반복자
}













equals 재정의

remove

public void delete(Scanner sc) { // 5.삭제
	Product p = new Product();

	System.out.print("삭제하고 싶은 번호를 입력하세요 : ");
	int num = sc.nextInt();
	p.setNum(num);
		
	if(listProds.remove(p)) {
		System.out.println(p.getNum()+"번의 데이터가 삭제됐습니다.");
	} else {
		System.out.println("데이터가 존재하지 않습니다.");
	}
}

위 코드에서

System.out.println(listProds.remove(p));

는 정상작동하면 true 반환, 정상작동하지 않으면 false 반환한다.






ArrayList remove()

remove(방번호) : 그 방에 있는 값을 삭제
remove(객체) : 삭제할 값을 찾아서 삭제.
equals()를 이용해서 찾아서 삭제.
그렇게 때문에 remove(객체)를 하려면 equals를 재정의 해야 한다.
동일함의 기준이 클래스마다 다르므로.
즉, 번호가 같냐, 이름이 같냐 등등 기준이 다르기 때문에 그것을 비교, 판정 할 수 있는 형태로 equals를 재정의 해줘야 한다.

이클립스에서
Menu > Source > Override/Implment > equals() 추가






❓ 뭐랑 뭐를 비교해야 해 ❓
thisobj를 비교


① 우선 두 개의 비교할 타입이 같은 타입인지 확인해야 한다.

if (obj instanceof Product) {

}




② 비교할 타입이 같으면 값이 같은지 비교

if (obj instanceof Product) {
	Product p = (Product) obj;
	// 다운캐스팅을 해서 비교하기

	if(p.num==this.num) {
		return true;
	}
}





public void printProduct(Scanner sc) { // 2. 번호로 검색
	System.out.print("검색하고 싶은 넘버를 입력하세요 : ");
	int num = sc.nextInt();
	Product p = new Product();
	p.setNum(num);
	int idx = listProds.indexOf(p);

	if (idx < 0) {
		System.out.println("존재하지 않음");
	} else {
		System.out.println(listProds.get(idx));
	}
}

검색할 번호를 Product 객체에 담는다.


❓ 왜 ❓


(MyAnswer) 객체에 번호를 저장한 후 listProds와 비교를 하기 위해서, indexOf(p)를 하기 위해서 → 무슨 말이니 도대체!

(TeacherAnswer) 이 코드는 equals()를 사용해서 객체를 비교하는데 equals()는 객체끼리 비교함. 값을 비교하는 것이 아니다!
그래서 Product 객체 p에 검색할 번호만 저장을 하고 arrayList에서 Product 객체를 하나씩 꺼내 p와 equals()로 비교하는 것이다.
p.equals(list.get(i));






재정의 하지 않은 equals

class Name {
	String name;

	public Name(String name) {
		this.name = name;
	}
}

public class Equals {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Name n1 = new Name("abcdefu");
		Name n2 = new Name("abcdefu");

		System.out.println(n1 == n2);		//	 false
		System.out.println(n1.equals(n2));	//	false
	}
}

위 소스는 equals를 재정의하지 않고 비교를 하였다.

n1 == n2는 새로운 객체를 생성한 것이므로 당연히 주소값이 다르니 false가 나오고
equals()는 Object 클래스의 equals()의 내부 코드를 보면 객체 자체를 비교 연산자 == 로 비교한다.
따라서 ==로 비교하는 것과 같은 결과값이 나온다.




재정의 한 equals

class Name2 {
	String name2;

	public Name2(String name2) {
		this.name2 = name2;
	}

	@Override
	public boolean equals(Object obj) {
		// TODO Auto-generated method stub
		return this.name2 == ((Name2) obj).name2;
	}
}

public class Equals2 {
	public static void main(String[] args) {
		Name2 n1 = new Name2("min hyun");
		Name2 n2 = new Name2("min hyun");

		System.out.println(n1 == n2);		// false
		System.out.println(n1.equals(n2));	// true
	}
}

equals를 먼저 Object 타입으로 매개변수를 받는다.

들어온 매개변수는 Object 타입이기 때문에 Name2 클래스 내의 필드를 사용할 수 없다.
그래서 Name2로 다운캐스팅을 해줘야 한다.
코드와 같이 ((Name2)obj)와 같이 다운캐스팅을하면 Name2의 필드를 사용할 수 있다.













반복자

배열, 리스트는 다음 칸으로 이동 요소를 하나씩 추출하는 동작을 반복한다.
이 작업을 자동 처리해줌
꼭 사용할 필요는 없다.

생성

Iterator iter = list.iterator();
iter.hasNext(); // 다음 요소 있으면 true, 아니면 false 반환
iter.next(); // 다음 요소 추출





반복자.java

public static void main(String[] args) {
	// TODO Auto-generated method stub
	ArrayList<String> list = new ArrayList<String>();
	list.add("aaa");
	list.add("bbb");
	list.add("ccc");
	list.add("ddd");
  
 	Iterator<String> iter = list.iterator();
	while (iter.hasNext()) {
		String s = iter.next();
		System.out.println(s);
	}
  
    for (String s : list) {	
		System.out.println(s);
	}
}

에서




외부에서 사용

Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
	String s = iter.next();
	System.out.println(s);
}

위는 반복자를 외부에서 사용한 것이다.
옛날엔 위처럼 많이 사용했는데 요즘에는 반복자를 밑코드처럼 내부 사용한다.




내부에서 사용

for (String s : list) {	
	System.out.println(s);
}

이렇게 간단하게 내부에서 사용할 수 있다.


for(요소타입 변수명 : 리스트명) {
변수로 원하는 작업
}

의 식으로 작성하면 된다.













리스트는 값만 저장하고 방의 순서가 있다.
그러나 맵은 키와 값을 같이 저장하고 데이터 순서가 없다.



방 번호로 접근하지 않는다.


❓그럼 뭐로 접근할까 ❓
➡ 키 값으로 접근을 한다.


❓ 그럼 뭐가 좋은데? ❓
➡ 빠른 검색을 위한 것이다.



보통 Map중에 HashMap을 많이 사용한다.

생성 : HashMap<Integer, String> map = new HashMap<Integer, String>();
추가 : map.put(키, 값);
검색 : map.get(키);
키 묶음 : map.keySet();
값 묶음 : map.values();









package arraylist;

import java.util.HashMap;
import java.util.Map;

public class MapTest {

	public static void main(String[] args) {
		HashMap<Integer, String> map = new HashMap<Integer, String>();
		
		map.put(1, "mango");
		map.put(2, "min");
		map.put(3, "hyun");
		
		System.out.println(map.get(1));
		System.out.println(map.get(2));
		System.out.println(map.get(3));
	}

}

키 타입int값 타입String
키는 검색의 기준이기 때문에 중복 허용 안 함



출력하면

mango
min
hyun

값이 나온다.











HashMap<String, String> map2 = new HashMap<String, String>();
	map2.put("name", "hyun");
	map2.put("tel", "010-1111-1111");
	map2.put("address", "서울");

	System.out.println("name : " + map2.get("name"));
	System.out.println("tel : " + map2.get("tel"));
	System.out.println("address : " + map2.get("address"));




출력하면

name : hyun
tel : 010-1111-1111
address : 서울

이 나온다.







보통 ArrayList랑 Map이랑 비교한다면 9:1 비율로 사용한다.



❓ 언제 사용해 ❓
파라미터 이름과 값 아이디 패스워드 전달할 때
예를 들어

id=aaa&pwd=aaa111

이런 데이터를 전달할 때, 즉 이름과 값 두 개를 쌍으로 처리 해야할때 이용한다.









Map iterator

Map도 iterator를 사용할 수 있다.


for (String key : map2.keySet()) { // keySet() : 키 묶음
	System.out.println(key + " : " + map2.get(key)); // 키로 값 추출
}

for (String s : map2.values()) { // 값만 추출
	System.out.println(s);
}




출력하면

aaddress : 서울
name : hyun
tel : 010-1111-1111
서울
hyun
010-1111-1111

순서는 존재하지 않으므로 순서대로 나오지 않는다.





0개의 댓글