我有一个问题。
public class TestVO {
private String name;
private String id;
private int weight;
private int height;
public TestVO() {}
public TestVO(String name, String id, int weight, int height) {
this.name = name;
this.id = id;
this.height = height;
this.weight = weight;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@Override
public String toString() {
return "Name: " + getName() + " ID: " + getId() + " Height: " + getHeight() + " Weight: " + getWeight();
}
}
List<TestVO> tmpList = new ArrayList<>();
tmpList.add(new TestVO("David", "id1", 10, 10));
tmpList.add(new TestVO("", "id2", 11, 11));
tmpList.add(new TestVO("Michael", "id3", 12, 12));
tmpList.add(new TestVO("Jack", "id4", 13, 13));
tmpList.add(new TestVO("Subodh", "id5", 14, 14));
tmpList.add(new TestVO("", "id6", 15, 15));
tmpList.add(new TestVO("Mrinal", "id7", 16, 16));
tmpList.add(new TestVO("", "id8", 17, 17));
tmpList.add(new TestVO("Eddie", "id9", 18, 18));
tmpList.add(new TestVO("Peter", "id10", 19, 19));
我想做的是迭代tmpList,找到身高和体重的总和,并在名称为空时添加“No Name”。
// below into stream
int totalWeight = 0;
int totalHeight = 0;
for (TestVO testVO : tmpList) {
if( !"".equals(testVO.getName())){
totalWeight += totalWeight;
totalHeight += totalHeight;
}else {
testVO.setName("No-Name");
}
}
Map<Boolean, List<TestVO>>tmpMap = tmpList.stream()
.collect(Collectors.partitioningBy(test -> !"".equals(test.getName())));
int totalWeigt = tmpMap.get(true).stream()
.mapToInt(test -> test.getWeight())
.sum();
int totalHeight = tmpMap.get(true).stream()
.mapToInt(test -> test.getHeight())
.sum();
tmpMap.get(false).stream()
.forEach(test -> {
test.setName("No-Name");
});
// method 1
List<TestVO> tmpRet1 = Stream.of(tmpMap.get(true), tmpMap.get(false)).flatMap(Collection::stream).collect(Collectors.toList());
//method 2
List<TestVO> tmpRet2 = Stream.concat(tmpMap.get(true).stream(), tmpMap.get(false).stream()).collect(Collectors.toList());
我已经工作到目前为止,这似乎是不对的。我是说我必须重复每个案例。
有没有办法把它们结合在一起?或者有什么更好的建议?
如果确实希望在流中而不是在循环中执行所有这些操作:
// sums[0] = total weight, sums[1] = total height
int[] sums = tmpList.stream()
.reduce(new int[]{0, 0},
(acc, t) -> {
if (t.getName().equals("")) {
t.setName("No-Name");
return acc;
} else {
return new int[]{ acc[0] + t.getWeight(), acc[1] + t.getHeight()};
}
},
(a, b) -> new int[]{ a[0] + b[0], a[1] + b[1] });
尽管流操作中的副作用通常不被鼓励。
首先,循环版本似乎更适合此任务,该任务通过两个字段(按高度
和重量
求和)进行聚合,并在遍历输入集合时修改空名称
字段的状态,因为它确保整个输入只经过一次。
因此,"有状态"流操作作为foreach
应该用于整个任务,但这与通常的for-each
循环没有显著区别。一般来说,不建议使用这样的副作用操作:
_通常不鼓励行为参数对流操作产生副作用,因为它们通常会导致无意中违反无状态性要求,以及其他线程安全危险_
因此,如果任务被分成两个独立的子任务,使用流API分别解决每个任务将更合适。
使用Java16record
和Stream::reduce(BinaryOperator)的示例
record SumHeightWeight(int weight, int height) {
SumHeightWeight sum(SumHeightWeight that) {
return new SumHeightWeight(
this.weight() + that.weight(),
this.height() + that.height()
);
}
}
Predicate<TestVO> nonEmptyName = t -> !"".equals(t.getName());
SumHeightWeight sum = tmpList.stream()
.filter(nonEmptyName)
.map(t -> new SumHeightWeight(t.getWeight(), t.getHeight()))
.reduce(SumHeightWeight::sum) // Optional<SumHeightWeight>
.orElseGet(()-> new SumHeightWeight(0, 0));
System.out.println(sum); // -> SumHeightWeight[weight=102, height=102]
tmpList.stream()
.filter(Predicate.not(nonEmptyName))
.forEach(t -> t.setName("No-Name"));
它可以在流中的一次运行中完成:
我改变了前两个的体重和身高,所以更明显的是结果是正确的。
import java.util.List;
import java.util.ArrayList;
public class Testing {
public static void main(String[] args) {
List<TestVO> tmpList = new ArrayList<>();
tmpList.add(new TestVO("David", "id1", 100, 200));
tmpList.add(new TestVO("", "id2", 2048, 1024));
tmpList.add(new TestVO("Michael", "id3", 12, 12));
tmpList.add(new TestVO("Jack", "id4", 13, 13));
tmpList.add(new TestVO("Subodh", "id5", 14, 14));
tmpList.add(new TestVO("", "id6", 15, 15));
tmpList.add(new TestVO("Mrinal", "id7", 16, 16));
tmpList.add(new TestVO("", "id8", 17, 17));
tmpList.add(new TestVO("Eddie", "id9", 18, 18));
tmpList.add(new TestVO("Peter", "id10", 19, 19));
String NoName = "No-Name";
int[] weigthHeight =
tmpList.stream()
// modify the testVO
.map(testVO -> { if (testVO.getName().isEmpty()) {
testVO.setName(NoName);
}
return testVO;
})
// it changed them:
.peek(testVO-> System.out.println(testVO))
// remove the ones we don't want anymore
.filter(testVO-> !NoName.equals(testVO.getName()))
// make an array of the Weight and Height
.map(testVO-> new int[]{testVO.getWeight(), testVO.getHeight()})
// reduce to one array with the sum of Weight and Height
.reduce(new int[]{0,0}, (a,b) -> add(a,b));
System.out.println("Weight: " + weigthHeight[0]);
System.out.println("Height: " + weigthHeight[1]);
}
static int[] add(int[] a, int[]b) {
a[0] = a[0] + b[0];
a[1] = a[1] + b[1];
return a;
}
}
它给了我这个机会:
Name: David ID: id1 Height: 200 Weight: 100
Name: No-Name ID: id2 Height: 1024 Weight: 2048
Name: Michael ID: id3 Height: 12 Weight: 12
Name: Jack ID: id4 Height: 13 Weight: 13
Name: Subodh ID: id5 Height: 14 Weight: 14
Name: No-Name ID: id6 Height: 15 Weight: 15
Name: Mrinal ID: id7 Height: 16 Weight: 16
Name: No-Name ID: id8 Height: 17 Weight: 17
Name: Eddie ID: id9 Height: 18 Weight: 18
Name: Peter ID: id10 Height: 19 Weight: 19
Weight: 192
Height: 292
我不确定这比使用一个方法获取重量和高度,另一个方法替换空名称更具可读性和透明性。
在溪流中跑步的感觉有点“黑”。它依赖于改变物体,我认为这是一种副作用。请参阅java包上的JavaDoc。util。关于“副作用”的信息流。首先是:
通常不鼓励行为参数对流操作产生副作用,因为它们通常会导致无意中违反无状态性要求,以及其他线程安全危险。
但是,要添加到我的txt文件中的事务列表的类型是Transaction,而不是String。 作为一个例子,这里有一些用户存款情况下的代码。 理想情况下,我希望代码读取用户以前的事务,将他们的新事务添加到txt文件的末尾,然后在用户完成时将所有这些事务保存到同一个txt文件中。有没有一种方法可以读取用户以前的事务类型为Transaction而不是String,或者以某种方式将这两个列表组合起来,给
输出如下:http://imgur.com/a/nu3n6
下面我有两个箱子。 案例1和案例2之间的区别在于案例2具有在中,但案例1在中具有。 问题是关于案例2的输出:为什么包含两个不同的值,一个是,另一个是字符串“B”?
我有一个问题要用java来解决。 我的代码有三个变量:a、b、c,分别是双精度的。所有变量之和必须等于1。 我需要测试这些变量中所有可能的组合,值从0.10变化 示例: 组合1: 组合2: 然后继续。 是否有任何框架或库来自动化这种测试?
但是,这并不适用于String类。请参见下面的代码: 这是因为字符串类和自声明类之间的差异吗?谢谢你的帮助!
使用MongoDB 3.4。10和猫鼬4.13。6我能够计算用户模型上两个阵列的大小: 我的用户所在的位置(per) {“_id”:ObjectId(“5a2b21e63023c6117085c240”),“右投票”:[2],“左投票”:[1,6]} {“_id”:ObjectId(“5a2c0d68efde3416bc8b7020”),“右投票”:[2],“左投票”:[1]} 在这里,我得到了预