목차
Lambda 구문
Lambda는 어디에 사용됩니까?
메서드 참조
1. 정적 메소드 참조
2. 인스턴스 메소드 참조
생성자 메서드참조" >3. 생성자 메서드참조
访问局部变量
访问静态变量和成员变量
Lambda不能访问函数接口的默认方法
Lambda实践
Predicate接口
Function接口
Supplier接口
Consumer接口
Stream
Stream的创建
中间方法
过滤器(Filter)" >过滤器(Filter)
排序(Sorted)
Map)" >映射(Map
完结方法
匹配(Match)
收集(Collect)
计数(Count)
规约(Reduce)
并行Stream VS 串行Stream
懒操作
Java java지도 시간 Java Lambda 시작하기 자습서

Java Lambda 시작하기 자습서

Mar 23, 2017 am 10:55 AM

Lambda소개

Lambda는 함수형 프로그래밍의 기본 부분으로 오랫동안 다른 프로그래밍 언어(예: Scala)에서 널리 사용되어 왔지만, Java 필드 천천히, Lambda는 Java 8까지 지원되지 않았습니다.

수학적 정의는 무시하고 Lambda를 직접 알아봅시다. 람다 식은 기본적으로 익명 메서드이며 기본 구현은 호출동적 명령을 통해 익명 클래스를 생성합니다. 더 간단한 구문과 작성 스타일을 제공하므로 기능적 인터페이스를 표현식으로 대체할 수 있습니다. 어떤 사람들은 Lambda가 코드를 더 간결하게 만들 수 있으며 전혀 사용할 필요가 없다고 생각합니다. 물론 이 보기도 좋지만 중요한 것은 Lambda가 클로저를 제공한다는 것입니다. 자바. Lamdba의 컬렉션 지원 덕분에 멀티 코어 프로세서 조건에서 Lambda를 통한 컬렉션 순회 성능이 크게 향상되었습니다. 또한 데이터 흐름 방식으로 컬렉션을 처리할 수 있다는 점은 매우 매력적입니다.

Lambda 구문

Lambda의 구문은 매우 간단하며 다음 구조와 유사합니다.

(parameters) -> expression
로그인 후 복사

또는

(parameters) -> { statements; }
로그인 후 복사

Lambda 표현식은 세 부분으로 그룹화됩니다. 은 다음과 같습니다.

  1. 매개변수: 메소드의 형식 매개변수 목록과 유사하게 여기의 매개변수는 기능적 인터페이스의 매개변수입니다. 여기서 매개변수 유형은 명시적으로 선언되거나 선언되지 않고 JVM에 의해 암시적으로 추론될 수 있습니다. 또한, 추론된 유형이 하나만 있는 경우에는 괄호를 생략할 수 있습니다.

  2. ->: "~에 사용된다"라는 의미로 이해 가능

  3. 메서드 본문: 표현식 또는 코드 블록일 수 있으며 기능적 인터페이스에서 메서드를 구현합니다. 코드 블록은 값을 반환하거나 아무것도 반환하지 않을 수 있습니다. 여기서 코드 블록은 메서드의 메서드 본문과 동일합니다. 표현식인 경우 값을 반환하거나 아무것도 반환하지 않을 수도 있습니다.

다음 예를 통해 설명합니다.

//示例1:不需要接受参数,直接返回10
()->10

//示例2:接受两个int类型的参数,并返回这两个参数相加的和
(int x,int y)->x+y;

//示例2:接受x,y两个参数,该参数的类型由JVM根据上下文推断出来,并返回两个参数的和
(x,y)->x+y;

//示例3:接受一个字符串,并将该字符串打印到控制到,不反回结果
(String name)->System.out.println(name);

//示例4:接受一个推断类型的参数name,并将该字符串打印到控制台
name->System.out.println(name);

//示例5:接受两个String类型参数,并分别输出,不反回
(String name,String sex)->{System.out.println(name);System.out.println(sex)}

//示例6:接受一个参数x,并返回该该参数的两倍
x->2*x
로그인 후 복사

Lambda는 어디에 사용됩니까?

