Can some one correct this statement for me?
List<Object> objectList = new ArrayList<Object>();
objectList.addAll(Arrays.asList(["206C(1)", "CG", 1],["206C(1)", "SG", 1]));
after getting this data in objectlist i need to use .stream() like operations
Object will be a class of
public class Object{
private String section;
private String code;
private Boolean yn;
getters and setters
}
any help is truly appreciated
In general a class' name should give an idea of the class' content/purpose. That is such generic names as Object are a bad idea in most cases. Additionally Object might easily get confused with java.lang.Object...
public class MyObject {
private String section;
private String code;
private Boolean yn;
//getters and setters
public MyObject(String section, String code, Boolean yn) {
this.section = section;
this.code = code;
this.yn = yn;
}
}
With the above constructor you can do:
List<Object> objectList = List.of(new MyObject("206C(1)", "CG", true), new MyObject("206C(1)", "SG", true));
If you make a static import for a factory method, you can save some characters:
public class MyObject {
// all of the above
public static MyObject of(String section, String code, Boolean yn) {
return new MyObject(section, code, yn);
}
}
import static MyObject.of
...
List<Object> objectList = List.of(of("206C(1)", "CG", true), of("206C(1)", "SG", true));
Related
I have the following request
{
"attachments":[
{
"fields":[
{
"value":"Testing value"
}
]
}
],
"channel":"testing",
"value":"Testing value"
}
and want to make it as a request in Java, but I am struggling how to represent it and use it. So far I've done this
public class RequestTest {
ArrayList<ArrayList<String>> attachments = new ArrayList<ArrayList<String>>();
ArrayList<String> fields = new ArrayList<String>();
private String channel;
private String value;
}
But I am not sure how to put the value and how to call it after that.
You have to create an object structure like:
public class RequestTest {
ArrayList<Attachment> attachments = new ArrayList<>();
private String channel;
private String value;
}
public class Attachement {
ArrayList<Field> fields = new ArrayList<>();
}
public class Field {
String value;
}
Then you can use jackson or gson to create the json string you expect.
If you want to present the request in Java class, then you should create a class named "Field" and class named "Attachment".
public class Field{
private String value;
}
public class Attachment{
private List<Field> fields;
}
public class RequestTest{
private List<Attachment> attachments;
private String channel;
private String value;
}
If you want to present it with JsonObject, you can refer to JsonObject
So I have this GameType class:
public class GameType {
private final String name;
public GameType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
and I have a list of my game types, so, basically I want to print all of my GameType classes' name field and I am using Java 8, this is what I have done so far:
List<String> list = new ArrayList<>();
gameTypes.forEach(gameType -> list.add(gameType.getName()));
System.out.println(list);
So, what I am asking is, is there a better way to do that?
You can try this:
System.out.println(gameTypes.stream()
.map(GameType::getName)
.collect(Collectors.toList()));
What is wrong with the JXpath expression in the code below? The following code always throws this exception:
org.apache.commons.jxpath.JXPathNotFoundException: No value for xpath: countries[gdp=4]
However I expected the country Germany to be returned. Whats wrong here?
import org.apache.commons.jxpath.JXPathContext;
public class Test {
private final Country[] countries = {
new Country("US", 20),
new Country("China", 13),
new Country("Japan", 5),
new Country("Germany", 4),
new Country("UK", 3)};
public static void main(String[] args) {
Object result = JXPathContext.newContext(new Test()).getValue("countries[gdp=4]");
System.out.println(result);
}
public Country[] getCountries() {
return countries;
}
}
-
class Country{
private String name;
private int gdp;
public Country(String name, Integer gdp){
this.name=name;
this.gdp=gdp;
}
#Override
public String toString() {
return name;
}
public String getName() {
return name;
}
public int getGdp() {
return gdp;
}
}
I don't know enough about the jxpath lib you are using. But the xpath expression should be like this:
/countries/country[gdp=4]
It started to work after I replaced:
Object result = JXPathContext.newContext(new Test()).getValue("countries[gdp=4]");
By:
Iterator result = JXPathContext.newContext(new Test()).iterate("countries[gdp=4]");
I'm saving some ArrayList in Sharedpreferences. But I want to set my custom model to ArrayList in adapter cause get items with getter. I really tired too many solutions from stackoverflow but I couldn't do that.
private ArrayList<String> fullList = new ArrayList<>();
to
private ArrayList<MyCustom> fullList = new ArrayList<>();
My Custom Class:
public class InstagramUserSummary implements Serializable {
public boolean is_verified;
public String profile_pic_id;
public boolean is_favorite;
public boolean is_private;
public String username;
public long pk;
public String profile_pic_url;
public boolean has_anonymous_profile_picture;
public String full_name;
#Override
public int hashCode() {
return Objects.hash(username, pk);
}
#Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (!(obj instanceof InstagramUserSummary)) {
return false;
}
InstagramUserSummary user = (InstagramUserSummary) obj;
return pk == user.getPk();
}}
List coming like this:
[InstagramUserSummary(super=dev.niekirk.com.instagram4android.requests.payload.InstagramUserSummary#a4acf205, is_verified=false, profile_pic_id=1773528799482591987_1654599017, is_favorite=false, is_private=false, username=ququletta, pk=1654599017, profile_pic_url=https://instagram.fada1-5.fna.fbcdn.net/vp/8d99014623ed527e52512a20002d884b/5C387E45/t51.2885-19/s150x150/31203725_200759604054857_5778864946146181120_n.jpg, has_anonymous_profile_picture=false, full_name=Ququletta)]
Thanks.
First of all, there is no need to have the username field be a public member of the MyCustom class. Since you're exposing access to the field via getters/setters having it public is wrong.
Aside from that, you can easily use streams and a mapping function to create a new MyCustom instance from a Stream of String.
In order to avoid boilerplate code, I would go ahead and create a static creator method in MyCustom like this:
public class MyCustom {
private String userName;
public String getUserName() { return userName; }
public void setUserName(String userName) { this.userName = userName; }
public static MyCustom from(final String userName) {
MyCustom custom = new MyCustom();
custom.setUserName(userName);
return custom;
}
}
And then I would use this as a method reference to convert Strings over to MyCustoms thus collecting them into a new list like this:
List<String> list = new ArrayList<>();
List<MyCustom> customs = list.stream()
.map(MyCustom::from)
.collect(Collectors.toList());
Finally, also avoid initializing lists using the concrete type (e.g. ArrayList<String> someList = new ArrayList<>;'. It's much better to code the interfaces, thus doing something like List<String> someList = new ArrayList<>.
Solution:
Suppose you have a String variable in MyCustom class, like:
public class MyCustom {
private String strName;
public MyCustom(String name) {
this.strName = name;
}
public void setName(String name) {
this.strName = name;
}
public String getName() {
return this.strName;
}
}
then, you can do something like this:
for (MyCustom value : fullList) {
customFullList.add(new MyCustom(value))
}
Hope it helps.
Is it possible to avoid creating stream inside current stream from the same collection like in below example to collect some data (listOfA is used two times to create stream) ?
List<A> listOfA = Arrays.asList(new A(1L, "A1", "V1"), new A(2L, "A2", "V1"), new A(1L, "A1", "V2"));
List<B> listOfB = listOfA.stream().map(r -> new B(r.getId(), r.getName(),
listOfA.stream().filter(r2 -> r.getId().equals(r2.getId())).map(A::getVal).collect(toSet())
)).distinct().collect(toList());
class A {
private final Long id;
private final String name;
private final String val;
A(Long id, String name, String val) //constructor
//getters
}
class B {
private final Long id;
private final String name;
private final Set<String> values;
B(Long id, String name, Set<String> values) //constructor
//getters
#Override
public boolean equals(Object o) {
...
return id.equals(a.id);
}
//hashCode
}
The final result should be a list of 2 objects:
B{id=1, name='A1', values=[V1, V2]}
B{id=2, name='A2', values=[V1]
Thanks in advance!
I'm not sure what you question aims at. If the question is what the minimal changes are that are necessary in order to avoid re-creating the stream, then I have to answer: I don't know. However, it seems like your approach is overly complicated. The chain of map, collect, filter, distinct and collect that is built there is really hard to understand.
After a short rant...
Maybe my fear that future Java programs will all look like this, and thus become completely unmaintainable is not justified. Maybe one just has "to get used to" this programming style. Maybe there's a short period when people are too eager with using the new language features, and it will come back to a "normal" style (and a "healthy" level of functional elements) sooner or later. But I, personally, think that a method like createBsByMergingTheValuesOfAs() would be sufficient and appropriate here.
... I'd like to suggest using a dedicated Collector, which already offers much of the infrastructure for mutable reduction that you seem to be emulating with this chain of operations:
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class StreamCollectTest
{
public static void main(String[] args)
{
List<A> listOfA = Arrays.asList(
new A(1L, "A1", "V1"),
new A(2L, "A2", "V1"),
new A(1L, "A1", "V2"));
Map<Long, B> result = listOfA.stream().collect(
Collectors.toConcurrentMap(
// The "id" will be the key of the map
a -> a.getId(),
// The initial value stored for each key will be a "B"
// whose set of values contains only the element of
// the corresponding "A"
a -> new B(a.getId(), a.getName(),
new LinkedHashSet<String>(Collections.singleton(a.getVal()))),
// Two "B"s with the same key will be merged by adding
// all values from the second "B" to that of the first
(b0,b1) -> { b0.values.addAll(b1.values); return b0; }));
System.out.println(result);
}
static class A
{
private final Long id;
private final String name;
private final String val;
A(Long id, String name, String val)
{
this.id = id;
this.name = name;
this.val = val;
}
public Long getId()
{
return id;
}
public String getName()
{
return name;
}
public String getVal()
{
return val;
}
}
static class B
{
private final Long id;
private final String name;
private final Set<String> values;
B(Long id, String name, Set<String> values)
{
this.id = id;
this.name = name;
this.values = values;
}
#Override
public String toString()
{
return id+","+name+","+values;
}
}
}
It prints
{1=1,A1,[V1, V2], 2=2,A2,[V1]}
So the values() of the resulting map should be exactly what you are looking for.