Stream API

Jan 05, 2024
Stream API

Stream (DartPad, JAVA 비교)

DartPad

→ …list (전개연산자) 흩뿌려진 데이터가 널려있는 걸 타입으로 감싸면 복사 가능
notion image
  • map, filter
    • void main() { // map var newList = list.map((e) => e*100).toList(); // filter = where var list2 = list.where((e) => e<3).toList(); print(newList); print(list2); }
      웹사이트 f12에서 같은 방식으로 사용 방법
      notion image
      notion image
       
       

Java

  • 컬렉션에서 지원
    • public class CopyEx01 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(1); list.add(2); list.add(3); list.add(4); // 객체 복사 List<Integer> newList = new ArrayList<>(list); newList.add(5); System.out.println(list.size()); System.out.println(newList.size()); } }
      컬렉션 복사
      Stream의 순서
      Stream의 순서
      1. stream 흩뿌리기
      1. 가공(map, filter)
      1. collect 수집
      • map
        • public class CopyEx02 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4); List<Integer> newList = list.stream().map((i -> i*100)).toList(); // forEach newList.stream().forEach(i -> System.out.println(i)); } }
          forEach로 순회하면서 for문과 같은 출력 가능
      • filter
        • public class CopyEx03 { public static void main(String[] args) { List<Integer> list = Arrays.asList(1,2,3,4); List<Integer> newList = list.stream().filter(i->i<3).toList(); newList.stream().forEach(i -> System.out.println(i)); } }
 
  • 객체 복사 응용
    • class User{ private int id; private String name; private String tel; public User(int id, String name, String tel) { this.id = id; this.name = name; this.tel = tel; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", tel='" + tel + '\'' + '}'; } public int getId() { return id; } public String getName() { return name; } public String getTel() { return tel; } } public class CopyEx04 { public static void main(String[] args) { User u1= new User(1,"ssar","0102222"); // 통째로 복사 User u2 = new User(u1.getId(),u1.getName(),u1.getTel()); // 부분변경 복사 User u3 = new User(u1.getId(),u1.getName(),"0103333"); } }
      class User{ private int id; private String name; private String tel; public User(User user) { this.id = user.getId(); this.name = user.getName(); this.tel = user.getTel(); } public User(int id, String name, String tel) { this.id = id; this.name = name; this.tel = tel; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", tel='" + tel + '\'' + '}'; } public int getId() { return id; } public String getName() { return name; } public String getTel() { return tel; } } public class CopyEx04 { public static void main(String[] args) { User u1= new User(1,"ssar","0102222"); // 통째로 복사 User u2 = new User(u1); // 부분변경 복사는 동일 User u3 = new User(u1.getId(),u1.getName(),"0103333"); } }
      User 메소드로 묶어서 호출
      // Data Transfer Object class JoinDTO { private String username; // ssar private String password; private String email; public String getUsername() { return username; } public String getPassword() { return password; } public String getEmail() { return email; } public JoinDTO(String username, String password, String email) { this.username = username; this.password = password; this.email = email; } } class Member { private int no; private String username; private String password; private String email; private LocalDateTime createdAt; public Member(int no, JoinDTO dto) { this.no = no; this.username = dto.getUsername(); this.password = dto.getPassword(); this.email = dto.getEmail(); this.createdAt = LocalDateTime.now(); } public Member(int no, String username, String password, String email, LocalDateTime createdAt) { this.no = no; this.username = username; this.password = password; this.email = email; this.createdAt = createdAt; } @Override public String toString() { return "Member{" + "no=" + no + ", username='" + username + '\'' + ", password='" + password + '\'' + ", email='" + email + '\'' + ", createdAt=" + createdAt + '}'; } } public class CopyEx05 { public static void main(String[] args) { JoinDTO d1 = new JoinDTO("ssar", "1234","ssar@nate.com"); JoinDTO d2 = new JoinDTO("cos", "1234","cos@nate.com"); Member m1 = new Member(1, d1); Member m2 = new Member(2, d2); System.out.println(m1); System.out.println(m2); } }
      JoinDTO를 Member로 복사해서 출력
 
  • 예제
import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; public class StreamEx01 { public static void main(String[] args) { Map<String, Object> data = new HashMap<>(); data.put("name", "홍길동"); data.put("age", 20); Map<String, Object> data2 = new HashMap<>(); data.put("name", "장보고"); data.put("age", 15); Map<String, Object> data3 = new HashMap<>(); data.put("name", "이순신"); data.put("age", 30); List<Map<String, Object>> arr = Arrays.asList(data, data2, data3); List<Map<String, Object>> newArr = arr.stream().map(d -> { int newAge = (Integer) d.get("age") - 1; d.put("age", newAge); return d; }).toList(); newArr.stream().forEach(d -> { System.out.println(d.get("age")); }); } }
HashMap으로 stream 사용한 코딩
import java.util.Arrays; import java.util.List; class User { private String name; private int age; public void changeAge() { this.age = this.age - 1; } public User(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public int getAge() { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } } public class StreamEx02 { public static void main(String[] args) { // User 3명 만들기 User u1 = new User("홍길동", 20); User u2 = new User("장보고", 15); User u3 = new User("임꺽정", 30); List<User> arr = Arrays.asList(u1, u2, u3); List<User> newArr = arr.stream().map(u -> { u.changeAge(); return u; }).toList(); newArr.stream().forEach(user -> { System.out.println(user.getAge()); }); } }
class로 stream 사용한 코딩
 

보조 스트림

  • InputStream - 모두 출력
  • 하드디스크 입장에서 Input은 들고 오는 것
  • Application (프로그램) - 인간의 영역 / HW - 하드웨어
버퍼링 = 소비가 공급보다 느리거나 빠를 때
버퍼 = 소비와 공급의 속도가 맞지 않을 때 유실 데이터를 버퍼에 넣어둠
버퍼링 = 소비가 공급보다 느리거나 빠를 때 버퍼 = 소비와 공급의 속도가 맞지 않을 때 유실 데이터를 버퍼에 넣어둠
 
크기를 사용자가 지정하면 메모리 낭비 ⇒ 보조스트림 필요
크기를 사용자가 지정하면 메모리 낭비 ⇒ 보조스트림 필요
import java.io.IOException; import java.io.InputStream; // 보조스트림이 없는 코드 public class StreamEx01 { public static void main(String[] args) { InputStream input = System.in; try { int value = input.read(); System.out.println("받은 값: " + (char)value); } catch (IOException e) { throw new RuntimeException(e); } } }
ab를 입력하면 a만 읽고 b는 버려서 출력 (”받은 값: a” 으로 출력) ⇒ 보조스트림 필요
 
파일이 h를 먼저 들고오면 h가 지워지고 ‘e’,’l’,’l’이 옆으로 밀리면서 ‘o’가 들어온다.
보조스트림: 버퍼(물길)에 가둬 놓고 계속 소비
hello를 OS가 가져옴 → 버퍼가 비게 되고 HW로 이동 → output으로 출력
파일이 h를 먼저 들고오면 h가 지워지고 ‘e’,’l’,’l’이 옆으로 밀리면서 ‘o’가 들어온다. 보조스트림: 버퍼(물길)에 가둬 놓고 계속 소비 hello를 OS가 가져옴 → 버퍼가 비게 되고 HW로 이동 → output으로 출력
public class StreamEx02 { public static void main(String[] args) { InputStream in = System.in; // ir은 키보드에 연결된 객체 InputStreamReader ir = new InputStreamReader(System.in); // 보조스트림에 연결된 ir이 ch를 불러옴 char[] ch = new char[4]; try { ir.read(ch); for (char c : ch) { System.out.print(c + " "); } } catch (IOException e) { throw new RuntimeException(e); } } }
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; public class StreamEx03 { public static void main(String[] args) { // 보조 스트림을 버퍼로 만들기 // 통신에서는 System.in이 상대 컴퓨터의 소켓을 입력 InputStreamReader ir = new InputStreamReader(System.in); BufferedReader br = new BufferedReader(ir); try { String line = br.readLine(); System.out.println(line); } catch (IOException e) { throw new RuntimeException(e); } } }
import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; public class StreamEx04 { public static void main(String[] args) { // 모니터로 출력 BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); try { bw.write("Hello\n"); bw.write("Nice to meet you\n"); bw.flush(); } catch (IOException e) { throw new RuntimeException(e); } } }
통신은 한번 읽을 때 \n까지 읽음. readLine으로 읽기 때문에 \n이 없으면 통신이 못 읽어서 출력 X
💡
flush - 버퍼가 꽉 자치 않으면 소비하지 않기 때문에 강제로 소비하는 것
 
 
동시에 여러 개 사용 가능, 프로세스에 따라 스레드 개수 동일
동시에 여러 개 사용 가능, 프로세스에 따라 스레드 개수 동일
 
Share article

from-web-developer