[기능적 인터페이스][1]에서 우리는 대상이 람다 식의 유형은 기능적 인터페이스입니다. 모든 람다는 특정 기능적 인터페이스를 통해 주어진 유형과 일치될 수 있습니다. 따라서 람다 표현식은 대상 유형과 일치하는 모든 위치에서 사용할 수 있습니다. 람다 표현식은 기능적 인터페이스의 추상 함수 설명과 동일한 매개변수 유형을 가져야 하며, 해당 반환 유형도 추상 함수의 반환 유형과 호환되어야 합니다. 발생할 수 있는 예외도 함수의 설명 범위로 제한됩니다.

다음으로 사용자 정의 기능 인터페이스의 예를 살펴보겠습니다.

  @FunctionalInterface
  interface Converter<F, T>{

      T convert(F from);

}
로그인 후 복사

먼저 기존 방식으로 인터페이스를 사용합니다.

  Converter<String ,Integer> converter=new Converter<String, Integer>() {
            @Override
            public Integer convert(String from) {
                return Integer.valueOf(from);
            }
        };

       Integer result = converter.convert("200");
        System.out.println(result);
로그인 후 복사

분명히 문제가 없습니다. 다음 단계는 Lambda가 등장하는 단계입니다. Lambda를 사용하여 Converter 인터페이스를 구현합니다:

Converter<String ,Integer> converter=(param) -> Integer.valueOf(param);
        Integer result = converter.convert("101");
        System.out.println(result);
로그인 후 복사

위의 예를 통해 Lambda의 사용법을 간단하게 이해했다고 생각합니다. Runnable 데모:

과거에는 다음과 같은 코드를 작성할 수 있었습니다.

new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello lambda");
            }
        }).start();
로그인 후 복사

경우에 따라 익명 클래스가 많으면 코드가 지저분해 보일 수 있습니다. 이제 Lambda를 사용하여 간결하게 만들 수 있습니다.

new Thread(() -> System.out.println("hello lambda")).start();
로그인 후 복사

메서드 참조

메서드 참조는 Lambda 표현식을 작성하는 단순화된 방법입니다. 참조된 메서드는 실제로 Lambda 표현식의 메서드 본문을 구현한 것입니다. 구문 구조는 다음과 같습니다.

ObjectRef::methodName
로그인 후 복사

왼쪽은 클래스 이름 또는 인스턴스 이름일 수 있고, 가운데는 메서드 참조 기호 ":: "이고 오른쪽은 해당 메소드 이름입니다. 메소드 참조는 세 가지 범주로 나뉩니다.

1. 정적 메소드 참조

경우에 따라 다음과 같은 코드를 작성할 수 있습니다.

public class ReferenceTest {
    public static void main(String[] args) {
        Converter<String ,Integer> converter=new Converter<String, Integer>() {
            @Override
            public Integer convert(String from) {
                return ReferenceTest.String2Int(from);
            }
        };
        converter.convert("120");

    }

    @FunctionalInterface
    interface Converter<F,T>{
        T convert(F from);
    }

    static int String2Int(String from) {
        return Integer.valueOf(from);
    }
}
로그인 후 복사

정적 참조를 사용하면 더 간결한 코드:

 Converter<String, Integer> converter = ReferenceTest::String2Int;
 converter.convert("120");
로그인 후 복사

2. 인스턴스 메소드 참조

다음과 같은 코드를 작성할 수도 있습니다:

public class ReferenceTest {
    public static void main(String[] args) {

        Converter<String, Integer> converter = new Converter<String, Integer>() {
            @Override
            public Integer convert(String from) {
                return new Helper().String2Int(from);
            }
        };
        converter.convert("120");
    }

    @FunctionalInterface
    interface Converter<F, T> {
        T convert(F from);
    }

    static class Helper {
        public int String2Int(String from) {
            return Integer.valueOf(from);
        }
    }
}
로그인 후 복사

마찬가지로 인스턴스 메소드 참조를 사용하면 더 간결해 보입니다.

  Helper helper = new Helper();
  Converter<String, Integer> converter = helper::String2Int;
  converter.convert("120");
로그인 후 복사

3. 생성자 메서드참조

이제 생성자 메서드의 참조를 보여드리겠습니다. 먼저 상위 클래스 Animal을 정의합니다:

    class Animal{
        private String name;
        private int age;

        public Animal(String name, int age) {
            this.name = name;
            this.age = age;
        }

       public void behavior(){

        }
    }
로그인 후 복사

