天道酬勤,学无止境

Java 8中findAny()和findFirst()之间的区别(Difference between findAny() and findFirst() in Java 8)

问题

我对Java 8中Stream API的Stream#findAny()Stream#findFirst()有点困惑。

我了解的是,例如当与filter一起使用时,两者都会从流中返回第一个匹配的元素?

那么,为什么要用两种方法完成同一任务? 我想念什么吗?

回答1

我了解到的是,例如当与filter一起使用时,两者都会从流中返回第一个匹配的元素?

这不是真的。 根据javadoc,Stream#findAny():

返回一个Optional<T>描述流的一些元件或空Optional<T>如果流是空的。 该操作的行为明确地是不确定的。 可以自由选择流中的任何元素。 这是为了在并行操作中获得最佳性能。

而Stream.findFirst()将返回Optional<T>严格描述流的第一个元素。 Stream类没有.findOne()方法,因此我想您的意思是.findFirst()

回答2

不,两者都不会返回Stream的第一个元素。

从Stream.findAny()(强调我的):

返回一个Optional描述流的一些元件,或一个空Optional如果流是空的。

这是短路端子的操作。

该操作的行为明确地是不确定的。 可以自由选择流中的任何元素。 这是为了在并行操作中获得最佳性能。 代价是对同一源的多次调用可能不会返回相同的结果。 (如果需要稳定的结果,请改用findFirst() 。)

因此,简单地说,它可能会或可能不会选择Stream的第一个元素。

对于当前特定于Oracle的实现,我相信它将返回非并行管道中的第一个元素。 但是,在并行管道中,它并不总是执行例如

System.out.println(IntStream.range(0, 100).parallel().findAny());

我运行它时返回了OptionalInt[50] 。 无论如何,您一定不能依靠它。

回答3

findFirst返回流的第一个元素,但是findAny可以自由选择流中的任何元素。

List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");

Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();
Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny();

System.out.println(findFirst.get()); //Always print David
System.out.println(fidnAny.get()); //Print Jack/Jill/Julia :behavior of this operation is explicitly nondeterministic
回答4

在并行模式下, findAny不能保证顺序,但是findFirst可以保证顺序。

我写了一些代码片段来显示差异,请访问它

回答5

在流findFirst和findAny中返回第一个元素,不执行其余元素,但是在parallelStream中,说顺序是不可行的,而parallelStream执行集合的其余部分。

参考

时间1:25:00

回答6

我只是说,在使用时要注意findFirst()findAny()

从它们的Javadoc(此处和此处)开始,这两个方法都从流中返回一个任意元素-除非流具有遇到顺序,否则, findFirst()返回第一个元素,而findAny()将返回任何元素。

假设我们有包含ISBN和BOOK名称的自定义list 。 对于场景,请看以下示例:

public class Solution {
   private Integer ISBN;
   private String BookName;

public Solution(int i, String string) {
    ISBN =i;
    BookName = string;
}
//getters and setters
}

public static void main(String[] args) {
        List<Solution> Library = Arrays.asList(new Solution(12,"Java in Action"),new Solution(13,"Java 8"),new Solution(15,"Java 8 Features"),new Solution(16,"Java in Action"));
 System.out.println(Library.stream()
        .map(p->p.getBookName())
        .sorted(Comparator.reverseOrder())
        .findFirst());
    }

输出Optional[Java in Action]

在某些情况下,书名相同但ISBN号不同,在这种情况下,对书的排序和查找可能与findAny()非常相似,并且会给出错误的结果。 考虑这样一种情况,其中5本书被命名为“ Java参考”,但是具有不同的ISBN号,按名称findAny() findFirst()书将与findAny()产生相同的结果。

考虑以下情况:

 ISBN    Name Of book
+-----+------------------+
| 100 | Java-8 in Action |
+-----+------------------+
| 101 | Java-8 in Action |
+-----+------------------+
| 102 | Java-8 in Action |
+-----+------------------+
| 103 | Java-8 in Action |
+-----+------------------+
| 104 | Java-8 in Action |
+-----+------------------+

