【问题标题】:is there any function to set a value to the complete list in java是否有任何函数可以为java中的完整列表设置一个值
【发布时间】:2020-01-13 03:25:42
【问题描述】:

如何使用 List 在我的模型中添加每个属性值?这就是我的工作

这是我的对象:Student.java

public class Student {

private String userName;

private String firstName;

private boolean isActive;

// skip the getter setter
}

我确实调用数据库来获取学生列表,并且我想根据条件将所有用户的活动标志设置为真或假

我的模拟数据看起来像

Student studentList = new Student();
Student student1 = new Student();
student1.setUserName("skol");
student1.setFirstName("soumya");
studentList.add(student1);
Student student2 = new Student();
student1.setUserName("vrac");
student1.setFirstName("vivek");
studentList.add(student2);

所以现在不进行迭代我想将所有 isActive 标志设置为 true,在 java 中可以吗?

现在我正在做类似的事情

 studentList.parallelStream.forEach(stu -> {
 stu.setIsActive(true);
 }
 )

【问题讨论】:

  • 将静态添加到“isActive”。这将导致所有学生“共享”该单个字段。
  • 在流上调用forEach 正在迭代。与for 循环的效果相同。
  • 您认为流的工作原理是什么?他们无法在不迭代的情况下神奇地更改列表中的所有内容,它只是为您编写 for 循环。不,它不能神奇地跨多个内核并行执行 - 除非 N 非常大,否则您无论如何都不想这样做,否则设置线程和任务切换所花费的时间将超过并行化所获得的时间。对于一个简单的吸气剂,您需要 N 达到数十万甚至数百万才能获得任何收益。
  • studentList.forEach(stu -> stu.setIsActive(true)); 在 a) 表现力或 b) 性能方面有什么问题?你真的遇到过任何一种问题吗?唯一让我想知道的是“打电话给数据库以获取学生名单”的事情。数据库中的活动属性是否持久?然后,进行数据库调用以在数据库中的所有记录上设置标志。否则,明确的forEach也没什么问题。

标签: java arraylist java-8 java-stream


【解决方案1】:

你必须以一种或另一种方式迭代

所以现在不重复我想将所有isActive 标志设置为true,在java 中可以吗?

不,不是没有迭代。您必须访问每个对象并设置其属性(或调用设置其属性的方法)。

在 Java 中有多种迭代方式。您使用流找到了其中之一。普通的for 是较旧的传统方法。

至于您使用并行化流来使用多个内核,这只有在您拥有大量数据时才能提供显着的好处。我建议在您遇到已证明的问题之前不要进行并行化,并且测试已证明有好处,并且您肯定知道您的部署方案很可能在运行时经常有内核可用。

首先我们需要一个Student 类。

package work.basil.example;

public class Student
{
    // ---------|  Member Vars  |-------------------------

    private String name;
    private Boolean active;

    // ---------|  Constructors  |-------------------------

    public Student ( String name , Boolean active )
    {
        this.name = name;
        this.active = active;
    }

    // ---------|  Logic  |-------------------------

    public void activate ( )
    {
        this.active = Boolean.TRUE;
    }

    // ---------|  Object  |-------------------------

    @Override
    public String toString ( )
    {
        return "Student{ " +
                "name='" + name + '\'' +
                " | active=" + active +
                " }";
    }
}

实例化一些要使用的示例数据。

List < Student > students = List.of(
        new Student( "Alice" , Boolean.FALSE ) ,
        new Student( "Bob" , Boolean.FALSE ) ,
        new Student( "Carol" , Boolean.TRUE )
);

for-each 循环

带有 for-each 循环的循环。在我们进行更改之前和之后报告我们的 Student 对象列表。

System.out.println( "students = " + students );
for ( Student student : students )
{
    student.activate();
}
System.out.println( "students = " + students );

学生 = [学生{ name='Alice' |活动=假},学生{名称='鲍勃'|活动=假},学生{姓名='卡罗尔'|主动=真}]

学生 = [学生{ name='Alice' |活动=真},学生{名称='鲍勃'|活动=真},学生{姓名='卡罗尔'|主动=真}]

Stream::forEach循环

使用流循环。

我们编写了 activate 方法来始终将值切换为 TRUE 而无需参数。所以我们的 lambda 可以使用通过双冒号 :: 语法创建的 method reference。我们也可以编写一个带有 Boolean 参数的 lambda。

System.out.println( "students = " + students );
students.forEach( Student :: activate );
System.out.println( "students = " + students );

同样的效果。

学生 = [学生{ name='Alice' |活动=假},学生{名称='鲍勃'|活动=假},学生{姓名='卡罗尔'|主动=真}]

学生 = [学生{ name='Alice' |活动=真},学生{名称='鲍勃'|活动=真},学生{姓名='卡罗尔'|主动=真}]

【讨论】:

  • 解释得很好! @罗勒
【解决方案2】:

CASE #1 (With Iteration):在这种情况下,您不需要流来设置 isActive。遍历列表并将 isActive 设置为 true 应该可以解决问题。

 studentList.forEach(stu -> {
   stu.setIsActive(true);
 }

如果学生列表不大,ParallelStreams 可能会降低性能

CASE #2(无迭代):如上所述答案集 isActive=true 默认情况下

【讨论】:

    【解决方案3】:

    在您的模型中尝试将默认值设置为 true,如下所示,请让我知道它是否有效 -

    private boolean isActive = true;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-06
      • 1970-01-01
      • 2014-10-19
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      相关资源
      最近更新 更多