다음으로 Animal의 두 하위 클래스인 Dog, Bird

public class Bird extends Animal {

    public Bird(String name, int age) {
        super(name, age);
    }

    @Override
    public void behavior() {
        System.out.println("fly");
    }
}

class Dog extends Animal {

    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void behavior() {
        System.out.println("run");
    }
}
로그인 후 복사

를 정의한 다음 팩토리 인터페이스를 정의합니다:

    interface Factory<T extends Animal> {
        T create(String name, int age);
    }
로그인 후 복사

다음, Dog 클래스와 Bird 클래스의 객체를 생성하는 데 여전히 전통적인 방법을 사용합니다.

        Factory factory=new Factory() {
            @Override
            public Animal create(String name, int age) {
                return new Dog(name,age);
            }
        };
        factory.create("alias", 3);
        factory=new Factory() {
            @Override
            public Animal create(String name, int age) {
                return new Bird(name,age);
            }
        };
        factory.create("smook", 2);
로그인 후 복사

두 객체를 생성하기 위해 10개 이상의 코드를 작성했지만 이제는 🎜>생성자를 사용합니다. 다음을 인용해 보세요:

  Factory<Animal> dogFactory =Dog::new;
  Animal dog = dogFactory.create("alias", 4);

  Factory<Bird> birdFactory = Bird::new;
  Bird bird = birdFactory.create("smook", 3);
로그인 후 복사

이렇게 하면 코드가 깨끗하고 깔끔하게 보일 것입니다. Dog::new를 통해 객체를 생성할 때 Factory.create 함수의 시그니처는 해당 생성자를 선택합니다.

Lambda의 도메인 및 액세스 제한

Domain은 Lambda 표현식의 매개변수 목록에 있는 매개변수가 Lambda 표현식의 범위(도메인) 내에서 유효합니다. 작업 Lambda 표현식 내에서 외부

변수 (로컬 변수, 클래스 변수, 정적 변수)에 액세스할 수 있지만 작업은 다양한 수준으로 제한됩니다.

访问局部变量

在Lambda表达式外部的局部变量会被JVM隐式的编译成final类型,因此只能访问外而不能修改。

public class ReferenceTest {
    public static void main(String[] args) {

        int n = 3;
        Calculate calculate = param -> {
            //n=10; 编译错误
            return n + param;
        };
        calculate.calculate(10);
    }

    @FunctionalInterface
    interface Calculate {
        int calculate(int value);
    }

}
로그인 후 복사

访问静态变量和成员变量

在Lambda表达式内部,对静态变量和成员变量可读可写。

public class ReferenceTest {
    public int count = 1;
    public static int num = 2;

    public void test() {
        Calculate calculate = param -> {
            num = 10;//修改静态变量
            count = 3;//修改成员变量
            return n + param;
        };
        calculate.calculate(10);
    }

    public static void main(String[] args) {

    }

    @FunctionalInterface
    interface Calculate {
        int calculate(int value);
    }

}
로그인 후 복사

Lambda不能访问函数接口的默认方法

java8增强了接口,其中包括接口可添加default关键词定义的默认方法,这里我们需要注意,Lambda表达式内部不支持访问默认方法。

Lambda实践

在[函数式接口][2]一节中,我们提到java.util.function包中内置许多函数式接口,现在将对常用的函数式接口做说明。

Predicate接口

输入一个参数,并返回一个Boolean值,其中内置许多用于逻辑判断的默认方法:

    @Test
    public void predicateTest() {
        Predicate<String> predicate = (s) -> s.length() > 0;
        boolean test = predicate.test("test");
        System.out.println("字符串长度大于0:" + test);

        test = predicate.test("");
        System.out.println("字符串长度大于0:" + test);

        test = predicate.negate().test("");
        System.out.println("字符串长度小于0:" + test);

        Predicate<Object> pre = Objects::nonNull;
        Object ob = null;
        test = pre.test(ob);
        System.out.println("对象不为空:" + test);
        ob = new Object();
        test = pre.test(ob);
        System.out.println("对象不为空:" + test);
    }
로그인 후 복사

Function接口