即使对BookByName进行排序,这里的findFirst()和findAny()也会给出相同的结果

详细文章:

回答7

[1]我开发了一个小代码来测试findAny和findFirst of stream。 我已经创建了1000万个伪数据并过滤了这些数据,并通过在两个流上同时使用并行流和顺序流来应用findAny和findFirst。

从小型实验中,我发现findAny和findFirst给出相同的结果,并且在顺序流中提供第一个结果。 但是我发现findAny不能保证每次在parallelStream中产生相同的结果,而findFirst可以保证无论是并行流还是顺序流,它总是产生相同的结果。

public class TestFilter {
static class Employee {
    String name;
    double salary;
    long id;

    public Employee(String name, long id, double salary) {
        this.name = name;
        this.id = id;
        this.salary = salary;
    }

    String genNextName() {
        return "Emp-" + (this.id + 1);
    }

    double genNextSalary() {
        return new Random().nextDouble() * 1000000;
    }

    long genNextId() {
        return this.id + 1;
    }

    @Override
    public String toString() {
        return this.id + " " + this.name + " " + this.salary + "\n";
    }
}

public static void main(String[] args) {
    List<Employee> employees = createDummyEmployee(10000000l);
    List<Employee> emps = null;
    long time = 0;
    for (int i = 0; i < 50; i++) {
        
        Optional<Employee> e1 = employees.stream()
                .filter(e -> e.name.endsWith("999"))
                .filter(e -> e.salary > 10000)
                .filter(e -> e.id % 2 == 1)
                .findAny();
        
        Optional<Employee> e2 = employees.stream()
                .filter(e -> e.name.endsWith("999"))
                .filter(e -> e.salary > 10000)
                .filter(e -> e.id % 2 == 1)
                .findFirst();
        
        Optional<Employee> pe1 = employees.parallelStream()
                .filter(e -> e.name.endsWith("999"))
                .filter(e -> e.salary > 10000).filter(e -> e.id % 2 == 1)
                .findAny();
        
        Optional<Employee> pe2 = employees.parallelStream()
                .filter(e -> e.name.endsWith("999"))
                .filter(e -> e.salary > 10000)
                .filter(e -> e.id % 2 == 1)
                .findFirst();

        System.out.print("FindAny without parallel : " + (e1.isPresent() ? e1.get().id +"": "null"));
        System.out.print(" | FindFirst without parallel : " + (e2.isPresent() ? e2.get().id +"": "null"));
        System.out.print(" | FindAny by Parallel : " + (pe1.isPresent() ? pe1.get().id +"": "null"));
        System.out.print(" | FindFirst by Parallel : " + (pe2.isPresent() ? pe2.get().id +"": "null"));
        System.out.println();
    }
}

public static List<Employee> createDummyEmployee(long n) {
    Employee e1 = new Employee("Emp-1", 1l, 1.0);
    return Stream.iterate(e1, (Employee e) -> new Employee(e.genNextName(), e.genNextId(), e.genNextSalary()))
            .limit(n).collect(Collectors.toList());
}

}

[实验结果] [1]:https://i.stack.imgur.com/HOZjA.png

回答8

