public class String_getTextOfLocation {
//charAt() 사용하여 문자 출력
public static Character getFirstCharacter(String str){
if(str == null || str.length() == 0) { //문자열이 null이거나 문자열 길이가 0이면
return null; //null을 반환
} else {
return (Character) str.charAt(0); //그렇지 않으면 문자열의 0번째 문자를 반환
}
}
public static void main(String[] args)
{
String str = "Hello welcome to develop world!!";
System.out.println("문자열 : " + str);
System.out.print("문자열에 첫번째 문자는 : " + getFirstCharacter(str));
}
}
문자열 : Hello welcome to develop world!!
문자열에 첫번째 문자는 : H
2. substring( )
startIdx에서 시작하는 하위 문자열부터 나머지 모든 문자를 반환한다
startIdx, endIdx를 전달하면 startIdx에서 시작하여 endIdx-1번째 문자까지 반환한다
public String substring(int startIdx)
public String substring(int startIdx, int endIdx)
public class String_getTextOfLocation_substring {
public static void main(String[] args){
String str = "Hello welcome to develop world!!";
//01234567890123456789012345678901
System.out.println("문자열 : " + str);
System.out.println("시작점 index(3): " + str.substring(3)); //4번째 문자부터 전체 반환
System.out.println("index(2)부터 index(6)까지의 문자 : " + str.substring(2, 7)); //3번째 문자부터 6번째 앞 문자까지
System.out.println("index(3)부터 index(7)까지의 문자 : " + str.substring(3, 8)); //3번째 문자부터 8번째 앞 문자까지
System.out.print("문자열에 첫번째 문자는 : " + getFirstCharacter(str)); //첫번째 문자열 가져오기
}
public static String getFirstCharacter(String str)
{
if(str == null || str.length() == 0) //빈 문자열일 경우의 조건
return null;
else
return str.substring(0, 1);
}
}
문자열 : Hello welcome to develop world!!
시작점 index(3): lo welcome to develop world!!
index(2)부터 index(6)까지의 문자 : llo w
index(3)부터 index(7)까지의 문자 : lo we
문자열에 첫번째 문자는 : H
3. toCharArray( )
index 값을 사용하여 배열의 요소에 액세스할 수 있다
문자열을 char 데이터 유형의 배열로 변환할 수 있다면 index를 사용하여 모든 요소를 가져올 수 있다
인덱스 0을 통해 첫 번째 문자를 가져올 수 있다
toCharArray() 메서드를 사용하여 문자열을 문자 배열로 변환한다
public class String_getTextOfLocation_toCharArray {
public static Character getFirstCharacter(String str)
{
if(str == null || str.length() == 0) //빈 문자열일 경우 null 반환
return null;
else
{
char[] charArr = str.toCharArray(); //문자열을 배열로 변환
return charArr[0];
}
}
public static void main(String[] args)
{
String str = "Hello welcome to develop world!!";
System.out.println("문자열 : " + str);
System.out.print("문자열에 첫번째 문자는 : " + getFirstCharacter(str));
}
}
문자열 : Hello welcome to develop world!!
문자열에 첫번째 문자는 : H
HashMap은 key와 value 값으로 구성된다 - HashMap(key, value) - key 값은 중복되면 않된다 - value 값은 중복될 수 있다
HashMap = Hash Table 에 저장 = 배열(Array) + 링크드리스트(LinkedList) 로 구성된다
HashMap은 순서를 유지하지 않아도 된다 - 순서를 유지하고 싶다면 LikedHashMap을 사용하면 된다
HashMap은 Hashing 기법으로 만들어진다
HashMap map = new HasgMap();
map.put("key", "value"); //저장하기 위한 명령어로 put를 사용한다
key와 value 값 한쌍을 Entry라고 한다
2. Hashing
hash function은 key값을 받아서 해당되는 index 값(저장위치)을 반환하는 함수이다
반환되는 index 값을 hash code라고 한다
hash 함수를 이용하여 hash 테이블에 데이터를 저장하고 반환하는 작업을 hashing이라고 한다 - key값이 같으면 항상 같은 값을 반환한다 - key값이 달라도 같은 값을 반환할 수 있다
hash table은 배열과 링크드 리스트의 조합이다 - 배열의 접근성과 링크드리스트의 변경 용이성을 모두 가지고 있다
3. HashMap 메서드
1) HashMap
HashMap()
HashMap(int initialCapacity)
HashMap(int initialCapacity, float loadFactor)
HashMap(Map m)
2) Object Method
Object put(Object key, Object value) - 데이터를 저장할 때 사용한다 - key와 value를 묶어서 저장한다(key=value)
void putAll(Map m) - 지정한 Map m의 값을 모두 저장할 때 사용한다
Object remove(Object key) - key 데이터를 삭제할 때 사용한다
Object replace(Object key, object value) - 지정한 key의 value를 변경할 때 사용한다
boolean replace(Object key, Object oldValue, Object newValue) - 지정한 key에 해당되는 value를 변경할 때 사용한다
3) HashMap에 저장된 데이터를 읽어오는 Method
Set entrySet() - key와 value 쌍으로 구성된 데이터를 호출한다
Set keySet() - key 데이터만 호출한다
Collection value() - value 데이터만 호출한다
4) HashMap에 저장된 데이터를 조회하는 Method
Object get(Object key) - 지정한 key에 해당하는 value를 반환한다
Object getOrDefault(Object key, Object defaultValue) - 주어진 key가 데이터에 없을 경우, 지정한 defaultValue 데이터를 반환한다
boolean containsKey(object key) - 주어진 key가 key 데이터에 있는지 여부를 확인한다 - true / false 로 반환한다
boolean containsValue(Object vaalue) - 주어진 value가 value 데이터에 있는지 여부를 확인한다 - true / false 로 반환한다
5) 정량적 Method
int size() - 데이터의 크기를 확인한다 boolean isEmpty() - 데이터가 비었는지 확인한다
void clear() - 데이터를 삭제한다
Object clone() - 데이터를 복제한다
4. 예제
import java.util.HashMap;
import java.util.Scanner;
public class HashMap_IdPw {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("Id1", "1111");
map.put("Id2", "2222");
map.put("Id3", "3333");
// System.out.println(map);
Scanner scanner = new Scanner(System.in);
while (true) { //반복문을 실행
System.out.println("Id와 Pw를 입력하세요");
System.out.println("Id : ");
String id = scanner.nextLine().trim(); //trim 은 앞 뒤 공백을 없애준다
System.out.println("Pw : ");
String pw = scanner.nextLine().trim();
System.out.println(); //줄바꿈 역활
if (!map.containsKey(id)) { //containsKey는 key 값 전체를 가리킨다
System.out.println("일치하는 id가 없습니다" + "\n" + "다시 입력해 주시기 바랍니다");
continue; //다음 반복 while 문으로 이동
}
if (!map.get(id).equals(pw)) { //get(id)는 key 값 중에 id와 일치하는 값이 있으면 value 값을 반환한다
System.out.println("비밀번호가 일치하지 않습니다" + "\n" + "다시 입력해 주시기 바랍니다");
} else { //id와 pw가 일치하면 문장 출력 후 반복문 털출
System.out.println("id와 비밀번호가 일치합니다");
break;
}
}
}
}
import java.util.*;
public class HashMap_SumAverage {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("kim", 90);
map.put("lee", 50);
map.put("cha", 80);
map.put("park", 100);
map.put("choi", 70);
// System.out.println(map);
//전체 map에 저장된 데이터에서 값을 호출,조회하는 코드
Set set = map.entrySet(); //map에 저장된 데이터를 key,value 쌍으로 호출한다
Iterator iter = set.iterator(); //set에 데이터가 남아 있는지 확인한다
while(iter.hasNext()) {
Map.Entry me = (Map.Entry)iter.next(); //Map 인터페이스 안의 Entry 인터페이스
System.out.println("이름 : " + me.getKey() + ", 점수 : " + me.getValue());
}
//전체 map에서 key 데이터만을 호출하는 코드
set = map.keySet(); //key에 저장된 값만 가져온다
System.out.println("참가자 명단 : " + set);
//전체 map에서 value 데이터만을 호출하는 코드
Collection values = map.values(); //value 데이터를 가져온다
iter = values.iterator();
int total = 0;
while(iter.hasNext()) { //hasNext()는 읽어 올 요소가 남았는지 확인한다
int i = (int)iter.next(); //next() 메소드는 읽어 올 요소가 남았는지 확인한다
total = total +i;
}
System.out.println("총점 : " + total);
System.out.println("평균 : " + (float)total/set.size()); //정수로 결과값이 나오므로 float로 형변환 해 준다
System.out.println("최고점수 : "+ Collections.max(values));
System.out.println("최저점수 : "+ Collections.min(values));
}
}
import java.util.*;
public class HashMap_SumAverage {
public static void main(String[] args) {
HashMap map = new HashMap();
map.put("kim", 90);
map.put("lee", 50);
map.put("cha", 80);
map.put("park", 100);
map.put("choi", 70);
// System.out.println(map);
//전체 map에 저장된 데이터에서 값을 호출,조회하는 코드
Set set = map.entrySet(); //map에 저장된 데이터를 key,value 쌍으로 호출한다
Iterator iter = set.iterator(); //set에 데이터가 남아 있는지 확인한다
while(iter.hasNext()) {
Map.Entry me = (Map.Entry)iter.next(); //Map 인터페이스 안의 Entry 인터페이스
System.out.println("이름 : " + me.getKey() + ", 점수 : " + me.getValue());
}
//전체 map에서 key 데이터만을 호출하는 코드
set = map.keySet(); //key에 저장된 값만 가져온다
System.out.println("참가자 명단 : " + set);
//전체 map에서 value 데이터만을 호출하는 코드
Collection values = map.values(); //value 데이터를 가져온다
iter = values.iterator();
int total = 0;
while(iter.hasNext()) { //hasNext()는 읽어 올 요소가 남았는지 확인한다
int i = (int)iter.next(); //next() 메소드는 읽어 올 요소가 남았는지 확인한다
total = total +i;
}
System.out.println("총점 : " + total);
System.out.println("평균 : " + (float)total/set.size()); //float로 형변환 해 준다
System.out.println("최고점수 : "+ Collections.max(values));
System.out.println("최저점수 : "+ Collections.min(values));
}
}
두 클래스를 상위 클래스와 하위 클래스로 나누어 상위 클래스의 멤버(필드, 메서드, 이너 클래스)를 하위 클래스와 공유하는 것을 의미한다
여기서 우리는 이 두 클래스를 서로 상속 관계 있다고 하며, 하위 클래스는 상위 클래스가 가진 모든 멤버를 상속받게 됩니다.
하위 클래스의 멤버 개수는 상위 클래스의 멤버 개수보다 같거나 많아야 한다
상위 클래스-하위 클래스의 관계를 조상-자손 관계로 표현하기도 한다
두 클래스 간 상속 관계를 설정할 때 사용하는 extends 키워드는 "확장하다"라는 의미를 가지고 있다
상위 클래스와 하위 클래스의 공통점과 다른점이 있다 - 상위 클래스의 변수와 메서드를 하위 클래스에 그대로 받아와서 사용한다 - 하위 클래스는 필요한 변수와 메서드를 추가하여 코드를 작성할 수 있다
상속을 통해 클래스를 작성하면 코드를 재사용하여 보다 적은 양의 코드로 새로운 클래스를 작성할 수 있어 코드의 중복을 제거할 수 있다
상속은 다형적 표현이 가능하다는 장점이 있다
하위 객체의 클래스에 상위 객체에서 확장된 클래스의 성격도 가지고 있는 것을 다형성이라 한다
위의 그림을 코드로 작성하면 아래와 같다 - extends 를 확장 메서드로 사용한다
class Person{
String name;
int age;
void learn(){
System.out.println("study");
}
void walk(){
System.out.println("walking");
}
void eat(){
System.out.println("eating");
}
}
class Teacher extends Person{
String schoolName;
void teach(){
System.out.println("teaching");
}
}
class Ceo extends Person{
String companyName;
void approval(){
System.out.println("review");
}
}
class Developer extends Person{
String groupName;
void coding(){
System.out.println("coding");
}
}
public class Extends {
public static void main(String[] args) {
Person p = new Person();
p.name = "kms";
p.age = 25;
p.learn();
p.walk();
p.eat();
System.out.println(p.name);
Teacher t = new Teacher();
t.name = "kim";
t.age = 30;
t.learn();
t.walk();
t.eat();
t.teach();
System.out.println(t.name);
}
}
코드의 결과는 다음과 같이 출력된다 - Teach 클래스가 person 클래스의 변수와 메서드를 상속받아서 확장된 것을 확인할 수 있다 - extends 메서드로 상위 클래스를 확장하지 않았다면 중복된 변수와 메서드를 반복해서 작성해야 했을 것이다
2. 포함(composit)
포함(composite)은 상속처럼 클래스를 재사용할 수 있는 방법이다
클래스의 멤버로 다른 클래스 타입의 참조변수를 선언한다
클래스명(멤버1, 멤버2, 멤버3,...) 의 형태로 사용한다 - 외부 클래스 내에 내부 클래스를 작성한다 - 내부 클래스에 main 클래스가 있다 - Address 객체를 외부 클래스 밖에서 별도의 클래스로 선언 한다
public class Composit {
int id;
String name;
Address address;
public Composit(int id, String name, Address address) {
this.id = id;
this.name = name;
this.address = address;
}
void showInfo() {
System.out.println(id + " " + name);
System.out.println(address.city + " " + address.country);
}
public static void main(String[] args) {
Address address1 = new Address("Gangnamgu", "Seoul");
Address address2 = new Address("Junggu", "Seoul");
Composit e = new Composit(1, "kms", address1);
Composit e2 = new Composit(2, "kim", address2);
e.showInfo();
e2.showInfo();
}
}
class Address {
String city, country;
public Address(String city, String country) {
this.city = city;
this.country = country;
}
}
Address 클래스에 포함되어 있는 인스턴스 변수 city와 country를 각각 Composit 클래스의 변수로 정의해주어야 하지만, Address 클래스로 해당 변수들을 묶어준 후 Composit 클래스 안에 참조변수를 선언하였다 - 코드의 중복을 없애고 포함관계로 재사용하는 방법이다
3. 상속과 포함의 선택
클래스 간의 관계가 ‘~은 ~이다(IS-A)’ 의 관계이면 상속을 사용한다
클래스 간의 관계가 '~은 ~을 가지고 있다(HAS-A)'의 관계이면 포함을 사용한다
4. 메서드 오버라이딩(Method Overriding)
상위 클래스로부터 상속받은 메서드와 동일한 이름의 메서드를 재정의하는 것을 의미한다
Override는 사전적으로 "~위에 덮어쓰다"를 의미한다
1) 일반적인 메서드오버라이딩
class Airplane{
void fly(){
System.out.println("Airplane is flying");
}
}
public class MethodOverriding extends Airplane {
void fly(){
System.out.println("MethodOverriding is flying");
}
public static void main(String[] args) {
MethodOverriding over = new MethodOverriding();
over.fly();
}
}
MethodOverriding 클래스가 Airplane 클래스의 fly 메서드를 오버라이딩 한 후 MethodOverriding 클래스에 적합하게 fly 메서드를 변경하고 있다
메서드 오버라이딩은 세가지 조건을 반드시 만족해야 한다 - 메서드의 선언부(메서드 이름, 매개변수, 반환타입)가 상위클래스와 완전히 일치해야 한다 - 접근 제어자의 범위가 상위 클래스의 메서드보다 같거나 넓어야 한다 - 예외는 상위 클래스의 메서드보다 많이 선언할 수 없다
2) 상위 클래스의 타입을 적용한 메서드 오버라이딩
public class Overriding {
public static void main(String[] args) {
Bike bike = new Bike();
Car car = new Car();
Human human = new Human();
bike.run();
car.run();
human.run();
//상위 클래스 Vehicle 타입을 사용하여 각각의 객체의 메서드 값을 다르게 출력한다
Vehicle bike2 = new Bike();
Vehicle car2 = new Car();
Vehicle human2 = new Human();
bike2.run();
car2.run();
human2.run();
}
}
class Vehicle{
void run(){
System.out.println("Vehicle is running");
}
}
class Bike extends Vehicle{
void run(){
System.out.println("Bike is running");
}
}
class Car extends Vehicle{
void run(){
System.out.println("Car is running");
}
}
class Human extends Vehicle{
void run(){
System.out.println("Human is running");
}
}
3) 배열을 적용한 메서드 오버라이딩
Vehicle[] vehicles = new Vehicle[]{new Bike(), new Car(), new Human()};
for (Vehicle vehicle : vehicles) {
vehicle.run();
}
??? 이해가 잘 안간다...추가로 찾아보자.
5. super
1) super
자신보다 상위의 클래스에 있는 객체를 의미한다
반드시 함수의 첫 줄에 위치하여야 한다
ex1) Parents의 변수 count와 Kim의 변수 count가 동일한 상황에서의 Kim 과 Parents의 나이를 출력
class
Kim
Parents
variable
age
count
count
constructor
Kim()
- #19 에서 굳이 this 키워드를 사용하지 않아도 출력은 동일하다. 설명을 위하여 구분하기 위해 사용하였다
- 여기서 super 과 this() 의 차이점은 각각 상위클래스의 객체와 생성자를 의미한다는 부분이다
-상속관계를 전제로 하며, super.변수명 의 형식으로 사용한다
※ 상속관계가 아닐 경우 에러(count 변수를 찾을 수 없다)가 발생한다
2) super()
super은 객체를 의미하지만, super()는 생성자를 의미한다
반드시 함수의 첫 줄에 위치하여야 한다
ex1) Parentsname의 변수 count와 Kimname의 변수 count가 동일한 상황에서의 Kimname 과 Parentsname의 나이를 출력하고, Parentsname를 상속받아 모두 출력
class
Kimname
Parentsname
variable
name
count
constructor
Kimname
Parentsname
6. Object 클래스
자바 클래스 상속계층도 중 최상위에 위치한 상위클래스이다
자바의 모든 클래스는 Object클래스를 기본적으로 상속되면, Object클래스로부터 확장된다
상속클래스가 없는 경우 자동으로 extends object를 추가하여 Object클래스가 상속된다
class Parent //컴파일러가 "extends Object" 자동 추가 {
}
class Child extends Parent {
}
변수는 클래스 변수(cv, class variable), 인스턴스 변수(iv, instance variable), 지역 변수(lv, local variable) 세 가지로 구분될 수 있다
필드는 클래스 변수와 인스턴스 변수이며, static 키워드의 유무로 구분할 수 있다 - static 키워드가 함께 선언된 것은 클래스 변수이다 - static 키워드가 없는 것은 인스턴스 변수이다
두 가지 변수 유형에 포함되지 않고 메서드 내에 포함된 모든 변수를 지역변수라고 한다
세 가지 유형의 변수들은 주로 선언된 위치에 따라 그 종류가 결정되며 각각 다른 유효 범위(scope)를 가진다
class Area { //클래스 영역 시작
int instanceVariable; // 인스턴스 변수
static int classVariable; // 클래스 변수(static 변수, 공유변수)
void method() {
// 메서드 영역 시작
int localVariable = 0; // 지역 변수. 속해있는 {}블록 안에서만 유효
} //메서드 영역 끝
}//클래스 영역 끝
1) 인스턴스 변수(iv)
인스턴스가 가지는 각각의 고유한 속성을 저장하기 위한 변수이다
new 생성자() 를 통해 인스턴스가 생성될 때 만들어진다
클래스를 통해 만들어진 인스턴스는 힙 메모리의 독립적인 공간에 저장된다
동일한 클래스로부터 생성되었지만 객체의 고유한 개별성을 가진다
사람마다 성별, 이름, 나이, MBTI가 다 다르듯 인스턴스 변수는 그 고유한 특성을 정의하기 위한 용도로 사용한다
2) 클래스 변수(cv)
static 키워드를 통해 선언한다
클래스 변수는 독립적인 저장 공간을 가지는 인스턴스 변수와 다르게 공통된 저장공간을 공유한다
한 클래스로부터 생성되는 모든 인스턴스 들이 특정한 값을 공유해야하는 경우에 주로 static 키워드를 사용하여 클래스 변수를 선언한다
사람을 예로 들면 손가락과 발가락 개수와 같이 모든 사람이 공유하는 특성을 저장하는 데에 사용된다
클래스 변수는 인스턴스 변수와 달리 인스턴스를 따로 생성하지 않고 '클래스명.클래스변수명' 을 통해 사용이 가능하다
area.classVariable 처럼 클래스 변수를 사용할 수 있다
3) 지역변수(lv)
지역변수는 메서드 내에 선언된다
메서드 내({} 블록)에서만 사용가능한 변수이다
멤버 변수와는 다르게 지역변수는 스택 메모리에 저장되어 메서드가 종료되는 것과 동시에 함께 소멸되어 더이상 사용할 수 없게 된다
힙 메모리에 저장되는 필드 변수는 객체가 없어지지 않는 한 절대로 삭제되지 않지만, 스택 메모리에 저장되는 지역변수는 한동안 사용되지 않는 경우 가상 머신에 의해 자동으로 삭제된다
4) 필드변수와 지역변수의 차이
필드 변수와 지역 변수의 주요한 한 가지 차이점은 초기값에 있다
지역변수는 직접 초기화하지 않으면 값을 출력할 때에 오류가 발생한다
필드 변수는 직접적으로 초기화를 실행하지 않더라도 강제로 초기화가 이뤄진다
메모리의 저장 위치와 긴밀한 연관성을 가진다
힙 메모리에는 빈 공간이 저장될 수 없기 때문에 저장되는 필드는 강제로 초기화된다
스택 메모리는 강제로 초기화되지 않으므로 지역 변수는 선언시 반드시 초기화를 실행해야 한다
2. static & instance 변수
1) static 변수
공유의 개념을 가지고 있다
클래스 변수를 생성하는데 사용한다
예제1)
public class StaticTest0 {
public static void main(String[] args) {
}
class Car {
public String str1 = "Instance Variable";
public static String str2 = "class Variable";
public static void method() {
System.out.println(str1);
System.out.println(str2);
}
public void method() {
System.out.println(str1);
System.out.println(str2);
}
}
}
<결과>
java: non-static variable str1 cannot be referenced from a static context
java: 정적 컨텍스트에서 비정적 변수 str1을 참조할 수 없습니다.
- 위의 코드에서 어느 부분에서 에러가 발생할까?
- public static void method() { System.out.println(str1); : 출력 명령에서 발생한다 : str1은 인스턴스 변수로써 클래스 메서드 내에서는 참조를 할 수 없다 : 클래스 메서드 내에서는 클래스 변수만이 참조가 가능하다
예제2)
public class StaticTest1 {
public static void main(String[] args) {
Car.method1();
Car.method2();
System.out.println(Car.str1);
System.out.println(Car.str2);
}
class Car {
public String str1 = "Instance variable";
public static String str2 = "class variable";
public static void method1() {
// System.out.println(str1);
System.out.println(str2);
}
public void method2() {
System.out.println(str1);
System.out.println(str2);
}
}
}
java: non-static method method2() cannot be referenced from a static context
java: 정적 메서드2는 정적 컨텍스트에서 참조할 수 없습니다.
- Car.method2(); System.out.println(Car.str1); : 참조와 출력 명령에서 에러가 발생한다 : method2 메서드는 인스턴스 메서드이므로 공유가 되지 않는다 : str1 역시 인스턴스 변수로써 공유가 되지 않는다 - 인스턴스 메서드를 참조하고져 하면 인스턴스를 new 연산자로 생성하여야 한다
예제 3) 클래스 변수의 내용을 변경할 경우 전체가 변경된다
public class StaticTest1 {
public static void main(String[] args) {
Car car1 = new Car();
Car car2 = new Car();
car1.cv = "car1.str1 = Instance variable";
System.out.println(car1.cv);
System.out.println(car2.cv);
System.out.println(Car.cv);
}
static class Car {
public String iv = "Instance variable";
public static String cv = "class variable";
public static void method1() {
System.out.println(cv);
}
}
}
예제 4) 인스턴스 변수의 내용을 변경할 경우 변경한 iv만 적용된다
public class StaticTest1 {
public static void main(String[] args) {
Car car1 = new Car();
Car car2 = new Car();
car1.iv = "car1.str1 = Instance variable";
System.out.println(car1.iv);
System.out.println(car2.iv);
// System.out.println(Car.iv);
}
static class Car {
public String iv = "Instance variable";
public static String cv = "class variable";
public static void method1() {
// System.out.println(iv);
}
}
}
Scanner 클래스 는 Scanner 사용자 입력을 받는 데 사용되며 java.util패키지에서 찾을 수 있다.
Scanner 클래스 를 사용하려면 Scanner클래스의 개체를 만들고 Scanner클래스 메서드를 사용한다
예문은 nextLine() 메서드를 사용하여 문자열을 입력받는다
import java.util.Scanner; // Import the Scanner class
class Main {
public static void main(String[] args) {
Scanner myObj = new Scanner(System.in); // Create a Scanner object
System.out.println("Enter username");
String userName = myObj.nextLine(); // Read user input
System.out.println("Username is: " + userName); // Output user input
}
}
Enter username
1) 입력 유형
Method
Description
nextBoolean()
Reads abooleanvalue from the user
nextByte()
Reads abytevalue from the user
nextDouble()
Reads adoublevalue from the user
nextFloat()
Reads afloatvalue from the user
nextInt()
Reads aintvalue from the user
nextLine()
Reads aStringvalue from the user
nextLong()
Reads alongvalue from the user
nextShort()
Reads ashortvalue from the user
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner myObj = new Scanner(System.in);
System.out.println("Enter name, age and salary:");
// String input
String name = myObj.nextLine();
// Numerical input
int age = myObj.nextInt();
double salary = myObj.nextDouble();
// Output input by user
System.out.println("Name: " + name);
System.out.println("Age: " + age);
System.out.println("Salary: " + salary);
}
}
Enter name, age and salary:
참고:잘못된 입력(예: 숫자 입력의 텍스트)을 입력하면 예외/오류 메시지(예: "InputMismatchException")가 표시된다
2. BufferReader
Scanner 클래스는 소량의 문자열을 입력받는데 용이하다
BufferReader 클래스는 용량이 많은 문자열을 입력받는데 적합하다 - 문자열을 하나식 전달하지 않고 버퍼에 담아 두었다가 한번에 전달한다 - 속도가 빠르고 효율적이다
BufferReader 는 Enter만을 경계로 입력값을 인식한다 - 입력값을 나누는 가공 작업이 추가로 필요하다
public class String_BufferedReader {
public static void main(String[] args) throws Exception {
//BufferReader를 사용하여 readLine()로 입력받을 경우 예외처리가 필수이다
//BufferReader (InputStreamReader) : 문자열 입력 메서드
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//InputStreamReader : 문자열 입력 메서드
String str = br.readLine(); //String 문자열을 라인 단위로 입력, Enter를 경계로 한다
String arr[] = str.split(" "); //" "빈칸을 경계로 하여 배열로 변환한다
int str1 = Integer.parseInt(br.readLine()); //정수형의 문자열 입력, 형변환이 필요하다
// System.out.println(str);
System.out.println(arr);
System.out.println(str1);
//BufferWriter (OutputStreamWriter) : 문자열 출력 메서드
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.newLine(); //줄바꿈 , "\n"와 같다
bw.write(str + "\n"); //출력
bw.newLine(); //줄바꿈 , "\n"와 같다
bw.flush();//남아있는 데이터를 모두 출력
bw.close();//스트림 닫음
}
// 문자열 가공 방법
public void manufacturing() throws Exception {
// 1번째 방법) StringTokenizer를 이용한다.
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine()); //StringTokenizer인자값에 입력 문자열 넣음
int a = Integer.parseInt(st.nextToken()); //첫번째 호출을 to int
int b = Integer.parseInt(st.nextToken()); //두번째 호출을 to int
// 두번째 방법) string을 한번에 받아서 split을 이용해 배열로 변환
String s = br.readLine();
String array[] = s.split(" "); //공백마다 데이터 끊어서 배열에 넣음
return;
}
}
Represents a time (hour, minute, second and nanoseconds (HH-mm-ss-ns))
LocalDateTime
Represents both a date and a time (yyyy-MM-dd-HH-mm-ss-ns)
DateTimeFormatter
Formatter for displaying and parsing date-time objects
1. 현재 날짜 표시
현재 날짜를 표시하려면 java.time.LocalDate클래스를 가져오고 해당 now()메서드를 사용합니다.
import java.time.LocalDate; // import the LocalDate class
public class Main {
public static void main(String[] args) {
LocalDate myObj = LocalDate.now(); // Create a date object
System.out.println(myObj); // Display the current date
}
}
2022-08-08
2. 현재 시간 표시
현재 시간(시, 분, 초 및 나노초)을 표시하려면 java.time.LocalTime클래스를 가져오고 해당 now()메서드를 사용합니다.
import java.time.LocalTime; // import the LocalTime class
public class Main {
public static void main(String[] args) {
LocalTime myObj = LocalTime.now();
System.out.println(myObj);
}
}
13:54:38.126484
3. 현재 날짜 및 시간 표시
현재 날짜와 시간을 표시하려면 java.time.LocalDateTime클래스를 가져오고 해당 now()메서드를 사용합니다.
import java.time.LocalDateTime; // import the LocalDateTime class
public class Main {
public static void main(String[] args) {
LocalDateTime myObj = LocalDateTime.now();
System.out.println(myObj);
}
}
2022-08-08T13:54:38.126501
4. 날짜 및 시간 형식 지정
위의 예에서 "T"는 날짜와 시간을 구분하는 데 사용됩니다. DateTimeFormatter동일한 패키지 의 메서드와 함께 클래스를 사용하여 ofPattern()날짜-시간 개체의 형식을 지정하거나 구문 분석할 수 있습니다. 다음 예는 날짜-시간에서 "T"와 나노초를 모두 제거합니다.
import java.time.LocalDateTime; // Import the LocalDateTime class
import java.time.format.DateTimeFormatter; // Import the DateTimeFormatter class
public class Main {
public static void main(String[] args) {
LocalDateTime myDateObj = LocalDateTime.now();
System.out.println("Before formatting: " + myDateObj);
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String formattedDate = myDateObj.format(myFormatObj);
System.out.println("After formatting: " + formattedDate);
}
}
Before Formatting: 2022-08-08T13:54:38.126996
After Formatting: 08-08-2022 13:54:38
5. ofPattern()
다른 형식으로 날짜와 시간을 표시하려는 경우 이 메서드는 모든 종류의 값을 허용합니다
Value
Example
yyyy-MM-dd
"1988-09-29"
dd/MM/yyyy
"29/09/1988"
dd-MMM-yyyy
"29-Sep-1988"
E, MMM dd yyyy
"Thu, Sep 29 1988"
import java.time.LocalDateTime; // Import the LocalDateTime class
import java.time.format.DateTimeFormatter; // Import the DateTimeFormatter class
public class Main {
public static void main(String[] args) {
LocalDateTime myDateObj = LocalDateTime.now();
System.out.println("Before formatting: " + myDateObj);
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm:ss");
String formattedDate = myDateObj.format(myFormatObj);
System.out.println("After formatting: " + formattedDate);
}
}
Before Formatting: 2022-08-08T14:05:58.945620
After Formatting: 08-08-2022 14:05:58
import java.time.LocalDateTime; // Import the LocalDateTime class
import java.time.format.DateTimeFormatter; // Import the DateTimeFormatter class
public class Main {
public static void main(String[] args) {
LocalDateTime myDateObj = LocalDateTime.now();
System.out.println("Before Formatting: " + myDateObj);
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd/MM/yyyy HH:mm:ss");
String formattedDate = myDateObj.format(myFormatObj);
System.out.println("After Formatting: " + formattedDate);
}
}
Before Formatting: 2022-08-08T14:06:58.846495
After Formatting: 08/08/2022 14:06:58
import java.time.LocalDateTime; // Import the LocalDateTime class
import java.time.format.DateTimeFormatter; // Import the DateTimeFormatter class
public class Main {
public static void main(String[] args) {
LocalDateTime myDateObj = LocalDateTime.now();
System.out.println("Before Formatting: " + myDateObj);
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("dd-MMM-yyyy HH:mm:ss");
String formattedDate = myDateObj.format(myFormatObj);
System.out.println("After Formatting: " + formattedDate);
}
}
Before Formatting: 2022-08-08T14:07:39.733365
After Formatting: 08-Aug-2022 14:07:39
import java.time.LocalDateTime; // Import the LocalDateTime class
import java.time.format.DateTimeFormatter; // Import the DateTimeFormatter class
public class Main {
public static void main(String[] args) {
LocalDateTime myDateObj = LocalDateTime.now();
System.out.println("Before Formatting: " + myDateObj);
DateTimeFormatter myFormatObj = DateTimeFormatter.ofPattern("E, MMM dd yyyy HH:mm:ss");
String formattedDate = myDateObj.format(myFormatObj);
System.out.println("After Formatting: " + formattedDate);
}
}
Before Formatting: 2022-08-08T14:08:27.450224
After Formatting: Mon, Aug 08 2022 14:08:27
import java.util.*;
public class Aaaa {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//int num = scanner.nextInt();
String input = scanner.nextLine();
//System.out.println(num);
System.out.println("입력한 숫자는?");
switch (input) {
case "1":
System.out.println("1번");
break;
case "2":
System.out.println("2번");
break;
case "3":
System.out.println("3번");
break;
case "4":
System.out.println("4번");
break;
case "5":
System.out.println("5번");
break;
default:
System.out.println(input + " 번은 해당이 없는 숫자입니다");
break;
}
}
}
result
6 //입력 후 enter
입력한 숫자는?
6 번은 해당이 없는 숫자입니다
타입에 따라 문자열 입력도 가능하다
import java.util.*;
public class Aaaa {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//int num = scanner.nextInt();
String input = scanner.nextLine();
//System.out.println(num);
System.out.println("입력한 사람은");
switch (input) {
case "kim":
System.out.println("대한민국 국적입니다");
break;
case "smith":
System.out.println("미국 국적입니다");
break;
case "jonadan":
System.out.println("가나 국적입니다");
break;
default:
System.out.println(input + " 번은 해당이 없는 숫자입니다");
break;
}
}
}
result
smith
입력한 사람은
미국 국적입니다
JDK 14 이상 부터는 아래와 같은 형식으로 사용할 수 있다
import java.util.*;
public class Aaaa {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//int num = scanner.nextInt();
String[] inputList = {"kim", "smith", "jonadan"};
String input = scanner.nextLine();
//System.out.println(num);
System.out.println("입력한 사람은");
switch (input) {
case "kim" -> System.out.println("대한민국 국적입니다");
case "smith", "jonadan" -> System.out.println("미국 또는 가나 국적입니다");
default -> System.out.println(input + " 번은 해당이 없는 숫자입니다");
}
}
}
// : 대신 -> 의 사용으로 break 생략
// , 를 사용하여 여러 조건을 한번에 처리할 수 있다
▷ 초기화 : for문을 시작할 때 한 번만 실행되며, 사용할 변수의 초기값을 지정해 준다 ▷ 조건식 : 반복 여부를 결정하는 조건으로 값이 true면 실행블록을 진행하고, false면 실행블록을 진행하지 않고 for문을 끝낸다 ▷ 증감식 : for문에서 지정한 변수의 값을 증감시켜 반복 횟수를 결정한다 (++ : 값을 1씩 증가시킨다)
public class Ffile {
public static void main(String[] args) {
int s=0;
for(int i=0; i < 10; i++){
s = s + i;
}
System.out.println(s);
}
}
result
45
for문의 초기화 식은 생략 가능할 경우 생략할 수 있다
for문은 둘 이상의 초기화식과 조건식, 증감식을 사용할 수 있다
public class Ffile {
public static void main(String[] args) {
int s = 0;
int s1 = 0;
for(int i=0, j=100; i < 10 && j<200; i++, j++){
s = s + i;
s1= s1 + j;
}
System.out.println(s);
System.out.println(s1);
}
}
result
45
1045
2) enhanced for문(향상된 for문)
타입에 따른 값을 배열로 지정하여 주었을 때 for문의 초기화 변수를 지정하고 ':'을 사용하여 참조변수를 가져온다
참조변수의 값이 존재하면 반복하여 실행문을 진행한다
public class Ffile {
public static void main(String[] args) {
String[] s = {"kim", "kang", "lee", "choi"};
for(String name : s){
System.out.println("나의 성은 " + name + " 입니다");
}
}
}
result
나의 성은 kim 입니다
나의 성은 kang 입니다
나의 성은 lee 입니다
나의 성은 choi 입니다
public class Wfile {
public static void main(String[] args) {
int n = 0, s = 0;
while(n <= 9){
s = s + n; //s += n 으로 작성할 수 있다
n++;
}
System.out.println(s);
}
}
result
45
//n이 9보다 작거나 같을때까지 반복하여 연산을 수행한다
Scanner scanner = new Scanner(System.in); //System.in : 화면입력 명령어
import java.util.*;
public class Aaaa {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//int num = scanner.nextInt();
String input = scanner.nextLine();
//System.out.println(num);
System.out.println(input);
}
}
result
kim //입력 후 enter
kim
import java.util.StringTokenizer;
public class Aaaa {
public static void main(String[] args) {
String abc = "SrtingTokenizer/result/is/token";
StringTokenizer bcd = new StringTokenizer(abc, "/");
while (bcd.hasMoreTokens()) {
String cde = bcd.nextToken();
System.out.print(" "+cde);
}
}
}
result
SrtingTokenizer result is token
더 검색할 문자열이 있는지 확인하는 hasMoreTokens 메서드와 다음 문자열을 가져오는 nextToken 메서드를 사용한다
2. StringTokenizer 메서드
int countTokens()
전체 token의 개수가 아닌 현재 남아있는 token 개수를 반환한다
boolean hasMoreElements() boolean hasMoreTokens()
둘다 동일한 값을 반환한다 현재 위치 뒤에 있는 문자열에서 하나 이상의 토큰을 사용할 수 있는 경우 True를 반환하고 그렇지 않으면 false를 반환한다
Object nextElement() String nextToken()
두 개의 메서드는 같은 객체를 반환하지만 반환형은 다르다 nextElement는 Object를 반환한다 nextToken은 String을 반환한다
public class Example { //Example class 선언
int a = 10; //필드
if a(){ }; //메서드
void printX() {...} //메서드
Example exe = new Exanple() //생성자
class Example2 {...} //이너 클래스
}
2) 클래스 추가 정의
클래스 == 데이터 + 함수 의 결합으로 사용할 수 있다 - 클래스 : 데이터와 함수의 결합 (구조체 + 함수) - 데이터는 변수와 같다 - 함수는 메서드와 같으며, 명령문의 집합체이다 - 함수의 작업은 데이터를 재료로 계산을 한다 - 데이터와 함수는 상호 관련성이 있으므로 결합하여 사용하는 것이 용이하다
데이터 저장의 변화는 다음과 같다 - 변 수 : 하나의 데이터를 저장할 수 있는 공간 - 배 열 : 같은 종류의 여러 데이터를 하나로 저장할 수 있는 공간 - 구조체 : 서로 다른 종류의 데이터라도 관련성이 있다면 하나로 저장할 수 있는 공간 - 클래스 : 데이터와 함수의 결합 (구조체 + 함수)
클래스는 사용자 정의 타입이다 - 원하는 타입을 사용자가 직접 만들 수 있다 - ex) 사용자 정의 변수를 통하여 코그의 단순화한 경우
2. 객체
실제로 존재하는 사물이나 개념, 논리 등을 말한다
객체가 가지는 기능과 속성에 따라 사용되는 용도가 다르다
실제 존재물 HW을 컴퓨터가 실행할 수 있는 SW 로 만들는 과정에서 사용된다
모든 인스턴스를 대표하는 일반적 용어이다
클래스를 객체로 생성하기 위해서 메모리로 할당하는 과정을 인스턴스화 한다고 말한다
1) 구성요소
객체 = 속성(변수) + 기능(메서드) 로 구성된다
객체를 사용하기 위해서는 속성과 기능을 부여해 줘야 한다
HW를 분석하여 SW화 하는 방법이다
2) 객체의 생성
클래스명 ; //클래스를 선언한다
클래스명 변수명 ; //클래스의 객체를 참조하기 위한 변수(참조변수)를 선언한다
변수명 = new 클래스명( ) ; //클래스 인스턴스를 생성하여 참조변수에 주소를 저장한다. 메모리에 참조변수 영역을 확보한 객체가 생성된다
2와 3은 다음과 같이 줄여서 사용할 수 있다 -> Audio audio = new Audio( );
ex) 1 class Audio; class Audio;
2 Audio audio; -> Audio audio = new Audio( );
3 audio = new Audio( );
3) 객체의 사용
클래스 작성 -> 객체 생성 -> 객체 사용 의 순서로 작성한다 - 클래스는 객체를 만들기 위한 설계도 역활이며, 객체는 객체를 사용하기 위하여 생성된다.
객체의 사용은 변수와 메서드를 사용한다는 의미이다
객체 사용 시에는 참조변수를 필히 호출하여 사용한다 - 참조변수.멤버변수 = 값 ;//참조변수 객체의 멤버변수에 값을 저장하는 경우에 사용한다 ex) audio.volume = 50 ; //오디오 객체의 볼륨변수의 값을 50으로 저장한다
- 참조변수.메서드변수( ) ;-> 참조변수 객체의 메서드변수를 호출하여 실행하는 경우에 사용한다 ex) audio.volumeup( ) ; //오디오 객체의 볼륨변수에 있는 기능을 실행시킨다 (volume++)
변수가 생성되면 기본값으로 초기화된다
ex1)
ex2)
ex3)
class Audio {
public static void main(String arg[]){
Audio audio = new Audio( );
audio.model;//변수 사용
audio.power = power; //전원 true
audio.volume = 50; //현재 볼륨 입력
audio.volumeup( ); //메서드 사용, 볼륨 +1 상승 = 50+1 = 51
System.out.println("현재의 볼륨은" + audio.volume + "입니다");
}
}
class audio {
String model;
Int volume;
boolean power = power;
audio.model( ) {“white”;}
audio.power( ) {power = !power;}
audio.volumeup( ) {volume++;}
audio.volumedown( ) {volume--;}
}
result
"현재의 볼륨은 51입니다
import java.util.Scanner; //Scanner 유틸 호출
//간이계산기 프로그램
public class Calculator {
public static void main(String[] args) { //maun 메서드 선언
Scanner scan = new Scanner(System.in); //Scanner 객체 생성 : 외부입력
System.out.println("첫 번째 숫자를 입력하세요."); //콘솔출력
String no1 = scan.nextLine(); //첫 번째 숫자 입력
System.out.println("사칙연산자를 입력하세요.");
String op = scan.nextLine(); //사칙연산자 입력
System.out.println("두 번째 숫자를 입력하세요.");
String no2 = scan.nextLine(); //두 번째 숫자 입력
int num1 = Integer.parseInt(no1); //입력받은 첫 번째 문자를 숫자형으로 변환
int num2 = Integer.parseInt(no2); //입력받은 두 번째 문자를 숫자형으로 변환
int result;
if(op.equals("+")) { //덧셈 연산
result = num1 + num2;
}
else if(op.equals("-")) { //뺄셈 연산
result = num1 - num2;
}
else if(op.equals("/")) { //나누기 연산
result = num1 / num2;
}
else{
result = num1 * num2; //곱하기 연산
}
System.out.println(no1 + " " + op + " " + no2 + " = " + result); // 결과값 출력
}
}
3. 소스파일과 클래스의 관계
하나의 소스 파일에는 하나의 public class만 존재해야 한다
또한, 하나의 소스 파일에는 하나의 클래스만 존재하는 것을 권장한다
소스파일의 이름은 main 메서드가 있는 클래스의 이름과 일치해야 한다
하나의 소스 파일에 여러 개의 클래스가 존재할 경우 소스파일의 이름은 아래와 같이 사용한다
소스파일
클래스
내용
Hello1.java
public class Hello1 { } class Hello2 { }
public class가 있는 경우 소스파일의 이름은 반드시 public class 이름과 일치해야 한다
class Hello1 { } class Hello2 { }
public class가 없는 경우 소스파일의 이름은 Hello1, Hello2 어떤 것을 사용해도 상관없다
아래와 같은 경우는 오류가 발생한다
소스파일
클래스
내용
Hello1.java
public class Hello1 { } public class Hello2 { }
하나의 소스파일에 두 개 이상의 public class가 존재할 수 없다 각 클래스를 별도의 소스파일로 나눠서 저장하거나 class 중 한 개의 public를 삭제해야 한다
Hello2.java
public class Hello1 { } class Hello2 { }
소스파일의 이름과 public class의 이름이 일치하지 않는다 소스파일의 이름을 Hello1.java로 변경해야 한다
hello1.java
public class Hello1 { } class Hello2 { }
소스파일의 이름과 public class의 이름이 일치하지 않는다 소스파일의 이름은 대소문자도 일치해야 한다 소스파일의 이름을 대문자 H로 변경해야 한다
'String 참조변수 ; 참조변수 = "문자열"'의 형태로 선언 : 문자열 리터럴을 대입하는 방식
'String 참조변수 = "문자열"'의 형태로 선언 : 문자열 리터럴을 대입하는 방식
'String 참조변수 = new String("문자열")'의 형태로 선언 : 객체를 생성하고 문자열을 대입하는 방식
public class Grade {
public static void main(String[] args) {
String str;
str = "문자열";
System.out.println(str);
String str1 = "문자열1";
System.out.println(str1);
String str2 = new String("문자열2");
System.out.println(str2);
}
}
result
문자열
문자열1
문자열2
'String 참조변수 = "문자열"'의 형태로 선언
문자열 리터럴을 대입하는 방식의 주소값과 객체를 생성하는 방식의 주소값은 서로 다르다
그러므로, 문자열을 비교할 경우 등호"=" 대신 equals를 사용한다 ("=="은 저장공간의 주소를 비교하므로 문자열에 적합하지 않다)
public class Grade {
public static void main(String[] args) {
String str;
str = "문자열";
String str1 = "문자열";
String str2 = new String("문자열");
System.out.println(str==str1);
System.out.println(str==str2);
}
}
result
true
false
위에 코드에서 str==str1은 true로 같지만, str==str2는 false로 서로 다르다
3. String 특성
String 문자열은 내용을 변경할 수 없다
a = a+ b로 인하여 문자열 결합을 하였을 때 새로운 a의 저장공간이 생성된다
a = a + b의 결과가 "문자열1"이 아닌 "문자열1문자열2"로 출력되며, a라는 새로운 저장공간이 생성된다
a = "문자열1";
b = "문자열2";
a = a + b;
System.out.println(a);
result
문자열1문자열2
수식에 의한 새로운 저장공간의 생성은 데이터의 처리 속도를 지연시킨다
문자열 변환이 필요한 변수에는 StingBuffer 메서드를 사용하는 것이 편리하다
같은 내용의 문자열 리터럴은 하나만 만들어진다
String a = "abc";
String b = "abc";
String c = "abc";
//문자열이 동일하므로 "abc" 저장공간 1개만 생성된다
4. String 관련 대표 method
1) charAt( )
해당 문자열의 특정 인덱스에 해당하는 문자를 반환한다
해당 문자열의 길이보다 큰 인덱스나 음수를 전달하면, 오류가 발생한다
public class Grade {
public static void main(String[] args) {
String str =new String("charAt method");
System.out.println("문자열 : "+ str);// "문자열 : charAt method""
System.out.println(str.charAt(0));// 'c'
System.out.println(str.charAt(4));// 'A'
System.out.println(str.charAt(6));// ' '
System.out.println(str.charAt(12));// 'd'
System.out.println(str.charAt(13));// 'error'
System.out.println("\ncharAt() 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : charAt method
c
A
d
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 13
at java.base/java.lang.StringLatin1.charAt(StringLatin1.java:47)
at java.base/java.lang.String.charAt(String.java:693)
at Grade.main(Grade.java:9)
//13번째문자열이 인덱스를 벗어났다고 에러 표시
public class Grade {
public static void main(String[] args) {
String str =new String("charAt method");
System.out.println("문자열 : "+ str);// "문자열 : charAt method""
System.out.println(str.charAt(0));// 'c'
System.out.println(str.charAt(4));// 'A'
System.out.println(str.charAt(6));// ' '
System.out.println(str.charAt(12));// 'd'
//System.out.println(str.charAt(13));// 'error'
System.out.println("\ncharAt() 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : charAt method
c
A
d
charAt() 메서드 호출 후 문자열 : charAt method
//index 13을 주석 처리 후 정상 출력
2) compareTo( )
해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교
문자열을 비교할 때 대소문자를 구분하여 비교한다
두 문자열이 같다면 0을 반환
해당 문자열이 인수로 전달된 문자열보다 작으면 음수를, 크면 양수를 반환
- 문자열을 비교할 때 대소문자를 구분하지 않으려면 compareToIgnoreCase() 메서드를 사용
public class Grade {
public static void main(String[] args) {
String str =new String("concat");
System.out.println("문자열 : "+ str);
System.out.println(str.concat(" - method"));
System.out.println(str.concat(""));
System.out.println("concat() 메서드 호출 전 문자열 : "+ str);
}
}
result
문자열 : concat
concat - method
concat
concat() 메서드 호출 전 문자열 : concat
4) indexOf( )
해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환한다
문자열의 대소문자를 구분한다
만약 해당 문자열에 전달된 문자나 문자열이 포함되어 있지 않으면 -1을 반환한다
public class Grade {
public static void main(String[] args) {
String str =new String("indexOf-method");
System.out.println("문자열 : "+ str);
System.out.println(str.indexOf('o'));//소문자 'o'의 위치값
System.out.println(str.indexOf('O'));//대문자 'O'의 위치값
System.out.println(str.indexOf('a'));//소문자 'a'의 위치값
System.out.println(str.indexOf("-"));//특수문자 '-'의 위치값
System.out.println("indexOf() 메서드 호출 후 원본 문자열 : "+ str);
}
}
result
문자열 : indexOf-method
12
5
-1
7
indexOf() 메서드 호출 후 원본 문자열 : indexOf-method
5) trim( )
해당 문자열의 맨 앞과 맨 뒤에 포함된 모든 공백 문자를 제거한다
public class Grade {
public static void main(String[] args) {
String str =new String(" trim ");
System.out.println("문자열 : "+ str);
System.out.println(str +"end");
System.out.println("0"+str.trim()+"-end");
System.out.println("trim() 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : trim
trim end
0trim-end
trim() 메서드 호출 후 문자열 : trim
6) toLowerCase()와 toUpperCase()
toLowerCase() : 해당 문자열의 모든 문자를 소문자로 변환한다
toUpperCase() : 해당 문자열의 모든 문자를 대문자로 변환한다
public class Grade {
public static void main(String[] args) {
String str =new String("toUpper/LowerCase");
System.out.println("문자열 : "+ str);
System.out.println(str.toLowerCase());
System.out.println(str.toUpperCase());
System.out.println("두 메서드 호출 후 문자열 : "+ str);
}
}
result
문자열 : toUpper/LowerCase
toupper/lowercase
TOUPPER/LOWERCASE
두 메서드 호출 후 문자열 : toUpper/LowerCase
7) 그 외 String 메서드 설명
char charAt(int index)
해당 문자열의 특정 인덱스에 해당하는 문자를 반환함.
String(char[ ] value)
주어진 문자열(char[ ])을 갖는 String으로 변환한다
int compareTo(String str)
해당 문자열을 인수로 전달된 문자열과 사전 편찬 순으로 비교함.
int compareToIgnoreCase(String str)
해당 문자열을 인수로 전달된 문자열과 대소문자를 구분하지 않고 사전 편찬 순으로 비교함.
String concat(String str)
해당 문자열의 뒤에 인수로 전달된 문자열을 추가한 새로운 문자열을 반환함.
int indexOf(int ch)int indexOf(String str)
해당 문자열에서 특정 문자나 문자열이 처음으로 등장하는 위치의 인덱스를 반환함.
int indexOf(int ch, int fromIndex) int indexOf(String str, int fromIndex)
해당 문자열에서 특정 문자나 문자열이 전달된 인덱스 이후에 처음으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch)
해당 문자열에서 특정 문자가 마지막으로 등장하는 위치의 인덱스를 반환함.
int lastIndexOf(int ch, int fromIndex)
해당 문자열에서 특정 문자가 전달된 인덱스 이후에 마지막으로 등장하는 위치의 인덱스를 반환함.
String[] split(String regex)
해당 문자열을 전달된 정규 표현식(regular expression)에 따라 나눠서 반환함.
String substring(int beginIndex)
해당 문자열의 전달된 인덱스부터 끝까지를 새로운 문자열로 반환함.
String substring(int begin, int end)
해당 문자열을 전달된 정규 표현식(regular expression)에 따라 나눠서 반환함.
참조변수[ ]에 배열의 값이 각각 자동으로 대입되며, 대입되는 값의 번호를 인덱스(index)라고 한다
index 의 범위는 0부터 '배열길이-1' 까지이며 '-1'을 하는 이유는 '0'부터 시작하기 때문이다
ublic class Grade {
public static void main(String[] args) {
int a=0, b=1, c=2, d=3, e=4; //a,b,c,d,e의 초기값 선언-5개 변수 사용
System.out.println(a); //a의 결과값 출력
System.out.println(b); //b의 결과값 출력
System.out.println(c); //c의 결과값 출력
System.out.println(d); //d의 결과값 출력
System.out.println(e); //e의 결과값 출력
int[] score = new int[5]; //int 타입의 참조변수 score에 대해 5개의 저장공간을 확보
score[0] = 1;
score[1] = 2;
score[2] = 3;
score[3] = 4;
score[4] = 5;
System.out.println(score[0]);//score의 0번째 값
System.out.println(score[1]);//score의 1번째 값
System.out.println(score[2]);//score의 2번째 값
System.out.println(score[3]);//score의 3번째 값
System.out.println(score[4]);//score의 4번째 값
}
}
result
0
1
2
3
4
1
2
3
4
5
//다중 변수의 연속 사용과 한개의 변수에 여러 값 사용의 차이
위에서 int a=0 은 정수 a에 대한 메모리 공간 4byte 1개를 확보한다
score는 int[5] 를 통해서 메모리에 5개의 저장공간을 연속으로 확보한다
'타입[ ] + 참조변수 = new 타입[ ]{요소 값}' 처럼 사용하기도 한다
public class Grade {
public static void main(String[] args) {
int[] score = new int[]{1,2,3,4,5}; //int 타입의 참조변수 score에 대해 5개의 저장공간을 확보
System.out.println(score[0]);//score의 0번째 값
System.out.println(score[1]);//score의 1번째 값
System.out.println(score[2]);//score의 2번째 값
System.out.println(score[3]);//score의 3번째 값
System.out.println(score[4]);//score의 4번째 값
}
}
result
1
2
3
4
5
.length 를 사용하여 배열의 길이를 확인할 수 있다
4. 다차원 배열
1) 다차원 배열이란?
1차원 이상의 논리적인 구조를 가진다는 의미이다
배열이 배열의 요소로 사용되는 경우이다
2) 2차원 배열
'타입[ ][ ] + 참조변수' 또는 '타입 + 참조변수[ index1] [index2] ]' 의 형태로 선언한다
String [ ] Arry = new String [ index ] - index : 단어의 갯수를 입력한다 Arry [1] = " 단어 " ; Arry [2] = " 단어 " ;
※ 문자와 문자열을 담는 기호에 주의한다
// 선언 후 각 배열에 값을 넣어 초기화하는 경우
String[] str = new String[3];
str[0] = "Hello";
str[1] = "Java";
str[2] = "World";
// 선언과 동시에 값을 넣어 초기화하는 경우
String[] str = new String[] {"Hello", "Java", "World"};
String[] str = {"Hello", "Java", "World"}; // new String[] 생략 가능
// String Class를 사용해서 선언하고 초기화하면 이렇게 간편하게 만들 수 있다
String str = "Hello Java World";
6. 객체의 배열
객체 배열 == 참조변수 배열
객체는 참조변수의 집합이므로 객체배열 또한 참조변수의 배열과 같다
Speak 클래스의 참조변수 speak1, speak2, speak3는 아래와 같이 작성할 수 있다 Speak speak1, speak2, speak3; // Spaea[ ] speakArr = new Speak[3];
classExample{ publicstaticvoidmain(String[] args){ int num1 = 1; // num1(변수) , 1(값) int num2 = 2; int num3 = 3; ... } }
2. 변수 사용의 목적
메모리에 데이터 저장 공간을 확보하기 위해서 사용한다
여러 개발자와 협업을 진행할 경우 변수명을 붙여 데이터의 흐름을 상호간에 식별하여 소통할 수 있게 한다
데이터를 재사용할 경우 변수명만으로 사용할 수 있어서 용이하다
public class Grade {
public static void main(String[] args) {
int a=10, b=2, c=5; //a, b, c의 초기값
System.out.println(a+b); //a+b의 결과값 출력
System.out.println(a+b*c); //a+b*c의 결과값 출력
System.out.println(a+b+c); //a+b+c의 결과값 출력
System.out.println(a+b/c); //a+b/c의 결과값 출력
}
}
result
12
20
17
10
//a,b,c 값을 한번 선언함으로 여러가지 수식에 의한 값을 도출할 수 있다
2) 변수의 선언 타입
변수 a의 값을 10으로 선언한다면 10이 정수이므로 int 타입으로 선언할 수 있다
public class Grade {
public static void main(String[] args) {
int a=10; //10이 정수이므로 int 타입으로 선언
}
}
데이터의 종류에 따라 타입을 사용할 수 있다
public class Grade {
public static void main(String[] args) {
int a=10; //10이 정수이므로 int 타입으로 선언
float b=1.23456789F; //실수이므로 float 타입으로 선언
double c=1.23456789012345678D; //실수이므로 double 타입으로 선언
char d=75; //K를 유니코드 75로 char 타입으로 선언
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
result
10
1.2345679
1.2345678901234567
K
변수는 동일한 타입일 경우 타입은 한번만 선언해도 된다
public class Grade {
public static void main(String[] args) {
int a=10, b=20, c=30, d=40; //10이 정수이므로 int 타입으로 선언
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
result
10
20
30
40
변수의 값은 마지막에 적용된 변수의 값으로 저장된다
public class Grade {
public static void main(String[] args) {
int a=10; //a의 초기값
a=a+1; //a+1의 결과값
System.out.println(a); //최종 a+1의 결과값 a 출력
}
}
result
11
3. 변수의 종류
1) 클래스 변수
클래스 영역 내에서 static이 붙는 변수이다
클래스 정의에서 static 필드로 객체가 공유하는 변수이다
선언된 클래스 내부에서 사용 가능하다
클래스 외부에서의 사용은 접근제어자(access modifier)에 따라 다르다
2) 인스턴스 변수
클래스 정의에서 static이 아닌 필드로 객체가 소유하는 변수이다
객체는 인스턴스 변수의 묶음이다
객체가 생성되었을 때 생성된다
선언된 클래스 내부에서 사용 가능하다
클래스 외부에서의 사용은 접근제어자(access modifier)에 따라 다르다
3) 지역 변수
메서드 내부 또는 블록 내부에서 선언된 변수이다
메서드가 실행될 때 만들어지고 실행 후 사라진다
초기값을 지정한 후 사용해야 한다
변수 선언 시 접근 제어자를 사용하지 않는다
4) 파라미터
메서드 호출 시 전달하는 값을 저장하기 위한 변수이다
메서드가 실행될 때 만들어지고 실행 후 사라진다
4. 변수명
변수명은 영문자(대문자, 소문자)나 숫자, _, $ 를 사용할 수 있다
영문자는 대소문자가 구별되어 인식된다 - a와A는 다른 문자로 인식한다
자바에서 변수명은 일반적으로 카멜 케이스(camelCase)를 사용한다 - 카멜케이스는 두 번째 단어부터 대문자로 시작해 구분한다 - camelCase 는 낙타와 닮았다고 붙여진 명칭이다
데이터의 실제 값을 의미하며 4가지 타입으로 구분된다 - 정수 타입 : byte, short, int, long - 실수 타입 : float, double - 문자 타입 : char - 논리 타입 : Boolean
2)참조 타입(reference type)
데이터가 저장된 주소값을 의미한다
객체의 주소를 저장한다 - 참조타입변수 = 객체;
8개의 기본타입을 제외한 나머지를 참조 타입이라 한다
‘OO은 OO에서 찾을 수 있다’처럼 간접적으로 표현하는 데이터이다
class Example {
public static void main(String[] args) {
Object object = new Object(); //Object 객체를 참조변수 object에 저장한다
System.out.pringln(object); //참조변수 object가 저장하고 있는 값을 출력한다
}
}
상기 예제를 실행하면 다음과 같은 결과가 출력된다
System.out.println(object); 의 결과로 Object 객체에 대한 주소값을 출력한다
- int(4byte)보다 길다 - long 타입 변수에 값을 할당할 때 4byte의 데이터가 아니라 8byte의 데이터 값이라는 것을 컴파일러에 알려주기 위해 끝에 'L'을 붙인다
※ byte= 컴퓨터가 처리하는 정보의 기본 단위
1byte = 8bit = 하나의 문자를 나타내는 가장 작은 단위 1bit = 0 또는 1을 저장하는 최소 단위
2) 정수 타입의 특성
int는 정수형의 기본타입이다
정수를 입력하면 기본적으로 int 로 인식한다
ex1) byte 타입 변수 a에 값 120을 할당하면, byte 범위 내에 있으므로 컴파일러가 byte로 바꿔서 전달한다
byte 타입 변수 a1에 값 128을 할당하면, byte 범위 밖에 있으므로 컴파일러에서 오류가 발생한다
public class Main {
public static void main(String[] args){
Object object =new Object();
byte a = 120; //정상 실행
System.out.println(a);
byte a1 = 128; //byte 127의 범위를 벗어남으로 오류 발생
System.out.println(a1);
}
}
/*java: incompatible types: possible lossy conversion from int to byte 에러 코드 발생
( 호환이 안되는 유형: byte에서 int로 전환 가능하다 ) */
ex2) int 타입 변수 a에 값 120을 할당하면, int 범위 내에 있으므로 컴파일러가 byte로 바꿔서 전달한다
int 타입 변수 a1에 값 2147483648을 할당하면, int 범위 밖에 있으므로 컴파일러에서 오류가 발생한다
public class Main {
public static void main(String[] args){
Object object =new Object();
int a = 120;
System.out.println(a);
int a1 = 2147483648;
System.out.println(a1);
}
}
/*java: integer number too large 에러발생
(정수가 너무 크다 )*/
long타입은 입력값 마지막에 'L'을 붙여준다
변수의 값이 자료형의 범위를 넘을 경우 오버플로우(overflow)또는 언더플로우(underflow)가 발생하기 때문에 필요에 따라long과 같은 타입을 사용
ex3) long 타입 변수 a1에 값 2147483648+'l' 또는 2147483648+'L'을 할당하면, long 범위 내에 있으므로 컴파일러가 byte로 바꿔서 전달한다
public class Main {
public static void main(String[] args){
Object object =new Object();
int a = 2147483647;
System.out.println(a);
long a1 = 2147483648l;
//마지막에 'l'을 붙이지 않으면 java: integer number too large 에러 발생
System.out.println(a1);
long a2 = 2147483648L;
//마지막에 'l'을 붙여도 에러는 발생하지 않지만 'L'을 사용하여 준자
System.out.println(a2);
}
}
3) 오버플로우(Overflow)
자료형이 표현할 수 있는 범위 이상의 값을 표현한 경우 발생하는 현상
어떤 값이 byte형이고, byte형의 최댓값인 127을 값으로 가지는 경우, 이 값에 1을 더하면 128이 아니라 -128이 됩니다.
4) 언더플로우(Underflow)
자료형이 표현할 수 있는 범위 이하의 값을 표현한 경우 발생하는 현상
어떤 값이 byte형이고, byte 형의 최솟값인 -128을 값으로 가지는 경우, 이 값에 1을 빼면 -129가 아니라 127이 됩니다.
4. 실수 타입(float, double)
: 실수는 소숫점을 가지고 있는 값을 말한다
float
double
4byte = 32bit 소숫점 포함 9자리까지 표시
8byte = 64bit 소숫점 포함 18자리까지 표시
32비트 IEEE 754 부동 소수점
64비트 IEEE 754 부동 소수점
접미사 'f'를 사용
접미사 'd' 또는 'D'를 사용
정수가 아닌 소수점 단위의 값을 데이터로 가져올 때 사용한다
실수 타입의 값은 두가지 유형 모두 정확하지 않다
public class Grade {
public static void main(String[] args) {
float f1 = 12345.123456789012345678901234567890f;
double d1 =12345.123456789012345678901234567890;
System.out.println("float f1 : " + f1);
System.out.println("double d1 : " + d1);
}
}
result
float f1 : 12345.123
double d1 : 12345.123456789011
5. 논리 타입(boolean)
: 참(true) 또는 거짓(false)를 저장할 수 있는 타입이다
값으로 true 와 false를 가진다
컴퓨터 언어로 0과 1로 저장하며 1bit로 표현된다
JVM이 다루는 최소 단위가 1byte이므로 1byte의 크기를 차지한다
조건이 참 또는 거짓일 경우 사용한다
public class Grade {
public static void main(String[] args) {
boolean Rain = true;
if (Rain == false) {
System.out.println("우산을 들고 나간다");
}
else {
System.out.println("우산을 놓고 나간다");
}
System.out.println(Rain);
}
}
result
우산을 놓고 나간다
true
long longValue = 12345L;
float floatValue = longValue;
// float이 long보다 정밀하므로, 자동으로 타입이 변환된다
System.out.println(floatValue);
// 12345.0이 출력된다
2) 수동 변환
메모리 용량이 큰 타입에서 작은 타입으로 변환은 자동변환이 되지 않는다
큰 데이터 타입을 작은 데이터 타입의 변수에 저장하는 것을 캐스팅(casting)이라고 한다
캐스팅 연산자 ( )를 사용하며, 연산자 안에 변환하고자 하는 타입을 작성해 준다
int intValue = 128;
byte byteValue = (byte)intValue;
//int 타입으로 선언된 변수 intValue를 더 작은 단위인 byte로 변환
System.out.println(byteValue);
//출력값은 byte의 최대 표현 값인 127이 아니라 -128이다
//표현 범위를 넘으면 한 바퀴를 돌아 음수로 출력하기 때문이다
내부 클래스를 사용하면 외부 클래스의 멤버들에 쉽게 접근 할 수 있고, 코드의 복잡성을 줄일 수 있다
외부적으로 불필요한 데이터를 감출 수 있어 캡슐화(encapsulation)를 달성하는 데 유용하다
기본적으로 내부 클래스는 외부 클래스 내에 선언된다는 점을 제외하면 일반 클래스와 차이점이 없다 - 외부 클래스와 내부 클래스가 서로 연관되어 있을 때 사용의 편의성을 고려하여 만들어진 문법 요소이다
class Outer { // 외부 클래스
class Inner {
// 인스턴스 내부 클래스
}
static class StaticInner {
// 정적 내부 클래스
}
void run() {
class LocalInner {
// 지역 내부 클래스
}
}
}
내부 클래스의 종류는 세가지로 구분한다 - 인스턴스 내부 클래스 - 정적 내부 클래스 - 지역 내부 클래스
세 가지 내부 클래스는 변수가 선언 위치에 따라 인스턴스 변수, 클래스 변수, 그리고 지역 변수로 구분되는 것과 유사하게 그 위치를 중심으로 구분될 수 있다
각각의 유효범위(scope)와 특성이 변수의 구분과 매우 유사하다
내부클래스 종류
종 류
선언 위치
사용 가능한 변수
인스턴스 내부 클래스 (instance inner class)
외부 클래스의 멤버변수 선언위치에 선언(멤버 내부 클래스)
외부 인스턴스 변수 외부 전역 변수
정적 내부 클래스 (static inner class)
외부 클래스의 멤버변수 선언위치에 선언(멤버 내부 클래스)
외부 전역 변수
지역 내부 클래스 (local inner class)
외부 클래스의 메서드나 초기화블럭 안에 선언
외부 인스턴스 변수 외부 전역 변수
익명 내부 클래스 (anonymous inner class)
클래스의 선언과 객체의 생성을 동시에 하는 일회용 익명 클래스
외부 인스턴스 변수 외부 전역 변수
1) 인스턴스 내부 클래스(instance inner class)
인스턴스 내부 클래스는 외부 클래스의 내부에 위치해 있다
private 접근 제어자(해당 클래스 안에서만 접근 가능한 멤버에 사용)를 사용하고 있음에도 내부에서 외부 클래스의 인스턴스 변수와 정적 변수에 각각 접근하여 해당 값을 사용하고 있다
인스턴스 내부 클래스는 반드시 외부 클래스를 생성한 이후에 사용해야 한다
클래스의 생성과 상관없이 사용할 수 있는 정적 변수와 정적 메서드는 인스턴스 내부 클래스에서 선언할 수 없다
class Outer{
private int num = 1;
private static int sNum = 2;
private InnerClass innerClass;
public Outer(){
innerClass = new InnerClass();
}
class InnerClass{
int inNum = 10;
void innerMethod(){
System.out.println("Outer num = " + num + "(instance variable of outer class)");
System.out.println("Outer sNum = " + sNum + "(static variable of outer class");
}
}
public void testClass(){
innerClass.innerMethod();
}
}
public class MainClass {
public static void main(String[] args) {
Outer outer = new Outer();
System.out.println("call up inner class function used outer class");
outer.testClass();
}
}
2) 정적 내부 클래스
내부 클래스가 외부 클래스의 존재와 무관하게 정적 변수를 사용할 수 있는 것이 정적 내부 클래스이다
인스턴스 내부 클래스와 동일하게 클래스의 멤버 변수 위치에 정의하지만 static 키워드를 사용한다
class Outer1{
private int num = 3;
private static int sNum = 4;
void getPrint(){
System.out.println("Instance Method");
}
static void getPrintStatic(){
System.out.println("Static Method");
}
static class StaticInClass {
void test() {
System.out.println("Outer num = " + sNum + "(static variable of outer class)");
getPrintStatic();
}
}
}
public class StaticInnerClass {
public static void main(String[] args) {
Outer1.StaticInClass a = new Outer1.StaticInClass();
a.test();
}
}
4. 지역 내부 클래스(local inner class)
지역 내부 클래스는 클래스의 멤버가 아닌 메서드 내에서 정의되는 클래스이다
지역 변수와 유사하게 메서드 내부에서만 사용가능하다
일반적으로 메서드 안에서 선언 후에 바로 객체를 생성해서 사용한다
class Outer2{
int num = 5;
void test(){
int num2 = 6;
class LocalInClass{
void getPrint(){
System.out.println(num);
System.out.println(num2);
}
}
LocalInClass localInClass = new LocalInClass();
localInClass.getPrint();
}
}
public class LocalInnerClass {
public static void main(String[] args) {
Outer2 outer = new Outer2();
outer.test();
}
}
지역 내부 클래스 LocalInClass가 메서드 안에서 선언되고 생성된 후에 정의된 메서드를 호출하여 외부 클래스의 변수들을 출력하고 있다
내부 클래스는 기본적으로 개발자의 편의를 위해 서로 연관있는 클래스들을 연결시켜 주는 것이다