接收一个参数,返回单一的结果,默认的方法(andThen)可将多个函数串在一起,形成复合Funtion(有输入,有输出)结果,

    @Test
    public  void functionTest() {
        Function<String, Integer> toInteger = Integer::valueOf;
        //toInteger的执行结果作为第二个backToString的输入
        Function<String, String> backToString = toInteger.andThen(String::valueOf);
        String result = backToString.apply("1234");
        System.out.println(result);

        Function<Integer, Integer> add = (i) -> {
            System.out.println("frist input:" + i);
            return i * 2;
        };
        Function<Integer, Integer> zero = add.andThen((i) -> {
            System.out.println("second input:" + i);
            return i * 0;
        });

        Integer res = zero.apply(8);
        System.out.println(res);
    }
로그인 후 복사

Supplier接口

返回一个给定类型的结果,与Function不同的是,Supplier不需要接受参数(供应者,有输出无输入)

    @Test
    public void supplierTest() {
        Supplier<String> supplier = () -> "special type value";
        String s = supplier.get();
        System.out.println(s);
    }
로그인 후 복사

Consumer接口

代表了在单一的输入参数上需要进行的操作。和Function不同的是,Consumer没有返回值(消费者,有输入,无输出)

    @Test
    public void consumerTest() {
        Consumer<Integer> add5 = (p) -> {
            System.out.println("old value:" + p);
            p = p + 5;
            System.out.println("new value:" + p);
        };
        add5.accept(10);
    }
로그인 후 복사

以上四个接口的用法代表了java.util.function包中四种类型,理解这四个函数式接口之后,其他的接口也就容易理解了,现在我们来做一下简单的总结:

Predicate用来逻辑判断,Function用在有输入有输出的地方,Supplier用在无输入,有输出的地方,而Consumer用在有输入,无输出的地方。你大可通过其名称的含义来获知其使用场景。

Stream

Lambda为java8带了闭包,这一特性在集合操作中尤为重要:java8中支持对集合对象的stream进行函数式操作,此外,stream api也被集成进了collection api,允许对集合对象进行批量操作。

下面我们来认识Stream。

Stream表示数据流,它没有数据结构,本身也不存储元素,其操作也不会改变源Stream,而是生成新Stream.作为一种操作数据的接口,它提供了过滤、排序、映射、规约等多种操作方法,这些方法按照返回类型被分为两类:凡是返回Stream类型的方法,称之为中间方法(中间操作),其余的都是完结方法(完结操作)。完结方法返回一个某种类型的值,而中间方法则返回新的Stream。中间方法的调用通常是链式的,该过程会形成一个管道,当完结方法被调用时会导致立即从管道中消费值,这里我们要记住:Stream的操作尽可能以“延迟”的方式运行,也就是我们常说的“懒操作”,这样有助于减少资源占用,提高性能。对于所有的中间操作(除sorted外)都是运行在延迟模式下。

Stream不但提供了强大的数据操作能力,更重要的是Stream既支持串行也支持并行,并行使得Stream在多核处理器上有着更好的性能。

Stream的使用过程有着固定的模式:

  1. 创建Stream

  2. 通过中间操作,对原始Stream进行“变化”并生成新的Stream

  3. 使用完结操作,生成最终结果
    也就是

创建——>变化——>完结
로그인 후 복사

Stream的创建

对于集合来说,可以通过调用集合的stream()或者parallelStream()来创建,另外这两个方法也在Collection接口中实现了。对于数组来说,可以通过Stream的静态方法of(T … values)来创建,另外,Arrays也提供了有关stream的支持。

除了以上基于集合或者数组来创建Stream,也可以通过Steam.empty()创建空的Stream,或者利用Stream的generate()来创建无穷的Stream。

下面我们以串行Stream为例,分别说明Stream几种常用的中间方法和完结方法。首先创建一个List集合:

List<String> lists=new ArrayList<String >();
        lists.add("a1");
        lists.add("a2");
        lists.add("b1");
        lists.add("b2");
        lists.add("b3");
        lists.add("o1");
로그인 후 복사

中间方法

过滤器(Filter)

结合Predicate接口,Filter对流对象中的所有元素进行过滤,该操作是一个中间操作,这意味着你可以在操作返回结果的基础上进行其他操作。

    public static void streamFilterTest() {
        lists.stream().filter((s -> s.startsWith("a"))).forEach(System.out::println);

        //等价于以上操作
        Predicate<String> predicate = (s) -> s.startsWith("a");
        lists.stream().filter(predicate).forEach(System.out::println);

        //连续过滤
        Predicate<String> predicate1 = (s -> s.endsWith("1"));
        lists.stream().filter(predicate).filter(predicate1).forEach(System.out::println);
    }