如果Stream是无序的,则findFirst()findAny()相同。 但是当订购Stream时, findAny()会更好。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • Difference between findAny() and findFirst() in Java 8
    I am little confused between Stream#findAny() and Stream#findFirst() of the Stream API in Java 8. What I understood is that both will return the first matched element from the stream, for example, when used in conjunction with filter? So, why two methods for the same task? Am I missing something?
  • 详解Java8中流(Stream)的使用
    文章列表 一、回忆Lambda表达式二、什么是流1、流只能遍历一次2、外部迭代和内部迭代 三、流操作1、谓词筛选2、筛选各异元素3、截段流4、跳过元素5、map和flatMap6、查找和匹配7、归约reduce 写在前面: 我是「境里婆娑」。我还是从前那个少年,没有一丝丝改变,时间只不过是考验,种在心中信念丝毫未减,眼前这个少年,还是最初那张脸,面前再多艰险不退却。 写博客的目的就是分享给大家一起学习交流,如果您对 Java感兴趣,可以关注我,我们一起学习。 前言:还没接触过流的同学可以深入研究下此篇文章,让你在写代码过程中可以让你达到事半功倍效果。 一、回忆Lambda表达式 在学习流之前,我们先回忆一下Lambda表达式和函数式接口 使用 案例lambda例子对应函数式接口布尔表达式(List< String> list -> list.isEmpty())Predicate<(List< String>>创建对象() -> new Car()Supplier< Car>消费一个对象(Car car) -> System.out.println(car.getColor)Consumer< Car>从一个对象提取(String s) -> s.length()Function< String,Integer>合并两个值(int a,int b) ->a
  • Java 8 Stream API 入门者教程
    Java 8 Stream API 入门者教程 过往记忆大数据 过往记忆大数据 Java 8 给我们带来了一个新功能,也就是本文要介绍的 Stream API,它可以让我们以一种声明的方式处理数据。Stream 使用一种类似于 SQL 的语法来提供一种对 Java 集合运算和表达的高阶抽象。极大提高 Java 程序员的生产力,让程序员写出高效率、干净、简洁的代码。 Stream 创建 有很多方法可以创建不同源的 stream 实例,stream 实例一旦创建,将不会修改其源,因此我们从单个源创建多个 stream 实例。 Empty Stream 如果我们想创建一个空的 Stream,可以使用 empty() 方法,具体如下: Stream<String> iteblogEmptyStream = Stream.empty(); 通常在 streams 没有元素然后不想返回 null 的情况下使用: public Stream<String> streamOf(List<String> list) { return list == null || list.isEmpty() ? Stream.empty() : list.stream(); } 通过集合(Collection)创建 Stream Java 中的任何继承 Collection 接口的类都可以创建 Stream
  • 使用Java 8 Stream API查找枚举值(Finding enum value with Java 8 Stream API)
    问题 假设有一个名为Type的简单枚举定义如下: enum Type{ X("S1"), Y("S2"); private String s; private Type(String s) { this.s = s; } } 为给定的s找到正确的枚举是通过带有for循环的静态方法(假设该方法在枚举内部定义的)轻松完成的,例如: private static Type find(String val) { for (Type e : Type.values()) { if (e.s.equals(val)) return e; } throw new IllegalStateException(String.format("Unsupported type %s.", val)); } 我认为用Stream API表示的功能等效如下: private static Type find(String val) { return Arrays.stream(Type.values()) .filter(e -> e.s.equals(val)) .reduce((t1, t2) -> t1) .orElseThrow(() -> {throw new IllegalStateException(String.format("Unsupported type %s.", val));})
  • Difference between anyMatch and findAny in java 8
    I have an Array and want to perform some matching on it's element. I came to know that it could be done in two ways in java 8 : String[] alphabet = new String[]{"A", "B", "C"}; anyMatch : Arrays.stream(alphabet).anyMatch("A"::equalsIgnoreCase); findAny : Arrays.stream(alphabet).filter("a"::equalsIgnoreCase) .findAny().orElse("No match found")); As I can understand both are doing the same work. However, I could not found which one to prefer? Could someone please make it clear what is the difference between both of them.
  • 从Java 8流中断还是返回forEach?(Break or return from Java 8 stream forEach?)
    问题 当在Iterable使用外部迭代时,我们使用增强型for-each循环的break或return : for (SomeObject obj : someObjects) { if (some_condition_met) { break; // or return obj } } 我们如何在Java 8 lambda表达式中使用内部迭代来break或return : someObjects.forEach(obj -> { //what to do here? }) 回答1 如果需要,则不应使用forEach ,而应使用流中可用的其他方法之一。 哪一个取决于您的目标是什么。 例如,如果此循环的目标是找到与某个谓词匹配的第一个元素: Optional<SomeObject> result = someObjects.stream().filter(obj -> some_condition_met).findFirst(); (注意:这不会迭代整个集合,因为流是延迟计算的-它将在与条件匹配的第一个对象处停止)。 如果您只是想知道集合中是否存在条件为真的元素,则可以使用anyMatch : boolean result = someObjects.stream().anyMatch(obj -> some_condition_met); 回答2 这对于Iterable
  • Java8之stream
    前言:   Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。 1、特点: 不是数据结构,不会保存数据。不会修改原来的数据源,它会将操作后的数据保存到另外一个对象中。(保留意见:毕竟peek方法可以修改流中元素)惰性求值,流在中间处理过程中,只是对操作进行了记录,并不会立即执行,需要等到执行终止操作的时候才会进行实际的计算。即延迟执行。 2、Stream的操作步骤 3、创建流:(几种方法如下) /** * 创建流 */ @Test public void test01(){ /** * 集合流 * - Collection.stream() 穿行流 * - Collection.parallelStream() 并行流 */ List<String> list = new ArrayList<>(); Stream<String> stream1 = list.stream(); //数组流 //Arrays.stream(array) String[] strings = new
  • Java 8中的可选链接(Chaining Optionals in Java 8)
    问题 寻找一种链接可选项的方法,以便返回第一个存在的可选项。 如果不存在,则应返回Optional.empty() 。 假设我有几种这样的方法: Optional<String> find1() 我正在尝试将它们链接起来: Optional<String> result = find1().orElse( this::find2 ).orElse( this::find3 ); 但是当然不行,因为orElse期望一个值,而orElseGet期望一个Supplier 。 回答1 使用流: Stream.of(find1(), find2(), find3()) .filter(Optional::isPresent) .map(Optional::get) .findFirst(); 如果您需要懒惰地评估查找方法,请使用供应商函数: Stream.of(this::find1, this::find2, this::find3) .map(Supplier::get) .filter(Optional::isPresent) .map(Optional::get) .findFirst(); 回答2 您可以这样做: Optional<String> resultOpt = Optional.of(find1() .orElseGet(() -> find2() .orElseGet(
  • 通过谓词限制流(Limit a stream by a predicate)
    问题 是否存在Java 8流操作来限制(可能无限) Stream直到第一个元素与谓词不匹配之前? 在Java 9中,我们可以使用下面的示例中的takeWhile来打印所有小于10的数字。 IntStream .iterate(1, n -> n + 1) .takeWhile(n -> n < 10) .forEach(System.out::println); 由于Java 8中没有这样的操作,以一般方式实现它的最佳方法是什么? 回答1 操作takeWhile和dropWhile已添加到dropWhile 。您的示例代码 IntStream .iterate(1, n -> n + 1) .takeWhile(n -> n < 10) .forEach(System.out::println); 在JDK 9下编译和运行时,其行为将完全符合您的预期。 JDK 9已发布。 可从以下位置下载:JDK 9版本。 回答2 这样的操作应该可以与Java 8 Stream ,但它不一定能高效地完成-例如,你不一定能并行这样的操作,你一定要看看元素的顺序。 该API并没有提供一种简便的方法,但是最简单的方法可能是采用Stream.iterator() ,将Iterator包装为具有“ take-while”实现,然后返回到Spliterator然后一条Stream 。 或者-也许
  • 为什么flatMap()之后的filter()在Java流中是“不完全”的懒惰?(Why filter() after flatMap() is “not completely” lazy in Java streams?)
    问题 我有以下示例代码: System.out.println( "Result: " + Stream.of(1, 2, 3) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get() ); System.out.println("-----------"); System.out.println( "Result: " + Stream.of(1, 2, 3) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .flatMap(i -> Stream.of(i - 1, i, i + 1)) .filter(i -> { System.out.println(i); return true; }) .findFirst() .get() ); 输出如下: 1 Result: 1 ----------- -1 0 1 0 1 2 1 2 3 Result: -1 从这里我看到,在第一种情况下, stream确实表现得很懒惰-我们使用findFirst()所以一旦有了第一个元素,就不会调用过滤lambda了。 但是,在使用flatMap的第二种情况下,我们看到尽管找到了满足过滤条件的第一个元素(因为lambda始终返回true,所以它只是任何第一个元素)
  • 基本类型和引用类型之间有什么区别?(What's the difference between primitive and reference types?)
    问题 这是过去的考试问题,我想知道什么是原始类型和引用类型? 对于数组,我知道引用类型是由对象或变量组成的数组,而原始类型是仅使用int或字符串创建数组的类型。 (对?) 您认为您会如何回答测试中的问题并获得良好的信誉? 如果没有真正直接引用原始的ARRAY类型,有没有办法做到这一点? 还是您只用数组解释一下就可以了。 回答1 这些是Java中的原始类型: 布尔值字节短的烧焦整型长漂浮双倍的 所有其他类型都是引用类型:它们引用对象。 这是Java教程有关语言基础的第一部分。 回答2 从书OCA JAVA SE 7 就像男人和女人有根本的不同(根据《火星上的男人是男人》和《金星上的女人》的作者约翰·格雷所说),原始变量和对象引用变量在很多方面都存在差异。 基本区别在于,原始变量存储实际值,而参考变量存储它们所引用的对象的地址。 假设已经定义了一个Person类。 如果创建一个int变量a和一个对象引用变量person,它们将把它们的值存储在内存中,如图2.13所示。 int a = 77; Person person = new Person(); 回答3 原始数据类型: 由语言预先定义并由关键字命名总数= 8 布尔值烧焦字节短的整数长漂浮双倍的 参考/对象数据类型: 使用类的已定义构造函数创建用于访问对象任何参考变量的默认值为null
  • Android中“ @ id /”和“ @ + id /”之间的区别(Difference between “@id/” and “@+id/” in Android)
    问题 @id/和@+id/之间的区别是什么? 在@+id/ ,加号+指示创建新的资源名称并将其添加到R.java文件中,但是@id/呢? 从ID的文档中:引用Android资源ID ,不需要加号,但必须添加android包名称空间,如下所示: android:id="@android:id/list" 但是在下面的图像中,Eclipse不建议使用任何@android:id/ 。 @id/和@android:id/相同吗? 回答1 您可以使用@android:id/..来引用已经在Android系统中定义的Android resources ,而要访问在项目中定义/创建的资源,则可以使用@id/.. 更多信息 根据您在聊天室中所做的澄清,您说自己有这样的问题: 如果我们使用android:id="@id/layout_item_id" ,则无法使用。 而是@+id/起作用,所以这里有什么区别? 那是我最初的问题。 好吧,这取决于上下文,当您使用android:id的XML属性时,您要指定一个新的ID,并指示解析器(或称其为builder)在R.java创建一个新条目R.java ,因此您必须包含一个+号。 在另一种情况下,例如android:layout_below="@id/myTextView" ,则是指已创建的ID,因此解析器将此链接到R.java已创建的ID。
  • for循环中的i ++和++ i有什么区别? [复制](What is the difference between i++ & ++i in a for loop? [duplicate])
    问题 这个问题已经在这里有了答案: 循环中的前增量和后增量之间的区别? (23个答案) Java中的x ++和++ x之间有区别吗? (16个答案) 1年前关闭。 已锁定。 该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。 我刚刚开始学习Java,现在我进入了for循环语句。 我不明白++i和i++如何在for循环中工作。 它们如何在加法和减法等数学运算中工作? 回答1 它们都增加数字。 ++i等于i = i + 1 。 i++和++i非常相似,但不完全相同。 两者都会增加数字,但是++i在计算当前表达式之前增加数字,而i++在计算表达式之后增加数字。 int i = 3; int a = i++; // a = 3, i = 4 int b = ++a; // b = 4, a = 4 回答2 这是一个示例类: public class Increment { public static void main(String [] args) { for (int i = 0; i < args.length; ++i) { System.out.println(args[i]); } } } 如果我使用javap.exe反汇编此类,则会得到以下信息: Compiled from "Increment.java" public class
  • Java中“ char”和“ String”之间的区别(Difference between “char” and “String” in Java)
    问题 我正在阅读要尝试学习的Java书籍,但有一个问题。 我不明白char和String变量类型有什么区别。 例如, int和short ,内存中的字节和它们具有的数字区域之间存在差异。 但是char和String什么区别? 除了char使用(')和“ String”(“)。 PS:这是我的第一种“真实”编程语言。 (在学校里,为了编程课程,我学到了一种伪造的语言。) 回答1 char是一个字符。 String是零个或多个字符。 char是原始类型。 String是一个类。 char c = 'a'; String s = "Hi!"; 注意char的单引号和String双引号。 回答2 char表示单个字符。 在Java中,它是UTF-16字符。 String可以认为是一个字符数组。 因此,想象一下“ Android”字符串。 它由'A', 'n', 'd', 'r', 'o', 'i'以及'd'字符组成。 char是java中的原始类型, String是一个类,它封装了chars数组。 回答3 用外行术语来说, char是字母,而String是字母(或单词)的集合。 的区别'和"非常重要,因为'Test'是在Java中是非法的。 char是原始类型, String是类 回答4 如果您对与Java有关的任何内容有疑问,我建议您通读Oracle网站上托管的Java教程文档。
  • >>>和>>之间的区别(Difference between >>> and >>)
    问题 Java中>>>和>>运算符之间有什么区别? 回答1 >>是算术右移, >>>是逻辑右移。 在算术移位中,将扩展符号位以保留数字的符号性。 例如:用8位表示的-2将是11111110 (因为最高有效位的权重为负)。 使用算术移位将其右移一位将得到11111111或-1。 但是,逻辑上的右移并不关心该值是否可能表示一个带符号的数字。 它只是将所有内容移至右侧,并从左侧填充0。 使用逻辑移位将我们的-2右移一位将得到01111111 。 回答2 >>>是无符号移位; 它将插入0。 >>被签名,并将扩展符号位。 JLS 15.19移位运算符 移位运算符包括左移位<< ,有符号右移位>>和无符号右移位>>> 。 n>>s的值是n个带符号扩展名的s右移位。 n>>>s的值是n个零位移的s n右移位。 System.out.println(Integer.toBinaryString(-1)); // prints "11111111111111111111111111111111" System.out.println(Integer.toBinaryString(-1 >> 16)); // prints "11111111111111111111111111111111" System.out.println(Integer.toBinaryString(-1 >>> 16));
  • Apache HTTP Server和Apache Tomcat之间的区别? [关闭](Difference between the Apache HTTP Server and Apache Tomcat? [closed])
    问题 从目前的情况来看,这个问题不适合我们的问答形式。 我们希望答案得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意测验或进一步的讨论。 如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 8年前关闭。 Apache HTTP Server和Apache Tomcat在功能方面有什么区别? 我知道Tomcat是用Java编写的,而HTTP Server是用C编写的,但是除此之外,我真的不知道它们的区别。 它们有不同的功能吗? 回答1 Apache Tomcat用于部署Java Servlet和JSP。 因此,在您的Java项目中,您可以构建WAR(Web ARchive的缩写)文件,然后将其放在Tomcat的deploy目录中。 因此,基本上,Apache是​​服务于HTTP的HTTP服务器。 Tomcat是服务于Java技术的Servlet和JSP Server。 Tomcat包括Catalina,这是一个Servlet容器。 最后,servlet是Java类。 将JSP文件(类似于PHP,以及较旧的ASP文件)生成为Java代码(HttpServlet),然后由服务器将其编译为.class文件,并由Java虚拟机执行。 回答2 除了上面的好答案之外,我认为应该说Tomcat内置了它自己的HTTP服务器
  • Java中a + = 10和a = a + 10之间的区别? [复制](Difference between a += 10 and a = a + 10 in java? [duplicate])
    问题 这个问题已经在这里有了答案: 为什么Java的+ =,-=,* =,/ =复合赋值运算符不需要强制转换? (11个答案) 4年前关闭。 a += 10和a = a + 10都一样吗,或者它们之间有区别吗? 我在学习Java作业时遇到了这个问题。 回答1 正如您现在提到的强制转换...在这种情况下有所不同: byte a = 5; a += 10; // Valid a = a + 10; // Invalid, as the expression "a + 10" is of type int 在Java语言规范第15.26.2节中: 形式为E1 op= E2的复合赋值表达式等效于E1 = (T)((E1) op (E2)) ,其中T是E1的类型,不同之处在于E1仅被评估一次。 有趣的是,他们在规范中给出的示例: short x = 3; x += 4.6; 是有效的在Java中,但不是在C#...基本上C#中的编译器执行特殊壳体+ =和- =以确保表达是目标类型中的一个或是目标类型的范围内的文字。 回答2 没有区别,一个是另一个的简写。 甚至编译器也会为两者生成相同的指令。 编辑:正如我刚发现的那样,编译器不会为两者生成相同的代码。 看一下这个: dan$ cat Test.java public class Test { public static void main
  • Java中的throw和throws之间的区别? [复制](Difference between throw and throws in Java? [duplicate])
    问题 这个问题已经在这里有了答案: 异常处理:throw,throws和Throwable (8个答案) 6年前关闭。 任何人都可以通过示例清楚地说明Java异常处理中throw与throws之间的区别吗? 我曾尝试使用Google搜索,但无法得出结论。 请帮助 回答1 throws子句用于声明异常, throw关键字用于显式抛出异常。 如果在语法上比较明智,则throw后面跟一个实例变量, throws后面跟异常类名。 在方法体内使用关键字throw来调用异常,在方法声明(签名)中使用throws子句。 例如 扔 throw new Exception("You have some exception") throw new IOException("Connection failed!!") 抛出 public int myMethod() throws IOException, ArithmeticException, NullPointerException {} 您不能使用throw声明多个异常。 您可以声明多个异常,例如public void method()引发IOException,SQLException。 被检查的异常不能仅通过throw异常进行传播,因为它被显式地用于引发特定异常。 可以使用throws传播已检查的异常。 异常传播
  • getAttribute()和getParameter()之间的区别(Difference between getAttribute() and getParameter())
    问题 HttpServletRequest类中的getAttribute()和getParameter()方法之间有什么区别? 回答1 getParameter()返回http请求参数。 那些是从客户端传递到服务器的。 例如http://example.com/servlet?parameter=1 。 只能返回String getAttribute()仅用于服务器端-您在请求中填充可以在同一请求中使用的属性。 例如,您在Servlet中设置了一个属性,并从JSP中读取了该属性。 可以用于任何对象,而不仅仅是字符串。 回答2 通常,参数是最常见的字符串值,它是从客户端发送到服务器(例如,表单发布)并从Servlet请求中检索的。 令人沮丧的例外是ServletContext初始参数,该参数是在web.xml中配置并存在于服务器上的字符串参数。 属性是存在于指定范围内的服务器变量,即: application ,在整个应用程序的生命周期内都可用 session ,在会话的整个生命周期内可用 request ,仅在请求的生命周期内可用 page (仅适用于JSP),仅适用于当前的JSP页面 回答3 request.getParameter() 我们使用request.getParameter()提取请求参数(即通过发布html表单发送的数据)。 request.getParameter
  • 字符串replace()和replaceAll()之间的区别(Difference between String replace() and replaceAll())
    问题 除了以后使用正则表达式之外,java.lang.String的replace()和replaceAll()方法之间有什么区别? 对于像这样的简单替换,请替换. 与/ ,有什么区别吗? 回答1 在java.lang.String中, replace方法可以使用一对char或一对CharSequence (String是其子类,因此很高兴采用一对String)。 replace方法将替换所有出现的char或CharSequence 。 另一方面, replaceFirst和replaceAll的第一个String参数是正则表达式(regex)。 使用错误的功能可能会导致细微的错误。 回答2 问: java.lang.String方法replace()和replaceAll()之间有什么区别,除了后者使用正则表达式。 答:只是正则表达式。 他们都替换了所有:) http://docs.oracle.com/javase/8/docs/api/java/lang/String.html PS: 还有一个replaceFirst() (需要一个正则表达式) 回答3 replace()和replaceAll()替换String中所有出现的内容。 例子 我总是会找到一些有助于理解差异的示例。 代替() 使用replace(