Return string from arraylist - java

Lets say I have a class
public class Ttype{
private String type = "";
public Ttype(String type) {
this.type = type;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
and I have arraylist of this class
ArrayList<Ttype> type = new ArrayList<Ttype>();
I have added some elements to the arraylist
type.add( new new Ttype("Hello"));
type.add( new new Ttype("Bye"));
type.add( new new Ttype("Hi"));
I want to be able to return a string when I search for specefic string in the arraylist. What I mean by that is:
Ttype t = type.get("Hello"); //t will be set to "hello" if hello is in the arraylist.
How can I do that?

type.stream()
.filter(c -> c.getType().equals("test"))
.collect(Collectors.toList());

Well as others suggested in comments this will be much easy when you use a Map rather than ArrayList. But in your case to achieve what you need you can follow the below steps.This will be much easy when you use streams in Java 8.But I will provide a simple solution which you can achieve without streams.
Ttype result = null;//To store if an object found
String searchTxt = "Hello";
for(Ttype temp:type){//Iterating through the list find a match
if(temp.type.equlas(searchTxt)){
result = temp;
}
}
Now based on the value which contains in the result you can continue your work.If result is null after the iteration it means there is no matching item found.

Related

How do I convert java.sql.Array to List<MyCustomEnum>?

I have rs.getArray("lang"); which is java.sql.Array and the lang field is character varying[]. I want to convert it to List<MyEnumLanguage>. As an example I have {fr_FR,en_US} and I have used the following code to convert that my IDE didn't show any errors
List<MyEnumLanguage> myEnumLanguageList = (List<MyEnumLanguage>) rs.getArray("lang");
but it throws an exception org.postgresql.jdbc.PgArray cannot be cast to java.util.List.
My MyEnumLanguage is like:
public enum MyEnumLanguage {
en_US {
public String getCode() { return "en_US" }
},
de_DE {
public String getCode() { return "de_DE" }
};
private MyEnumLanguage() {
}
}
You cannot cast an array to List. Your IDE does not show any arror because casting happens on runtime.
Instead, you should use Arrays.asList(array) method, which returns a list containing all the elements of the array.
Note that if you want to map the elements of the array to another type, you could easily do that with streams. Example:
List<MyEnumLanguage> myEnumLanguageList = Arrays.asList(rs.getArray("lang"))
.stream()
.map(arrayElement -> convertToMyEnumLanguage(arrayElement))
.collect(Collectors.toList());
where convertToMyEnumLanguage() takes an element of your array and returns the corresponding MyEnumLanguage.
Take a look at this post: https://stackify.com/streams-guide-java-8/
UPDATE
Initially I missread the question. You have to first convert your PgArray to a normal java array, before you can use it in Arrays.asList().
This can be done using PgArray.getArray() method, and then cast the returned object to an array of the pgArray's containing type.
UPDATE 2
Improved example:
First of all you should define your enum like this:
public enum MyEnumLanguage {
en_US("en_US"),
de_DE("de_DE");
private final String code;
private MyEnumLanguage(String code) {
this.code = code;
}
public String getCode() {
return code;
}
public static MyEnumLanguage getEnumByCode(String code) {
if(code == null || code.isEmpty()) {
return null;
}
for(MyEnumLanguage e : values()) {
if(e.getCode().equals(code)) {
return e;
}
}
return null;
}
}
Then to map your pgArray to a List:
Array pgArray = rs.getArray("lang");
String[] langJavaArray = (String[]) pgArray.getArray(); //this returns an Object, so we cast it to a String array
List<MyEnumLanguage> myEnumLanguageList =
Arrays.stream(langJavaArray)
.map(MyEnumLanguage::getEnumByCode)
.collect(Collectors.toList())
;
Please note that the mapping function does not check for nulls. So if a wrong codes are passed, your list will contain nulls. If this is not the desired result, you have to perform the appropriate checks and handle null cases in your map function.

Using an ArrayList of custom class and setting variables at different times

I am just getting into Java and programming in general.
I have class Dogs:
public class Dog {
String name;
String URL;
public Dog(){
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getURL() {
return URL;
}
public void setURL(String URL) {
this.URL = URL;
}
}
I want to have a total of 300 or so Dogs. For this purpose I only included the "names" and "URL" variables, although in reality, I will have about 10 more variables for each object. I thought the best way to work with them would be to make an ArrayList<Dog>. So the first thing that I set is the URLs, which I do here:
static ArrayList<Dog> dogInfo = new ArrayList<>();
for (Element e : dogURLs) {
Dog dog = new Dog();
dog.setURL(e.attr("src").toString());
dogInfo.add(dog);
}
This works fine and as expected. I am able to get each individual URL by
for (int i = 0; i<dogInfo.size(); i++){
Log.i("DogURL", dogInfo.get(i).getURL());
}
But when I try to add the name next is where I'm having problem. My thought process is that the objects have already been added to the ArrayList, so I just need to use the name setter instead of adding a new element to the ArrayList:
for (int i = 0; i < dogInfo.size(); i++) {
dogInfo.get(i).setName(dogNamesElement.text());
}
But when doing this, and printing to the logs, it appears as if every element in the ArrayList contains the entire list of names.
for (int i = 0; i<dogInfo.size(); i++){
Log.i("DogNames", dogInfo.get(i).getName());
}
Can you tell me what I'm doing wrong? Also, is this the best way to handle working with data like this? I'm pretty new so if the way I'm doing this is non-optimal then please let me know before I go any further.
Solved. I changed it from an enhanced for loop to a regular for loop and forgot to use get(index) on the dogNameElement.
dogInfo.get(i).setName(dogNamesElement.get(i).text());
instead of
dogInfo.get(i).setName(dogNamesElement.text());

Most efficient way to convert Enum values into comma seperated String

I have a java class in which I store an Enum.(shown at the bottom of this question) In this enum, I have a method named toCommaSeperatedString() who returns a comma separated String of the enums values. I am using a StringBuilder after reading some information on performance in this question here.
Is the way I am converting this enum's values into a commaSeperatedString the most efficient way of doing so, and if so, what would be the most efficient way to remove the extra comma at the last char of the String?
For example, my method returns 123, 456, however I would prefer 123, 456. If I wanted to return PROPERTY1, PROPERTY2 I could easily use Apache Commons library StringUtils.join(), however, I need to get one level lower by calling the getValue method when I am iterating through the String array.
public class TypeEnum {
public enum validTypes {
PROPERTY1("123"),
PROPERTY2("456");
private String value;
validTypes(String value) {
this.value = value;
}
public String getValue() {
return value;
}
public static boolean contains(String type) {
for (validTypes msgType : validTypes.values()) {
if (msgType.value.equals(type)) {
return true;
}
}
return false;
}
public static String toCommaSeperatedString() {
StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
for(validTypes msgType : validTypes.values()) {
commaSeperatedValidMsgTypes.append(msgType.getValue() + ", ");
}
return commaSeperatedValidMsgTypes.toString();
}
}
}
I wouldn't worry much about efficiency. It's simple enough to do this that it will be fast, provided you don't do it in a crazy way. If this is the most significant performance bottleneck in your code, I would be amazed.
I'd do it something like this:
return Arrays.stream(TypeEnum.values())
.map(t -> t.value)
.collect(Collectors.joining(','));
Cache it if you want; but that's probably not going to make a huge difference.
A common pattern for the trailing comma problem I see is something like
String[] values = {"A", "B", "C"};
boolean is_first = true;
StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
for(String value : values){
if(is_first){
is_first = false;
}
else{
commaSeperatedValidMsgTypes.append(',');
}
commaSeperatedValidMsgTypes.append(value);
}
System.out.println(commaSeperatedValidMsgTypes.toString());
which results in
A,B,C
Combining this with the answers about using a static block to initialize a static final field will probably give the best performance.
The most efficient code is code that doesn't run. This answer can't ever change, so run that code as you have it once when creating the enums. Take the hit once, return the calculated answer every other time somebody asks for it. The savings in doing that would be far greater in the long term over worrying about how specifically to construct the string, so use whatever is clearest to you (write code for humans to read).
For example:
public enum ValidTypes {
PROPERTY1("123"),
PROPERTY2("345");
private final static String asString = calculateString();
private final String value;
private static String calculateString() {
return // Do your work here.
}
ValidTypes(final String value) {
this.value = value;
}
public static String toCommaSeparatedString() {
return asString;
}
}
If you have to call this static method thousand and thousand of times on a short period, you may worry about performance and you should first check that this has a performance cost.
The JVM performs at runtime many optimizations.
So finally you could write more complex code without added value.
Anyway, the actual thing that you should do is storing the String returned by toCommaSeperatedString and returned the same instance.
Enum are constant values. So caching them is not a problem.
You could use a static initializer that values a static String field.
About the , character, just remove it after the loop.
public enum validTypes {
PROPERTY1("123"), PROPERTY2("456");
private static String valueSeparatedByComma;
static {
StringBuilder commaSeperatedValidMsgTypes = new StringBuilder();
for (validTypes msgType : validTypes.values()) {
commaSeperatedValidMsgTypes.append(msgType.getValue());
commaSeperatedValidMsgTypes.append(",");
}
commaSeperatedValidMsgTypes.deleteCharAt
(commaSeperatedValidMsgTypes.length()-1);
valueSeparatedByComma = commaSeperatedValidMsgTypes.toString();
}
public static String getvalueSeparatedByComma() {
return valueSeparatedByComma;
}
I usually add a static method on the enum class itself:
public enum Animal {
CAT, DOG, LION;
public static String possibleValues() {
return Arrays.stream(Animal.values())
.map(Enum::toString)
.collect(Collectors.joining(","));
}
}
So I can use it like String possibleValues = Animal.possibleValues();

Java: how to convert from type A to type B?

I'm a java beginner and although I've looked for the topic both here and on Google I haven't found it. I'm sure it has to be there somewhere but it's me who doesn't know how to search. Anyway, here it is:
How can I write methods to convert from string/int/etc. to a class and vice-versa? I'd definitely like that my class conversion be automatic but I can live with less-than-perfect typecast. What I wouldn't be comfortable with is calling class("some string") or class.toString() for converting back and forth from string to class. I'd like it to be as seamless as possible. Here's an example:
I have a IsFound class that behaves like a boolean and I use it as a return type in a method; in the method body I return a string like "found" (instead of true). You may laugh at me for not using a Boolean but I want to play a little with a custom class/type. Here's some code
public class IsFound{
public boolean found; // field
public IsFound(String isFound_){
if(isFound_.equals("FOUND")){
found = true;
else found = false;
}
}
public String toString(){
if(found) return "found";
else return "not found";
}
}
This is the furthest I could get. I need the converter methods to/from string and for future references I'd like to know whether the converters are applicable for int, char or even other classes.
The solution to extend Boolean is only as a last resort, since I don't know what bloat I'm carrying along -- I want to create the class myself from 0.
EDIT:
I want to be able to use something like:
public IsFound parse(String substring_){
if(search(substring_, string) == true){
return FOUND; // or return "FOUND";
{
return NOTFOUND; // or return "NOT FOUND";
{
Currently it gives the error that can't convert from String to IsFound. I want to fill in this gap.
I'd also use an enum, here's one that gives you all of the functionality that is in your class.
public enum IsFound{
// each of these definitions are like calls to the IsFound constructor below
FOUND("found"),
NOT_FOUND("not found");
// string representation
private final String toString;
private IsFound(String isFound){
this.toString = isFound;
}
/**
* #Override
*/
public String toString(){
return toString;
}
// I think this is what you want. I'm not sure why you need this, but
// am including it as I think it gives you what you want. see example below
public static IsFound convert( String foundString ){
if( FOUND.toString.equals(foundString) ){
return FOUND;
}
else if( NOT_FOUND.toString.equals(foundString) ){
return NOT_FOUND;
}
else{
return null;
}
}
}
You can use this in the following ways:
private IsFound myFoundValue;
myFoundValue = IsFound.FOUND;
System.out.println(myFoundValue.toString()); // "found"
myFoundValue = IsFound.NOT_FOUND;
System.out.println(myFoundValue.toString()); // "not found"
switch( myFoundValue ){
case FOUND:
System.out.println("the value is FOUND");
break;
case NOT_FOUND:
System.out.println("the value is NOT_FOUND");
break;
default:
System.out.println("this should never happen");
break;
}
myFoundValue = IsFound.convert("found"); // IsFound.FOUND
System.out.println( myFoundValue.toString() ); // "found"
Your question smells like a classic XY Problem in that you appear to be barking up the wrong tree to find a solution to a problem that you may need to understand better. It's an anti-pattern to try to use Strings as a substitute for type, so you're far better off not doing this. For something like this, consider using either a boolean for a two-state type or an enum for a multi-state type.
e.g.,
public enum IsFound{
FOUND, NOT_FOUND, UNKNOWN
}
or...
public enum IsFound {
FOUND("Found"), NOT_FOUND("Not Found"), UNKNOWN("Unknown");
private String name;
private IsFound(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public String toString() {
return name;
}
}
in some other class.
private Map<Luggage, IsFound> lostLuggageMap = new HashMap<>();
The enum adds a compile-time type safety that Strings just don't have.
enums can have properties and behaviors (methods) that are extremely useful.
For conversion between "string" representations and POJO ( plain old java objects ), you may want to use serialization to / from a known text format such as JSON ( or XML ).
public class Search {
private boolean found;
// getters, setters, constructor
}
Serialization / Deserialization using Google's GSON library :
Search search = new Search();
search.setFound(true);
Gson gson = new Gson();
String json = gson.toJson(search);
// should output : { "found" : "true" }
// The opposite way , if json is a string equal to { "found" : "true" }
Gson gson = new Gson();
Search s = gson.fromJson(json, Search.class);
// s has found = true

Trying to compare two objects and extract a third object containing their differences

I've got two domain objects, of the same type. They contain enums, primitive arrays, and other objects and theres a list in the Heirarchy there too.
I need something to extract a third object of the same type that only contains their differences, almost like a mask that contains only their changes. And anything that hasn't changed be set to null.
Everything points to the Apache BeanUtils, but I cant find exactly what I'm looking for, any suggestions?
Edit#1
Example to clarify :
If obj1 is the original, and obj2 is the updated version. Then if obj1.value is equal to obj2.value then obj3.value will be null. If obj1.value is not equal to obj2.value then obj3.value will be set to the value of obj2.value
Edit#2
Ideally it should be abstract and in no way need to know what type of object the comparison is being run on. As this could be used for different objects in the future.
If one of the update values is set to null than it can be ignored as if its not a change.
Your question is interesting for me. I searching very much for your goals and find a little library do it. This library is in google code and its name is jettison.
This utility has a main class with name Diff4J that has a method with diffs method and by it compare two object and find differents.
Then I write codes for your goals as following:
fisrt define a Model Object with name Bean :
public class Bean
{
private String name;
private String family;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getFamily()
{
return family;
}
public void setFamily(String family)
{
this.family = family;
}
public Bean()
{
}
public Bean(String name, String family )
{
this.name = name;
this.family = family;
}
}
Then coding a test class as following:
public static void main(String[] args) throws IllegalAccessException,
InvocationTargetException
{
Bean bean_1 = new Bean("Sara", "clooney");
Bean bean_2 = new Bean("Sally", "clooney");
Diff4J comparator = new Diff4J();
Collection<ChangeInfo> diffs = comparator.diff(bean_1, bean_2);
Bean final_result = new Bean();
for(ChangeInfo c : diffs)
{
String filedName = c.getFieldName();
Object to_value = c.getTo();
Object from_value = c.getFrom();
BeanUtilsBean.getInstance().setProperty(final_result, filedName, to_value);
}
System.out.println(final_result);
}
By this solution if you run this code see following result:
Bean [family=null, name=Sally]
this result is your goals.
Note: In last line of loop statement, I used BeanUtilBean from Apache Commons Util for fill object by Reflection.
This utility has a problem, it doesn't support Deep Comparator(maybe I couldn't find it) and you have to simulate this task.
for see this library go to http://code.google.com/p/jettison/.
I hope this answer help you.
It can be done without any external library ;)
Let's take a trivial bean
public class Bean {
public String value;
public List<String> list;
public String[] array;
public EnumType enum;
}
and add a static (factory) method:
public static Bean createDelta(Bean master, Bean variant) {
Bean delta = new Bean();
// fields are simple
if (!master.value.equals(variant.value))
delta.value = variant.value;
// enums are simple too
if (master.enumValue != variant.enumValue)
delta.value = variant.value;
// for arrays .. it get's slightly difficult, because arrays may vary in size
int size = master.array.length > variant.array.length ?
master.array.length : variant.array.length;
delta.array = new String[size];
for (int i = 0; i < size; i++) {
if ((i >= master.array.length) ||
(!master.array[i].equals(variant.array[i]))) {
delta.array[i] = variant.array[i];
// same pattern for lists - except we have to add null
int size = master.array.length > variant.array.length ?
master.array.length : variant.array.length;
delta.list = new ArrayList<String>();
for (int i = 0; i < size; i++) {
if ((i >= master.array.length) ||
(!master.array[i].equals(variant.array[i]))) {
delta.list.add(variant.get(i));
} else {
delta.list.add(null);
}
}
}
(Note - not tested, no IDE/compiler at hand - but it shows a general approach)

Categories