로그인 후 복사

排序(Sorted)

结合Comparator接口,该操作返回一个排序过后的流的视图,原始流的顺序不会改变。通过Comparator来指定排序规则,默认是按照自然顺序排序。

     public static void streamSortedTest() {
        System.out.println("默认Comparator");
        lists.stream().sorted().filter((s -> s.startsWith("a"))).forEach(System.out::println);

        System.out.println("自定义Comparator");
        lists.stream().sorted((p1, p2) -> p2.compareTo(p1)).filter((s -> s.startsWith("a"))).forEach(System.out::println);

    }
로그인 후 복사

映射(Map

结合Function接口,该操作能将流对象中的每个元素映射为另一种元素,实现元素类型的转换。

    public static void streamMapTest() {
        lists.stream().map(String::toUpperCase).sorted((a, b) -> b.compareTo(a)).forEach(System.out::println);

        System.out.println("自定义映射规则");
        Function<String, String> function = (p) -> {
            return p + ".txt";
        };
        lists.stream().map(String::toUpperCase).map(function).sorted((a, b) -> b.compareTo(a)).forEach(System.out::println);

    }
로그인 후 복사

在上面简单介绍了三种常用的操作,这三种操作极大简化了集合的处理。接下来,介绍几种完结方法:

完结方法

“变换”过程之后,需要获取结果,即完成操作。下面我们来看相关的操作:

匹配(Match)

用来判断某个predicate是否和流对象相匹配,最终返回Boolean类型结果,例如:

    public static void streamMatchTest() {
        //流对象中只要有一个元素匹配就返回true
        boolean anyStartWithA = lists.stream().anyMatch((s -> s.startsWith("a")));
        System.out.println(anyStartWithA);
        //流对象中每个元素都匹配就返回true
        boolean allStartWithA
                = lists.stream().allMatch((s -> s.startsWith("a")));
        System.out.println(allStartWithA);
    }
로그인 후 복사

收集(Collect)

在对经过变换之后,我们将变换的Stream的元素收集,比如将这些元素存至集合中,此时便可以使用Stream提供的collect方法,例如:

    public static void streamCollectTest() {
        List<String> list = lists.stream().filter((p) -> p.startsWith("a")).sorted().collect(Collectors.toList());
        System.out.println(list);

    }
로그인 후 복사

计数(Count)

类似sql的count,用来统计流中元素的总数,例如:

    public static void streamCountTest() {
        long count = lists.stream().filter((s -> s.startsWith("a"))).count();
        System.out.println(count);
    }
로그인 후 복사

规约(Reduce)

reduce方法允许我们用自己的方式去计算元素或者将一个Stream中的元素以某种规律关联,例如:

    public static void streamReduceTest() {
        Optional<String> optional = lists.stream().sorted().reduce((s1, s2) -> {
            System.out.println(s1 + "|" + s2);
            return s1 + "|" + s2;
        });
    }
로그인 후 복사

执行结果如下:

a1|a2
a1|a2|b1
a1|a2|b1|b2
a1|a2|b1|b2|b3
a1|a2|b1|b2|b3|o1
로그인 후 복사

并行Stream VS 串行Stream

到目前我们已经将常用的中间操作和完结操作介绍完了。当然所有的的示例都是基于串行Stream。接下来介绍重点戏——并行Stream(parallel Stream)。并行Stream基于Fork-join并行分解框架实现,将大数据集合切分为多个小数据结合交给不同的线程去处理,这样在多核处理情况下,性能会得到很大的提高。这和MapReduce的设计理念一致:大任务化小,小任务再分配到不同的机器执行。只不过这里的小任务是交给不同的处理器。

通过parallelStream()创建并行Stream。为了验证并行Stream是否真的能提高性能,我们执行以下测试代码:

首先创建一个较大的集合:

   List<String> bigLists = new ArrayList<>();
        for (int i = 0; i < 10000000; i++) {
            UUID uuid = UUID.randomUUID();
            bigLists.add(uuid.toString());
        }
로그인 후 복사

测试串行流下排序所用的时间:

    private static void notParallelStreamSortedTest(List<String> bigLists) {
        long startTime = System.nanoTime();
        long count = bigLists.stream().sorted().count();
        long endTime = System.nanoTime();
        long millis = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
        System.out.println(System.out.printf("串行排序: %d ms", millis));

    }
로그인 후 복사

测试并行流下排序所用的时间:

    private static void parallelStreamSortedTest(List<String> bigLists) {
        long startTime = System.nanoTime();
        long count = bigLists.parallelStream().sorted().count();
        long endTime = System.nanoTime();
        long millis = TimeUnit.NANOSECONDS.toMillis(endTime - startTime);
        System.out.println(System.out.printf("并行排序: %d ms", millis));

    }
로그인 후 복사

结果如下:

串行排序: 13336 ms
并行排序: 6755 ms
로그인 후 복사

看到这里,我们确实发现性能提高了约么50%,你也可能会想以后都用parallel Stream不久行了么?实则不然,如果你现在还是单核处理器,而数据量又不算很大的情况下,串行流仍然是这种不错的选择。你也会发现在某些情况,串行流的性能反而更好,至于具体的使用,需要你根据实际场景先测试后再决定。

懒操作

上面我们谈到Stream尽可能以延迟的方式运行,这里通过创建一个无穷大的Stream来说明:

首先通过Stream的generate方法来一个自然数序列,然后通过map变换Stream:

 //递增序列
  class NatureSeq implements Supplier<Long> {
        long value = 0;

        @Override
        public Long get() {
            value++;
            return value;
        }
    }

  public  void streamCreateTest() {
        Stream<Long> stream = Stream.generate(new NatureSeq());
        System.out.println("元素个数:"+stream.map((param) -> {
            return param;
        }).limit(1000).count());

    }
로그인 후 복사

执行结果为:

元素个数:1000
로그인 후 복사

我们发现开始时对这个无穷大的Stream做任何中间操作(如:filter,map等,但sorted不行)都是可以的,也就是对Stream进行中间操作并生存一个新的Stream的过程并非立刻生效的(不然此例中的map操作会永远的运行下去,被阻塞住),当遇到完结方法时stream才开始计算。通过limit()方法,把这个无穷的Stream转为有穷的Stream。

위 내용은 Java Lambda 시작하기 자습서의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

자바의 제곱근 자바의 제곱근 Aug 30, 2024 pm 04:26 PM

자바의 제곱근 안내 여기서는 예제와 코드 구현을 통해 Java에서 Square Root가 어떻게 작동하는지 설명합니다.

자바의 완전수 자바의 완전수 Aug 30, 2024 pm 04:28 PM

Java의 완전수 가이드. 여기서는 정의, Java에서 완전 숫자를 확인하는 방법, 코드 구현 예제에 대해 논의합니다.

Java의 난수 생성기 Java의 난수 생성기 Aug 30, 2024 pm 04:27 PM

Java의 난수 생성기 안내. 여기서는 예제를 통해 Java의 함수와 예제를 통해 두 가지 다른 생성기에 대해 설명합니다.

자바의 웨카 자바의 웨카 Aug 30, 2024 pm 04:28 PM

Java의 Weka 가이드. 여기에서는 소개, weka java 사용 방법, 플랫폼 유형 및 장점을 예제와 함께 설명합니다.

자바의 암스트롱 번호 자바의 암스트롱 번호 Aug 30, 2024 pm 04:26 PM

자바의 암스트롱 번호 안내 여기에서는 일부 코드와 함께 Java의 Armstrong 번호에 대한 소개를 논의합니다.

Java의 스미스 번호 Java의 스미스 번호 Aug 30, 2024 pm 04:28 PM

Java의 Smith Number 가이드. 여기서는 정의, Java에서 스미스 번호를 확인하는 방법에 대해 논의합니다. 코드 구현의 예.

Java Spring 인터뷰 질문 Java Spring 인터뷰 질문 Aug 30, 2024 pm 04:29 PM

이 기사에서는 가장 많이 묻는 Java Spring 면접 질문과 자세한 답변을 보관했습니다. 그래야 면접에 합격할 수 있습니다.

Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Java 8 Stream foreach에서 나누거나 돌아 오시겠습니까? Feb 07, 2025 pm 12:09 PM

Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

See all articles